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 // 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
72 /* kmUPTextPart is the part code we return to indicate the user has clicked
73 in the text area of our control */
74 #define kmUPTextPart 1
77 /* routines for using existing user pane controls.
78 These routines are useful for cases where you would like to use an
79 existing user pane control in, say, a dialog window as a scrolling
82 /* Utility Routines */
84 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
85 routine. In our focus switching routine this part code is understood
86 as meaning 'the user has clicked in the control and we need to switch
87 the current focus to ourselves before we can continue'. */
88 #define kUserClickedToFocusPart 100
90 /* STPTextPaneVars is a structure used for storing the the mUP Control's
91 internal variables and state information. A handle to this record is
92 stored in the pane control's reference value field using the
93 SetControlReference routine. */
96 /* OS records referenced */
97 TXNObject fTXNRec
; /* the txn record */
98 TXNFrameID fTXNFrame
; /* the txn frame ID */
99 ControlRef fUserPaneRec
; /* handle to the user pane control */
100 WindowPtr fOwner
; /* window containing control */
101 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
103 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
104 Boolean fIsActive
; /* true while the control is drawn in the active state */
105 Boolean fTXNObjectActive
; /* reflects the activation state of the text edit record */
106 Boolean fFocusDrawState
; /* true if focus is drawn (default: true) */
107 /* calculated locations */
108 Rect fRBounds
; /* control bounds */
109 Rect fRTextArea
; /* area where the text is drawn */
110 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
111 Rect fRTextOutline
; /* rectangle used to draw the border */
112 RgnHandle fRTextOutlineRegion
; /* background region for the text, erased before calling TEUpdate */
113 /* our focus advance override routine */
114 EventHandlerUPP handlerUPP
;
115 EventHandlerRef handlerRef
;
121 /* mUPOpenControl initializes a user pane control so it will be drawn
122 and will behave as a scrolling text edit field inside of a window.
123 This routine performs all of the initialization steps necessary,
124 except it does not create the user pane control itself. theControl
125 should refer to a user pane control that you have either created
126 yourself or extracted from a dialog's control heirarchy using
127 the GetDialogItemAsControl routine. */
128 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
);
133 /* Univerals Procedure Pointer variables used by the
134 mUP Control. These variables are set up
135 the first time that mUPOpenControl is called. */
136 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
137 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
138 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
139 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
140 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
141 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
142 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
144 // one place for calculating all
145 static void TPCalculateBounds(STPTextPaneVars
*varsp
, const Rect
& bounds
)
147 SetRect(&varsp
->fRBounds
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
148 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
149 // eventually make TextOutline inset 1,1
150 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
151 if ( !varsp
->fNoBorders
)
153 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
154 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
158 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
159 bounds
.right
, bounds
.bottom
);
163 OSStatus
MLTESetObjectVisibility( STPTextPaneVars
*varsp
, Boolean vis
, long wxStyle
)
165 OSStatus err
= noErr
;
166 #if TARGET_API_MAC_OSX
167 TXNControlTag iControlTags
[1] = { kTXNVisibilityTag
};
168 TXNControlData iControlData
[1] = {{ vis
}};
169 err
= ::TXNSetTXNObjectControls( varsp
->fTXNRec
, false, 1, iControlTags
, iControlData
);
171 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
172 if ( vis
&& textctrl
)
175 UMAGetControlBoundsInWindowCoords( varsp
->fUserPaneRec
, &bounds
);
176 TPCalculateBounds( varsp
, bounds
) ;
177 wxMacWindowClipper
cl(textctrl
) ;
178 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
179 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
180 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
185 // make sure we don't miss changes as carbon events are not available for these under classic
186 static void TPUpdateVisibility(ControlRef theControl
) {
187 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
188 if ( textctrl
== NULL
)
191 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
194 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
195 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
197 // invalidate old position
198 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
199 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
201 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
204 Rect oldBounds
= varsp
->fRBounds
;
205 TPCalculateBounds( varsp
, bounds
) ;
206 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
207 if ( varsp
->fVisible
)
209 wxMacWindowClipper
cl(textctrl
) ;
210 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
211 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
213 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
214 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
218 // make correct activations
219 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
221 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
222 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
224 varsp
->fTXNObjectActive
= setActive
;
225 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
227 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
231 // update focus outlines
232 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
235 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
237 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
238 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
242 // update TXN focus state
243 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
244 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
246 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
247 varsp
->fInFocus
= setFocus
;
248 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
253 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
254 /* set up our globals */
256 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
257 if ( textctrl
== NULL
)
259 TPUpdateVisibility( theControl
) ;
261 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
262 if ( textctrl
->MacIsReallyShown() )
264 wxMacWindowClipper
clipper( textctrl
) ;
265 TXNDraw(varsp
->fTXNRec
, NULL
);
266 if ( !varsp
->fNoBorders
)
267 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
268 TPRedrawFocusOutline( varsp
) ;
274 /* TPPaneHitTestProc is called when the control manager would
275 like to determine what part of the control the mouse resides over.
276 We also call this routine from our tracking proc to determine how
277 to handle mouse clicks. */
278 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
279 ControlPartCode result
;
280 /* set up our locals and lock down our globals*/
282 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
283 if ( textctrl
== NULL
)
285 TPUpdateVisibility( theControl
) ;
286 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
287 if (textctrl
->MacIsReallyShown() )
289 if (PtInRect(where
, &varsp
->fRBounds
))
290 result
= kmUPTextPart
;
301 /* TPPaneTrackingProc is called when the mouse is being held down
302 over our control. This routine handles clicks in the text area
303 and in the scroll bar. */
304 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
306 ControlPartCode partCodeResult
;
307 /* make sure we have some variables... */
309 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
310 if ( textctrl
== NULL
)
312 TPUpdateVisibility( theControl
) ;
313 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
314 if (textctrl
->MacIsReallyShown() )
316 /* we don't do any of these functions unless we're in focus */
317 if ( ! varsp
->fInFocus
) {
319 owner
= GetControlOwner(theControl
);
320 ClearKeyboardFocus(owner
);
321 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
323 /* find the location for the click */
324 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
325 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
328 textctrl
->MacClientToRootWindow( &x
, &y
) ;
333 switch (TPPaneHitTestProc(theControl
, startPt
))
336 /* handle clicks in the text part */
339 wxMacWindowClipper
clipper( textctrl
) ;
342 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
343 TXNClick( varsp
->fTXNRec
, &rec
);
350 return partCodeResult
;
354 /* TPPaneIdleProc is our user pane idle routine. When our text field
355 is active and in focus, we use this routine to set the cursor. */
356 static pascal void TPPaneIdleProc(ControlRef theControl
) {
358 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
359 if ( textctrl
== NULL
)
361 TPUpdateVisibility( theControl
) ;
362 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
363 if (textctrl
->MacIsReallyShown()) {
364 /* if we're not active, then we have nothing to say about the cursor */
365 if (varsp
->fIsActive
) {
369 wxMacWindowClipper
clipper( textctrl
) ;
371 /* there's a 'focus thing' and an 'unfocused thing' */
372 if (varsp
->fInFocus
) {
373 /* flash the cursor */
374 SetPort(varsp
->fDrawingEnvironment
);
375 TXNIdle(varsp
->fTXNRec
);
377 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
379 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
380 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
385 // SetThemeCursor(kThemeArrowCursor);
388 /* if it's in our bounds, set the cursor */
389 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
390 if (PtInRect(mousep
, &bounds
))
392 // SetThemeCursor(kThemeArrowCursor);
400 /* TPPaneKeyDownProc is called whenever a keydown event is directed
401 at our control. Here, we direct the keydown event to the text
402 edit record and redraw the scroll bar and text field as appropriate. */
403 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
404 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
406 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
407 if ( textctrl
== NULL
)
409 TPUpdateVisibility( theControl
) ;
411 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
414 /* turn autoscrolling on and send the key event to text edit */
415 wxMacWindowClipper
clipper( textctrl
) ;
417 memset( &ev
, 0 , sizeof( ev
) ) ;
419 ev
.modifiers
= modifiers
;
420 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
421 TXNKeyDown( varsp
->fTXNRec
, &ev
);
423 return kControlEntireControl
;
427 /* TPPaneActivateProc is called when the window containing
428 the user pane control receives activate events. Here, we redraw
429 the control and it's text as necessary for the activation state. */
430 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
432 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
434 if ( textctrl
== NULL
)
436 TPUpdateVisibility( theControl
) ;
438 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
440 varsp
->fIsActive
= activating
;
441 wxMacWindowClipper
clipper( textctrl
) ;
442 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
443 /* redraw the frame */
444 if ( textctrl
->MacIsReallyShown() )
446 if ( !varsp
->fNoBorders
)
447 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
448 TPRedrawFocusOutline( varsp
) ;
453 /* TPPaneFocusProc is called when every the focus changes to or
454 from our control. Herein, switch the focus appropriately
455 according to the parameters and redraw the control as
457 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
458 ControlPartCode focusResult
;
460 focusResult
= kControlFocusNoPart
;
461 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
462 if ( textctrl
== NULL
)
464 TPUpdateVisibility( theControl
) ;
465 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
466 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
467 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
468 and kControlFocusNextPart will be received. When the user clicks in our field
469 and it is not the current focus, then the constant kUserClickedToFocusPart will
470 be received. The constant kControlFocusNoPart will be received when our control
471 is the current focus and the user clicks in another control. In your focus routine,
472 you should respond to these codes as follows:
474 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
475 the control and the focus rectangle as necessary.
477 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
478 depending on its current state. redraw the control and the focus rectangle
479 as appropriate for the new focus state. If the focus state is 'off', return the constant
480 kControlFocusNoPart, otherwise return a non-zero part code.
481 kUserClickedToFocusPart - is a constant defined for this example. You should
482 define your own value for handling click-to-focus type events. */
483 /* calculate the next highlight state */
486 case kControlFocusNoPart
:
487 TPFocusPaneText(varsp
, false);
488 focusResult
= kControlFocusNoPart
;
490 case kUserClickedToFocusPart
:
491 TPFocusPaneText(varsp
, true);
494 case kControlFocusPrevPart
:
495 case kControlFocusNextPart
:
496 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
497 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
500 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
501 /* redraw the text fram and focus rectangle to indicate the
503 if ( textctrl
->MacIsReallyShown() )
505 wxMacWindowClipper
c( textctrl
) ;
506 if ( !varsp
->fNoBorders
)
507 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
508 TPRedrawFocusOutline( varsp
) ;
514 /* mUPOpenControl initializes a user pane control so it will be drawn
515 and will behave as a scrolling text edit field inside of a window.
516 This routine performs all of the initialization steps necessary,
517 except it does not create the user pane control itself. theControl
518 should refer to a user pane control that you have either created
519 yourself or extracted from a dialog's control heirarchy using
520 the GetDialogItemAsControl routine. */
521 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
)
525 STPTextPaneVars
*varsp
;
526 OSStatus err
= noErr
;
528 /* set up our globals */
529 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
530 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
531 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
532 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
533 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
534 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
535 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
537 /* allocate our private storage */
538 varsp
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
541 /* set the initial settings for our private data */
542 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
543 varsp
->fNoBorders
= wxStyle
& wxNO_BORDER
;
544 varsp
->fInFocus
= false;
545 varsp
->fIsActive
= true;
546 varsp
->fTXNObjectActive
= false;
547 varsp
->fFocusDrawState
= false ;
548 varsp
->fUserPaneRec
= theControl
;
549 varsp
->fVisible
= true ;
551 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
553 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
555 /* set up the user pane procedures */
556 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
557 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
558 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
559 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
560 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
561 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
562 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
564 /* calculate the rectangles used by the control */
565 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
566 varsp
->fRTextOutlineRegion
= NewRgn() ;
567 TPCalculateBounds( varsp
, bounds
) ;
569 /* set up the drawing environment */
570 SetPort(varsp
->fDrawingEnvironment
);
572 /* create the new edit field */
574 TXNFrameOptions frameOptions
=
575 kTXNDontDrawCaretWhenInactiveMask
;
576 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
577 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
579 if ( wxStyle
& wxTE_MULTILINE
)
581 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
582 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
585 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
586 frameOptions
|= kTXNWantHScrollBarMask
;
589 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
590 frameOptions
|= kTXNWantVScrollBarMask
;
593 frameOptions
|= kTXNSingleLineOnlyMask
;
595 verify_noerr(TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
597 kTXNTextEditStyleFrameType
,
599 kTXNSystemDefaultEncoding
,
600 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) varsp
));
602 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
603 TXNControlData iControlData
[3] = { {false}, {kTXNAutoWrap
} };
605 #if TARGET_API_MAC_OSX
606 iControlTags
[2] = kTXNVisibilityTag
;
607 iControlData
[2].uValue
= varsp
->fVisible
;
611 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
612 iControlData
[1].uValue
= kTXNNoAutoWrap
;
614 verify_noerr( TXNSetTXNObjectControls( varsp
->fTXNRec
, false, toptag
,
615 iControlTags
, iControlData
)) ;
621 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
623 TXNTypeAttributes typeAttr
[] =
625 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
626 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
627 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
630 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
635 /* perform final activations and setup for our text field. Here,
636 we assume that the window is going to be the 'active' window. */
637 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
645 #if !USE_SHARED_LIBRARY
646 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
648 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
649 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
650 EVT_CHAR(wxTextCtrl::OnChar
)
651 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
652 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
653 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
654 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
655 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
657 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
658 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
659 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
660 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
661 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
665 static void SetTXNData( STPTextPaneVars
*varsp
, TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
668 #if SIZEOF_WCHAR_T == 2
669 size_t len
= st
.Len() ;
670 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
673 wxMBConvUTF16BE converter
;
674 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
675 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
676 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
677 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
682 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
683 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
689 void wxTextCtrl::Init()
692 m_macTXNvars
= NULL
;
697 m_maxLength
= TE_UNLIMITED_LENGTH
;
700 wxTextCtrl::~wxTextCtrl()
702 SetControlReference((ControlRef
)m_macControl
, 0) ;
703 TXNDeleteObject((TXNObject
)m_macTXN
);
704 /* delete our private storage */
706 /* zero the control reference */
710 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
713 const wxSize
& size
, long style
,
714 const wxValidator
& validator
,
715 const wxString
& name
)
717 m_macIsUserPane
= FALSE
;
720 m_macTXNvars
= NULL
;
723 // base initialization
724 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
727 wxSize mySize
= size
;
729 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
731 if ( m_windowStyle
& wxTE_MULTILINE
)
733 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
734 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
736 m_windowStyle
|= wxTE_PROCESS_ENTER
;
740 wxMacConvertNewlines13To10( &st
) ;
745 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
746 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
747 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
748 /* create the control */
749 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, "\p", true , featurSet
, 0, featurSet
, kControlUserPaneProc
, (long) this );
750 /* set up the mUP specific features and data */
751 wxMacWindowClipper
c(this) ;
752 STPTextPaneVars
*varsp
;
753 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
754 m_macTXNvars
= varsp
;
755 m_macTXN
= varsp
->fTXNRec
;
756 if ( style
& wxTE_PASSWORD
)
759 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
762 MacPostControlCreate(pos
,size
) ;
764 if ( MacIsReallyShown() )
765 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
768 wxMacWindowClipper
clipper( this ) ;
769 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
770 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
772 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
773 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
776 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
777 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
779 SetBackgroundColour( *wxWHITE
) ;
782 tback
.bgType
= kTXNBackgroundTypeRGB
;
783 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
784 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
786 if ( m_windowStyle
& wxTE_READONLY
)
788 SetEditable( false ) ;
791 wxMacCFStringHolder cf
;
792 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cf
, style
& wxTE_PASSWORD
, NULL
, (ControlRef
*) &m_macControl
) ;
799 void wxTextCtrl::MacVisibilityChanged()
801 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
802 if ( !MacIsReallyShown() )
803 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
807 void wxTextCtrl::MacEnabledStateChanged()
812 wxString
wxTextCtrl::GetValue() const
821 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
829 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
830 if ( actualSize
> 0 )
833 #if SIZEOF_WCHAR_T == 2
834 ptr
= new wxChar
[actualSize
+ 1 ] ;
835 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
838 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
840 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
841 wxMBConvUTF16BE converter
;
842 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
843 ptr
= new wxChar
[noChars
+ 1] ;
845 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
849 ptr
[actualSize
] = 0 ;
850 result
= wxString( ptr
) ;
853 DisposeHandle( theText
) ;
857 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
865 actualSize
= GetHandleSize( theText
) ;
866 if ( actualSize
> 0 )
869 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
872 DisposeHandle( theText
) ;
876 wxMacConvertNewlines10To13( &result
) ;
880 void wxTextCtrl::GetSelection(long* from
, long* to
) const
882 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
885 void wxTextCtrl::SetValue(const wxString
& str
)
888 if ( GetValue() == str
)
892 wxMacConvertNewlines13To10( &st
) ;
895 wxMacWindowClipper
c( this ) ;
896 bool formerEditable
= m_editable
;
897 if ( !formerEditable
)
900 // otherwise scrolling might have problems ?
901 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
902 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
903 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
904 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
905 if ( !formerEditable
)
906 SetEditable(formerEditable
) ;
910 void wxTextCtrl::SetMaxLength(unsigned long len
)
915 bool wxTextCtrl::SetFont( const wxFont
& font
)
917 if ( !wxTextCtrlBase::SetFont( font
) )
920 wxMacWindowClipper
c( this ) ;
921 bool formerEditable
= m_editable
;
922 if ( !formerEditable
)
925 TXNTypeAttributes typeAttr
[4] ;
926 Str255 fontName
= "\pMonaco" ;
927 SInt16 fontSize
= 12 ;
928 Style fontStyle
= normal
;
929 int attrCounter
= 0 ;
931 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
932 fontSize
= font
.MacGetFontSize() ;
933 fontStyle
= font
.MacGetFontStyle() ;
935 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
936 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
937 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
938 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
939 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
940 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
941 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
942 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
943 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
946 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
947 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
948 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
949 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
952 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
954 if ( !formerEditable
)
955 SetEditable(formerEditable
) ;
959 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
961 bool formerEditable
= m_editable
;
962 if ( !formerEditable
)
964 TXNTypeAttributes typeAttr
[4] ;
965 Str255 fontName
= "\pMonaco" ;
966 SInt16 fontSize
= 12 ;
967 Style fontStyle
= normal
;
969 int attrCounter
= 0 ;
970 if ( style
.HasFont() )
972 const wxFont
&font
= style
.GetFont() ;
973 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
974 fontSize
= font
.GetPointSize() ;
975 if ( font
.GetUnderlined() )
976 fontStyle
|= underline
;
977 if ( font
.GetWeight() == wxBOLD
)
979 if ( font
.GetStyle() == wxITALIC
)
980 fontStyle
|= italic
;
982 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
983 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
984 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
985 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
986 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
987 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
988 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
989 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
990 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
994 if ( style
.HasTextColour() )
996 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
997 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
998 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
999 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1003 if ( attrCounter
> 0 )
1005 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1007 if ( !formerEditable
)
1008 SetEditable(formerEditable
) ;
1013 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1015 wxTextCtrlBase::SetDefaultStyle( style
) ;
1016 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1020 // Clipboard operations
1021 void wxTextCtrl::Copy()
1025 ClearCurrentScrap();
1026 TXNCopy((TXNObject
)m_macTXN
);
1027 TXNConvertToPublicScrap();
1031 void wxTextCtrl::Cut()
1035 ClearCurrentScrap();
1036 TXNCut((TXNObject
)m_macTXN
);
1037 TXNConvertToPublicScrap();
1039 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1040 event
.SetString( GetValue() ) ;
1041 event
.SetEventObject( this );
1042 GetEventHandler()->ProcessEvent(event
);
1046 void wxTextCtrl::Paste()
1051 TXNConvertFromPublicScrap();
1052 TXNPaste((TXNObject
)m_macTXN
);
1053 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1055 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1056 event
.SetString( GetValue() ) ;
1057 event
.SetEventObject( this );
1058 GetEventHandler()->ProcessEvent(event
);
1062 bool wxTextCtrl::CanCopy() const
1064 // Can copy if there's a selection
1066 GetSelection(& from
, & to
);
1067 return (from
!= to
);
1070 bool wxTextCtrl::CanCut() const
1072 if ( !IsEditable() )
1076 // Can cut if there's a selection
1078 GetSelection(& from
, & to
);
1079 return (from
!= to
);
1082 bool wxTextCtrl::CanPaste() const
1087 return TXNIsScrapPastable() ;
1090 void wxTextCtrl::SetEditable(bool editable
)
1092 if ( editable
!= m_editable
)
1094 m_editable
= editable
;
1096 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1097 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1098 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1103 void wxTextCtrl::SetInsertionPoint(long pos
)
1105 SetSelection( pos
, pos
) ;
1108 void wxTextCtrl::SetInsertionPointEnd()
1110 long pos
= GetLastPosition();
1111 SetInsertionPoint(pos
);
1114 long wxTextCtrl::GetInsertionPoint() const
1117 GetSelection( &begin
, &end
) ;
1121 long wxTextCtrl::GetLastPosition() const
1125 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1133 actualsize
= GetHandleSize( theText
) ;
1134 DisposeHandle( theText
) ;
1139 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1141 wxString value
= str
;
1142 wxMacConvertNewlines13To10( &value
) ;
1144 bool formerEditable
= m_editable
;
1145 if ( !formerEditable
)
1147 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1148 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1149 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1150 if ( !formerEditable
)
1151 SetEditable( formerEditable
) ;
1156 void wxTextCtrl::Remove(long from
, long to
)
1158 bool formerEditable
= m_editable
;
1159 if ( !formerEditable
)
1161 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1162 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1163 if ( !formerEditable
)
1164 SetEditable( formerEditable
) ;
1169 void wxTextCtrl::SetSelection(long from
, long to
)
1171 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) m_macTXNvars
;
1172 /* and our drawing environment as the operation
1173 may force a redraw in the text area. */
1174 SetPort(varsp
->fDrawingEnvironment
);
1175 /* change the selection */
1176 if ((from
== -1) && (to
== -1))
1177 TXNSelectAll((TXNObject
) m_macTXN
);
1179 TXNSetSelection( varsp
->fTXNRec
, from
, to
);
1180 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1183 bool wxTextCtrl::LoadFile(const wxString
& file
)
1185 if ( wxTextCtrlBase::LoadFile(file
) )
1193 void wxTextCtrl::WriteText(const wxString
& str
)
1196 wxMacConvertNewlines13To10( &st
) ;
1198 bool formerEditable
= m_editable
;
1199 if ( !formerEditable
)
1201 long start
, end
, dummy
;
1202 GetSelection( &start
, &dummy
) ;
1203 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1204 GetSelection( &dummy
, &end
) ;
1205 SetStyle( start
, end
, GetDefaultStyle() ) ;
1206 if ( !formerEditable
)
1207 SetEditable( formerEditable
) ;
1209 MacRedrawControl() ;
1212 void wxTextCtrl::AppendText(const wxString
& text
)
1214 SetInsertionPointEnd();
1218 void wxTextCtrl::Clear()
1220 bool formerEditable
= m_editable
;
1221 if ( !formerEditable
)
1223 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1224 TXNClear((TXNObject
)m_macTXN
);
1226 if ( !formerEditable
)
1227 SetEditable( formerEditable
) ;
1232 bool wxTextCtrl::IsModified() const
1237 bool wxTextCtrl::IsEditable() const
1239 return IsEnabled() && m_editable
;
1242 bool wxTextCtrl::AcceptsFocus() const
1244 // we don't want focus if we can't be edited
1245 return /*IsEditable() && */ wxControl::AcceptsFocus();
1248 wxSize
wxTextCtrl::DoGetBestSize() const
1254 switch( m_windowVariant
)
1256 case wxWINDOW_VARIANT_NORMAL
:
1259 case wxWINDOW_VARIANT_SMALL
:
1262 case wxWINDOW_VARIANT_MINI
:
1270 if ( m_windowStyle
& wxTE_MULTILINE
)
1275 return wxSize(wText
, hText
);
1278 // ----------------------------------------------------------------------------
1280 // ----------------------------------------------------------------------------
1282 void wxTextCtrl::Undo()
1286 TXNUndo((TXNObject
)m_macTXN
);
1290 void wxTextCtrl::Redo()
1294 TXNRedo((TXNObject
)m_macTXN
);
1298 bool wxTextCtrl::CanUndo() const
1300 if ( !IsEditable() )
1304 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1307 bool wxTextCtrl::CanRedo() const
1309 if ( !IsEditable() )
1313 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1316 // Makes modifie or unmodified
1317 void wxTextCtrl::MarkDirty()
1322 void wxTextCtrl::DiscardEdits()
1327 int wxTextCtrl::GetNumberOfLines() const
1330 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1334 long wxTextCtrl::XYToPosition(long x
, long y
) const
1338 long lastpos
= GetLastPosition() ;
1340 // TODO find a better implementation : while we can get the
1341 // line metrics of a certain line, we don't get its starting
1342 // position, so it would probably be rather a binary search
1343 // for the start position
1346 int lastHeight
= 0 ;
1349 for ( n
= 0 ; n
<= lastpos
; ++n
)
1351 if ( y
== ypos
&& x
== xpos
)
1354 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1356 if ( curpt
.v
> lastHeight
)
1361 lastHeight
= curpt
.v
;
1370 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1374 long lastpos
= GetLastPosition() ;
1379 if ( pos
<= lastpos
)
1381 // TODO find a better implementation : while we can get the
1382 // line metrics of a certain line, we don't get its starting
1383 // position, so it would probably be rather a binary search
1384 // for the start position
1387 int lastHeight
= 0 ;
1390 for ( n
= 0 ; n
<= pos
; ++n
)
1392 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1394 if ( curpt
.v
> lastHeight
)
1399 lastHeight
= curpt
.v
;
1404 if ( y
) *y
= ypos
;
1405 if ( x
) *x
= xpos
;
1411 void wxTextCtrl::ShowPosition(long pos
)
1413 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1417 TXNOffset selstart
, selend
;
1418 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1419 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1420 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1421 //TODO use HIPoints for 10.3 and above
1422 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1424 OSErr theErr
= noErr
;
1425 SInt32 dv
= desired
.v
- current
.v
;
1426 SInt32 dh
= desired
.h
- current
.h
;
1427 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1428 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1429 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1435 int wxTextCtrl::GetLineLength(long lineNo
) const
1438 if ( lineNo
< GetNumberOfLines() )
1440 // TODO find a better implementation : while we can get the
1441 // line metrics of a certain line, we don't get its starting
1442 // position, so it would probably be rather a binary search
1443 // for the start position
1446 int lastHeight
= 0 ;
1447 long lastpos
= GetLastPosition() ;
1450 for ( n
= 0 ; n
<= lastpos
; ++n
)
1452 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1454 if ( curpt
.v
> lastHeight
)
1456 if ( ypos
== lineNo
)
1462 lastHeight
= curpt
.v
;
1472 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1476 wxString content
= GetValue() ;
1478 if ( lineNo
< GetNumberOfLines() )
1480 // TODO find a better implementation : while we can get the
1481 // line metrics of a certain line, we don't get its starting
1482 // position, so it would probably be rather a binary search
1483 // for the start position
1486 int lastHeight
= 0 ;
1487 long lastpos
= GetLastPosition() ;
1490 for ( n
= 0 ; n
<= lastpos
; ++n
)
1492 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1494 if ( curpt
.v
> lastHeight
)
1496 if ( ypos
== lineNo
)
1502 lastHeight
= curpt
.v
;
1506 if ( ypos
== lineNo
)
1507 line
+= content
[n
] ;
1520 void wxTextCtrl::Command(wxCommandEvent
& event
)
1522 SetValue (event
.GetString());
1523 ProcessCommand (event
);
1526 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1528 // By default, load the first file into the text window.
1529 if (event
.GetNumberOfFiles() > 0)
1531 LoadFile(event
.GetFiles()[0]);
1535 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1537 int key
= event
.GetKeyCode() ;
1538 bool eat_key
= false ;
1540 if ( key
== 'c' && event
.MetaDown() )
1547 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1548 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1549 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1556 // assume that any key not processed yet is going to modify the control
1559 if ( key
== 'v' && event
.MetaDown() )
1565 if ( key
== 'x' && event
.MetaDown() )
1574 if (m_windowStyle
& wxPROCESS_ENTER
)
1576 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1577 event
.SetEventObject( this );
1578 event
.SetString( GetValue() );
1579 if ( GetEventHandler()->ProcessEvent(event
) )
1582 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1584 wxWindow
*parent
= GetParent();
1585 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1586 parent
= parent
->GetParent() ;
1588 if ( parent
&& parent
->GetDefaultItem() )
1590 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1592 if ( def
&& def
->IsEnabled() )
1594 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1595 event
.SetEventObject(def
);
1596 def
->Command(event
);
1601 // this will make wxWindows eat the ENTER key so that
1602 // we actually prevent line wrapping in a single line
1610 // always produce navigation event - even if we process TAB
1611 // ourselves the fact that we got here means that the user code
1612 // decided to skip processing of this TAB - probably to let it
1613 // do its default job.
1615 wxNavigationKeyEvent eventNav
;
1616 eventNav
.SetDirection(!event
.ShiftDown());
1617 eventNav
.SetWindowChange(event
.ControlDown());
1618 eventNav
.SetEventObject(this);
1620 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1631 // perform keystroke handling
1632 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1633 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1637 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1639 EventRecord
*ev
= &rec
;
1642 keychar
= short(ev
->message
& charCodeMask
);
1643 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1645 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1649 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1650 key
== WXK_RETURN
||
1651 key
== WXK_DELETE
||
1654 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1655 event1
.SetString( GetValue() ) ;
1656 event1
.SetEventObject( this );
1657 wxPostEvent(GetEventHandler(),event1
);
1661 // ----------------------------------------------------------------------------
1662 // standard handlers for standard edit menu events
1663 // ----------------------------------------------------------------------------
1665 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1670 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1675 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1680 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1685 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1690 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1692 event
.Enable( CanCut() );
1695 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1697 event
.Enable( CanCopy() );
1700 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1702 event
.Enable( CanPaste() );
1705 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1707 event
.Enable( CanUndo() );
1710 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1712 event
.Enable( CanRedo() );
1715 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1720 // user pane implementation
1722 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1726 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1728 return kControlNoPart
;
1731 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1733 return kControlNoPart
;
1736 void wxTextCtrl::MacControlUserPaneIdleProc()
1740 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1742 return kControlNoPart
;
1745 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1749 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1751 return kControlNoPart
;
1754 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)