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 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
178 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
179 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
184 // make sure we don't miss changes as carbon events are not available for these under classic
185 static void TPUpdateVisibility(ControlRef theControl
) {
186 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
187 if ( textctrl
== NULL
)
190 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
193 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
194 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
196 // invalidate old position
197 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
198 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
200 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
203 Rect oldBounds
= varsp
->fRBounds
;
204 TPCalculateBounds( varsp
, bounds
) ;
205 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
206 if ( varsp
->fVisible
)
208 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
209 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
211 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
212 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
216 // make correct activations
217 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
219 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
220 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
222 varsp
->fTXNObjectActive
= setActive
;
223 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
225 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
229 // update focus outlines
230 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
233 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
235 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
236 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
240 // update TXN focus state
241 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
242 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
244 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
245 varsp
->fInFocus
= setFocus
;
246 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
251 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
252 /* set up our globals */
254 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
255 if ( textctrl
== NULL
)
257 TPUpdateVisibility( theControl
) ;
259 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
260 if ( textctrl
->MacIsReallyShown() )
262 wxMacWindowClipper
clipper( textctrl
) ;
263 TXNDraw(varsp
->fTXNRec
, NULL
);
264 if ( !varsp
->fNoBorders
)
265 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
266 TPRedrawFocusOutline( varsp
) ;
272 /* TPPaneHitTestProc is called when the control manager would
273 like to determine what part of the control the mouse resides over.
274 We also call this routine from our tracking proc to determine how
275 to handle mouse clicks. */
276 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
277 ControlPartCode result
;
278 /* set up our locals and lock down our globals*/
280 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
281 if ( textctrl
== NULL
)
283 TPUpdateVisibility( theControl
) ;
284 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
285 if (textctrl
->MacIsReallyShown() )
287 if (PtInRect(where
, &varsp
->fRBounds
))
288 result
= kmUPTextPart
;
299 /* TPPaneTrackingProc is called when the mouse is being held down
300 over our control. This routine handles clicks in the text area
301 and in the scroll bar. */
302 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
304 ControlPartCode partCodeResult
;
305 /* make sure we have some variables... */
307 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
308 if ( textctrl
== NULL
)
310 TPUpdateVisibility( theControl
) ;
311 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
312 if (textctrl
->MacIsReallyShown() )
314 /* we don't do any of these functions unless we're in focus */
315 if ( ! varsp
->fInFocus
) {
317 owner
= GetControlOwner(theControl
);
318 ClearKeyboardFocus(owner
);
319 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
321 /* find the location for the click */
322 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
323 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
326 textctrl
->MacClientToRootWindow( &x
, &y
) ;
331 switch (TPPaneHitTestProc(theControl
, startPt
))
334 /* handle clicks in the text part */
337 wxMacWindowClipper
clipper( textctrl
) ;
340 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
341 TXNClick( varsp
->fTXNRec
, &rec
);
348 return partCodeResult
;
352 /* TPPaneIdleProc is our user pane idle routine. When our text field
353 is active and in focus, we use this routine to set the cursor. */
354 static pascal void TPPaneIdleProc(ControlRef theControl
) {
356 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
357 if ( textctrl
== NULL
)
359 TPUpdateVisibility( theControl
) ;
360 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
361 if (textctrl
->MacIsReallyShown()) {
362 /* if we're not active, then we have nothing to say about the cursor */
363 if (varsp
->fIsActive
) {
367 wxMacWindowClipper
clipper( textctrl
) ;
369 /* there's a 'focus thing' and an 'unfocused thing' */
370 if (varsp
->fInFocus
) {
371 /* flash the cursor */
372 SetPort(varsp
->fDrawingEnvironment
);
373 TXNIdle(varsp
->fTXNRec
);
375 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
377 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
378 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
383 // SetThemeCursor(kThemeArrowCursor);
386 /* if it's in our bounds, set the cursor */
387 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
388 if (PtInRect(mousep
, &bounds
))
390 // SetThemeCursor(kThemeArrowCursor);
398 /* TPPaneKeyDownProc is called whenever a keydown event is directed
399 at our control. Here, we direct the keydown event to the text
400 edit record and redraw the scroll bar and text field as appropriate. */
401 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
402 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
404 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
405 if ( textctrl
== NULL
)
407 TPUpdateVisibility( theControl
) ;
409 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
412 /* turn autoscrolling on and send the key event to text edit */
413 wxMacWindowClipper
clipper( textctrl
) ;
415 memset( &ev
, 0 , sizeof( ev
) ) ;
417 ev
.modifiers
= modifiers
;
418 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
419 TXNKeyDown( varsp
->fTXNRec
, &ev
);
421 return kControlEntireControl
;
425 /* TPPaneActivateProc is called when the window containing
426 the user pane control receives activate events. Here, we redraw
427 the control and it's text as necessary for the activation state. */
428 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
430 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
432 if ( textctrl
== NULL
)
434 TPUpdateVisibility( theControl
) ;
436 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
438 varsp
->fIsActive
= activating
;
439 wxMacWindowClipper
clipper( textctrl
) ;
440 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
441 /* redraw the frame */
442 if ( textctrl
->MacIsReallyShown() )
444 if ( !varsp
->fNoBorders
)
445 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
446 TPRedrawFocusOutline( varsp
) ;
451 /* TPPaneFocusProc is called when every the focus changes to or
452 from our control. Herein, switch the focus appropriately
453 according to the parameters and redraw the control as
455 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
456 ControlPartCode focusResult
;
458 focusResult
= kControlFocusNoPart
;
459 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
460 if ( textctrl
== NULL
)
462 TPUpdateVisibility( theControl
) ;
463 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
464 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
465 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
466 and kControlFocusNextPart will be received. When the user clicks in our field
467 and it is not the current focus, then the constant kUserClickedToFocusPart will
468 be received. The constant kControlFocusNoPart will be received when our control
469 is the current focus and the user clicks in another control. In your focus routine,
470 you should respond to these codes as follows:
472 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
473 the control and the focus rectangle as necessary.
475 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
476 depending on its current state. redraw the control and the focus rectangle
477 as appropriate for the new focus state. If the focus state is 'off', return the constant
478 kControlFocusNoPart, otherwise return a non-zero part code.
479 kUserClickedToFocusPart - is a constant defined for this example. You should
480 define your own value for handling click-to-focus type events. */
481 /* calculate the next highlight state */
484 case kControlFocusNoPart
:
485 TPFocusPaneText(varsp
, false);
486 focusResult
= kControlFocusNoPart
;
488 case kUserClickedToFocusPart
:
489 TPFocusPaneText(varsp
, true);
492 case kControlFocusPrevPart
:
493 case kControlFocusNextPart
:
494 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
495 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
498 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
499 /* redraw the text fram and focus rectangle to indicate the
501 if ( textctrl
->MacIsReallyShown() )
503 wxMacWindowClipper
c( textctrl
) ;
504 if ( !varsp
->fNoBorders
)
505 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
506 TPRedrawFocusOutline( varsp
) ;
512 /* mUPOpenControl initializes a user pane control so it will be drawn
513 and will behave as a scrolling text edit field inside of a window.
514 This routine performs all of the initialization steps necessary,
515 except it does not create the user pane control itself. theControl
516 should refer to a user pane control that you have either created
517 yourself or extracted from a dialog's control heirarchy using
518 the GetDialogItemAsControl routine. */
519 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
)
523 STPTextPaneVars
*varsp
;
524 OSStatus err
= noErr
;
526 /* set up our globals */
527 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
528 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
529 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
530 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
531 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
532 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
533 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
535 /* allocate our private storage */
536 varsp
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
539 /* set the initial settings for our private data */
540 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
541 varsp
->fNoBorders
= wxStyle
& wxNO_BORDER
;
542 varsp
->fInFocus
= false;
543 varsp
->fIsActive
= true;
544 varsp
->fTXNObjectActive
= false;
545 varsp
->fFocusDrawState
= false ;
546 varsp
->fUserPaneRec
= theControl
;
547 varsp
->fVisible
= true ;
549 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
551 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
553 /* set up the user pane procedures */
554 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
555 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
556 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
557 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
558 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
559 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
560 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
562 /* calculate the rectangles used by the control */
563 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
564 varsp
->fRTextOutlineRegion
= NewRgn() ;
565 TPCalculateBounds( varsp
, bounds
) ;
567 /* set up the drawing environment */
568 SetPort(varsp
->fDrawingEnvironment
);
570 /* create the new edit field */
572 TXNFrameOptions frameOptions
=
573 kTXNDontDrawCaretWhenInactiveMask
;
574 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
575 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
577 if ( wxStyle
& wxTE_MULTILINE
)
579 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
580 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
583 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
584 frameOptions
|= kTXNWantHScrollBarMask
;
587 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
588 frameOptions
|= kTXNWantVScrollBarMask
;
591 frameOptions
|= kTXNSingleLineOnlyMask
;
593 verify_noerr(TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
595 kTXNTextEditStyleFrameType
,
597 kTXNSystemDefaultEncoding
,
598 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) varsp
));
600 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
601 TXNControlData iControlData
[3] = { {false}, {kTXNAutoWrap
} };
603 #if TARGET_API_MAC_OSX
604 iControlTags
[2] = kTXNVisibilityTag
;
605 iControlData
[2].uValue
= false ;
608 iControlData
[1].uValue
= varsp
->fVisible
;
610 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
611 iControlData
[2].uValue
= kTXNNoAutoWrap
;
613 verify_noerr( TXNSetTXNObjectControls( varsp
->fTXNRec
, false, toptag
,
614 iControlTags
, iControlData
)) ;
620 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
622 TXNTypeAttributes typeAttr
[] =
624 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
625 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
626 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
629 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
634 /* perform final activations and setup for our text field. Here,
635 we assume that the window is going to be the 'active' window. */
636 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
644 #if !USE_SHARED_LIBRARY
645 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
647 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
648 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
649 EVT_CHAR(wxTextCtrl::OnChar
)
650 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
651 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
652 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
653 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
654 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
656 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
657 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
658 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
659 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
660 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
664 static void SetTXNData( STPTextPaneVars
*varsp
, TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
667 #if SIZEOF_WCHAR_T == 2
668 size_t len
= st
.Len() ;
669 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
672 wxMBConvUTF16BE converter
;
673 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
674 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
675 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
676 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
681 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
682 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
688 void wxTextCtrl::Init()
691 m_macTXNvars
= NULL
;
696 m_maxLength
= TE_UNLIMITED_LENGTH
;
699 wxTextCtrl::~wxTextCtrl()
701 SetControlReference((ControlRef
)m_macControl
, 0) ;
702 TXNDeleteObject((TXNObject
)m_macTXN
);
703 /* delete our private storage */
705 /* zero the control reference */
709 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
712 const wxSize
& size
, long style
,
713 const wxValidator
& validator
,
714 const wxString
& name
)
716 m_macIsUserPane
= FALSE
;
719 m_macTXNvars
= NULL
;
722 // base initialization
723 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
726 wxSize mySize
= size
;
728 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
730 if ( m_windowStyle
& wxTE_MULTILINE
)
732 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
733 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
735 m_windowStyle
|= wxTE_PROCESS_ENTER
;
739 wxMacConvertNewlines13To10( &st
) ;
744 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
745 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
746 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
747 /* create the control */
748 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, "\p", true , featurSet
, 0, featurSet
, kControlUserPaneProc
, (long) this );
749 /* set up the mUP specific features and data */
750 wxMacWindowClipper
c(this) ;
751 STPTextPaneVars
*varsp
;
752 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
753 m_macTXNvars
= varsp
;
754 m_macTXN
= varsp
->fTXNRec
;
755 if ( style
& wxTE_PASSWORD
)
758 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
761 MacPostControlCreate(pos
,size
) ;
763 if ( MacIsReallyShown() )
764 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
767 wxMacWindowClipper
clipper( this ) ;
768 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
769 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
771 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
772 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
775 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
776 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
778 SetBackgroundColour( *wxWHITE
) ;
781 tback
.bgType
= kTXNBackgroundTypeRGB
;
782 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
783 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
785 if ( m_windowStyle
& wxTE_READONLY
)
787 SetEditable( false ) ;
790 wxMacCFStringHolder cf
;
791 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cf
, style
& wxTE_PASSWORD
, NULL
, (ControlRef
*) &m_macControl
) ;
798 void wxTextCtrl::MacVisibilityChanged()
800 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
801 if ( !MacIsReallyShown() )
802 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
806 void wxTextCtrl::MacEnabledStateChanged()
811 wxString
wxTextCtrl::GetValue() const
820 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
828 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
829 if ( actualSize
> 0 )
832 #if SIZEOF_WCHAR_T == 2
833 ptr
= new wxChar
[actualSize
+ 1 ] ;
834 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
837 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
839 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
840 wxMBConvUTF16BE converter
;
841 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
842 ptr
= new wxChar
[noChars
+ 1] ;
844 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
848 ptr
[actualSize
] = 0 ;
849 result
= wxString( ptr
) ;
852 DisposeHandle( theText
) ;
856 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
864 actualSize
= GetHandleSize( theText
) ;
865 if ( actualSize
> 0 )
868 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
871 DisposeHandle( theText
) ;
875 wxMacConvertNewlines10To13( &result
) ;
879 void wxTextCtrl::GetSelection(long* from
, long* to
) const
881 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
884 void wxTextCtrl::SetValue(const wxString
& str
)
887 if ( GetValue() == str
)
891 wxMacConvertNewlines13To10( &st
) ;
894 wxMacWindowClipper
c( this ) ;
895 bool formerEditable
= m_editable
;
896 if ( !formerEditable
)
899 // otherwise scrolling might have problems ?
900 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
901 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
902 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
903 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
904 if ( !formerEditable
)
905 SetEditable(formerEditable
) ;
909 void wxTextCtrl::SetMaxLength(unsigned long len
)
914 bool wxTextCtrl::SetFont( const wxFont
& font
)
916 if ( !wxTextCtrlBase::SetFont( font
) )
919 wxMacWindowClipper
c( this ) ;
920 bool formerEditable
= m_editable
;
921 if ( !formerEditable
)
924 TXNTypeAttributes typeAttr
[4] ;
925 Str255 fontName
= "\pMonaco" ;
926 SInt16 fontSize
= 12 ;
927 Style fontStyle
= normal
;
928 int attrCounter
= 0 ;
930 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
931 fontSize
= font
.MacGetFontSize() ;
932 fontStyle
= font
.MacGetFontStyle() ;
934 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
935 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
936 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
937 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
938 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
939 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
940 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
941 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
942 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
945 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
946 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
947 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
948 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
951 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
953 if ( !formerEditable
)
954 SetEditable(formerEditable
) ;
958 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
960 bool formerEditable
= m_editable
;
961 if ( !formerEditable
)
963 TXNTypeAttributes typeAttr
[4] ;
964 Str255 fontName
= "\pMonaco" ;
965 SInt16 fontSize
= 12 ;
966 Style fontStyle
= normal
;
968 int attrCounter
= 0 ;
969 if ( style
.HasFont() )
971 const wxFont
&font
= style
.GetFont() ;
972 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
973 fontSize
= font
.GetPointSize() ;
974 if ( font
.GetUnderlined() )
975 fontStyle
|= underline
;
976 if ( font
.GetWeight() == wxBOLD
)
978 if ( font
.GetStyle() == wxITALIC
)
979 fontStyle
|= italic
;
981 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
982 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
983 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
984 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
985 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
986 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
987 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
988 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
989 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
993 if ( style
.HasTextColour() )
995 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
996 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
997 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
998 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1002 if ( attrCounter
> 0 )
1004 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1006 if ( !formerEditable
)
1007 SetEditable(formerEditable
) ;
1012 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1014 wxTextCtrlBase::SetDefaultStyle( style
) ;
1015 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1019 // Clipboard operations
1020 void wxTextCtrl::Copy()
1024 ClearCurrentScrap();
1025 TXNCopy((TXNObject
)m_macTXN
);
1026 TXNConvertToPublicScrap();
1030 void wxTextCtrl::Cut()
1034 ClearCurrentScrap();
1035 TXNCut((TXNObject
)m_macTXN
);
1036 TXNConvertToPublicScrap();
1038 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1039 event
.SetString( GetValue() ) ;
1040 event
.SetEventObject( this );
1041 GetEventHandler()->ProcessEvent(event
);
1045 void wxTextCtrl::Paste()
1050 TXNConvertFromPublicScrap();
1051 TXNPaste((TXNObject
)m_macTXN
);
1052 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1054 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1055 event
.SetString( GetValue() ) ;
1056 event
.SetEventObject( this );
1057 GetEventHandler()->ProcessEvent(event
);
1061 bool wxTextCtrl::CanCopy() const
1063 // Can copy if there's a selection
1065 GetSelection(& from
, & to
);
1066 return (from
!= to
);
1069 bool wxTextCtrl::CanCut() const
1071 if ( !IsEditable() )
1075 // Can cut if there's a selection
1077 GetSelection(& from
, & to
);
1078 return (from
!= to
);
1081 bool wxTextCtrl::CanPaste() const
1086 return TXNIsScrapPastable() ;
1089 void wxTextCtrl::SetEditable(bool editable
)
1091 if ( editable
!= m_editable
)
1093 m_editable
= editable
;
1095 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1096 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1097 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1102 void wxTextCtrl::SetInsertionPoint(long pos
)
1104 SetSelection( pos
, pos
) ;
1107 void wxTextCtrl::SetInsertionPointEnd()
1109 long pos
= GetLastPosition();
1110 SetInsertionPoint(pos
);
1113 long wxTextCtrl::GetInsertionPoint() const
1116 GetSelection( &begin
, &end
) ;
1120 long wxTextCtrl::GetLastPosition() const
1124 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1132 actualsize
= GetHandleSize( theText
) ;
1133 DisposeHandle( theText
) ;
1138 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1140 wxString value
= str
;
1141 wxMacConvertNewlines13To10( &value
) ;
1143 bool formerEditable
= m_editable
;
1144 if ( !formerEditable
)
1146 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1147 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1148 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1149 if ( !formerEditable
)
1150 SetEditable( formerEditable
) ;
1155 void wxTextCtrl::Remove(long from
, long to
)
1157 bool formerEditable
= m_editable
;
1158 if ( !formerEditable
)
1160 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1161 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1162 if ( !formerEditable
)
1163 SetEditable( formerEditable
) ;
1168 void wxTextCtrl::SetSelection(long from
, long to
)
1170 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) m_macTXNvars
;
1171 /* and our drawing environment as the operation
1172 may force a redraw in the text area. */
1173 SetPort(varsp
->fDrawingEnvironment
);
1174 /* change the selection */
1175 if ((from
== -1) && (to
== -1))
1176 TXNSelectAll((TXNObject
) m_macTXN
);
1178 TXNSetSelection( varsp
->fTXNRec
, from
, to
);
1179 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1182 bool wxTextCtrl::LoadFile(const wxString
& file
)
1184 if ( wxTextCtrlBase::LoadFile(file
) )
1192 void wxTextCtrl::WriteText(const wxString
& str
)
1195 wxMacConvertNewlines13To10( &st
) ;
1197 bool formerEditable
= m_editable
;
1198 if ( !formerEditable
)
1200 long start
, end
, dummy
;
1201 GetSelection( &start
, &dummy
) ;
1202 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1203 GetSelection( &dummy
, &end
) ;
1204 SetStyle( start
, end
, GetDefaultStyle() ) ;
1205 if ( !formerEditable
)
1206 SetEditable( formerEditable
) ;
1208 MacRedrawControl() ;
1211 void wxTextCtrl::AppendText(const wxString
& text
)
1213 SetInsertionPointEnd();
1217 void wxTextCtrl::Clear()
1219 bool formerEditable
= m_editable
;
1220 if ( !formerEditable
)
1222 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1223 TXNClear((TXNObject
)m_macTXN
);
1225 if ( !formerEditable
)
1226 SetEditable( formerEditable
) ;
1231 bool wxTextCtrl::IsModified() const
1236 bool wxTextCtrl::IsEditable() const
1238 return IsEnabled() && m_editable
;
1241 bool wxTextCtrl::AcceptsFocus() const
1243 // we don't want focus if we can't be edited
1244 return /*IsEditable() && */ wxControl::AcceptsFocus();
1247 wxSize
wxTextCtrl::DoGetBestSize() const
1253 switch( m_windowVariant
)
1255 case wxWINDOW_VARIANT_NORMAL
:
1258 case wxWINDOW_VARIANT_SMALL
:
1261 case wxWINDOW_VARIANT_MINI
:
1269 if ( m_windowStyle
& wxTE_MULTILINE
)
1274 return wxSize(wText
, hText
);
1277 // ----------------------------------------------------------------------------
1279 // ----------------------------------------------------------------------------
1281 void wxTextCtrl::Undo()
1285 TXNUndo((TXNObject
)m_macTXN
);
1289 void wxTextCtrl::Redo()
1293 TXNRedo((TXNObject
)m_macTXN
);
1297 bool wxTextCtrl::CanUndo() const
1299 if ( !IsEditable() )
1303 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1306 bool wxTextCtrl::CanRedo() const
1308 if ( !IsEditable() )
1312 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1315 // Makes modifie or unmodified
1316 void wxTextCtrl::MarkDirty()
1321 void wxTextCtrl::DiscardEdits()
1326 int wxTextCtrl::GetNumberOfLines() const
1329 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1333 long wxTextCtrl::XYToPosition(long x
, long y
) const
1337 long lastpos
= GetLastPosition() ;
1339 // TODO find a better implementation : while we can get the
1340 // line metrics of a certain line, we don't get its starting
1341 // position, so it would probably be rather a binary search
1342 // for the start position
1345 int lastHeight
= 0 ;
1348 for ( n
= 0 ; n
<= lastpos
; ++n
)
1350 if ( y
== ypos
&& x
== xpos
)
1353 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1355 if ( curpt
.v
> lastHeight
)
1360 lastHeight
= curpt
.v
;
1369 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1373 long lastpos
= GetLastPosition() ;
1378 if ( pos
<= lastpos
)
1380 // TODO find a better implementation : while we can get the
1381 // line metrics of a certain line, we don't get its starting
1382 // position, so it would probably be rather a binary search
1383 // for the start position
1386 int lastHeight
= 0 ;
1389 for ( n
= 0 ; n
<= pos
; ++n
)
1391 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1393 if ( curpt
.v
> lastHeight
)
1398 lastHeight
= curpt
.v
;
1403 if ( y
) *y
= ypos
;
1404 if ( x
) *x
= xpos
;
1410 void wxTextCtrl::ShowPosition(long pos
)
1412 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1416 TXNOffset selstart
, selend
;
1417 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1418 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1419 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1420 //TODO use HIPoints for 10.3 and above
1421 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1423 OSErr theErr
= noErr
;
1424 SInt32 dv
= desired
.v
- current
.v
;
1425 SInt32 dh
= desired
.h
- current
.h
;
1426 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1427 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1428 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1434 int wxTextCtrl::GetLineLength(long lineNo
) const
1437 if ( lineNo
< GetNumberOfLines() )
1439 // TODO find a better implementation : while we can get the
1440 // line metrics of a certain line, we don't get its starting
1441 // position, so it would probably be rather a binary search
1442 // for the start position
1445 int lastHeight
= 0 ;
1446 long lastpos
= GetLastPosition() ;
1449 for ( n
= 0 ; n
<= lastpos
; ++n
)
1451 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1453 if ( curpt
.v
> lastHeight
)
1455 if ( ypos
== lineNo
)
1461 lastHeight
= curpt
.v
;
1471 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1475 wxString content
= GetValue() ;
1477 if ( lineNo
< GetNumberOfLines() )
1479 // TODO find a better implementation : while we can get the
1480 // line metrics of a certain line, we don't get its starting
1481 // position, so it would probably be rather a binary search
1482 // for the start position
1485 int lastHeight
= 0 ;
1486 long lastpos
= GetLastPosition() ;
1489 for ( n
= 0 ; n
<= lastpos
; ++n
)
1491 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1493 if ( curpt
.v
> lastHeight
)
1495 if ( ypos
== lineNo
)
1501 lastHeight
= curpt
.v
;
1505 if ( ypos
== lineNo
)
1506 line
+= content
[n
] ;
1519 void wxTextCtrl::Command(wxCommandEvent
& event
)
1521 SetValue (event
.GetString());
1522 ProcessCommand (event
);
1525 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1527 // By default, load the first file into the text window.
1528 if (event
.GetNumberOfFiles() > 0)
1530 LoadFile(event
.GetFiles()[0]);
1534 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1536 int key
= event
.GetKeyCode() ;
1537 bool eat_key
= false ;
1539 if ( key
== 'c' && event
.MetaDown() )
1546 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1547 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1548 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1555 // assume that any key not processed yet is going to modify the control
1558 if ( key
== 'v' && event
.MetaDown() )
1564 if ( key
== 'x' && event
.MetaDown() )
1573 if (m_windowStyle
& wxPROCESS_ENTER
)
1575 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1576 event
.SetEventObject( this );
1577 event
.SetString( GetValue() );
1578 if ( GetEventHandler()->ProcessEvent(event
) )
1581 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1583 wxWindow
*parent
= GetParent();
1584 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1585 parent
= parent
->GetParent() ;
1587 if ( parent
&& parent
->GetDefaultItem() )
1589 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1591 if ( def
&& def
->IsEnabled() )
1593 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1594 event
.SetEventObject(def
);
1595 def
->Command(event
);
1600 // this will make wxWindows eat the ENTER key so that
1601 // we actually prevent line wrapping in a single line
1609 // always produce navigation event - even if we process TAB
1610 // ourselves the fact that we got here means that the user code
1611 // decided to skip processing of this TAB - probably to let it
1612 // do its default job.
1614 wxNavigationKeyEvent eventNav
;
1615 eventNav
.SetDirection(!event
.ShiftDown());
1616 eventNav
.SetWindowChange(event
.ControlDown());
1617 eventNav
.SetEventObject(this);
1619 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1630 // perform keystroke handling
1631 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1632 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1636 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1638 EventRecord
*ev
= &rec
;
1641 keychar
= short(ev
->message
& charCodeMask
);
1642 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1644 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1648 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1649 key
== WXK_RETURN
||
1650 key
== WXK_DELETE
||
1653 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1654 event1
.SetString( GetValue() ) ;
1655 event1
.SetEventObject( this );
1656 wxPostEvent(GetEventHandler(),event1
);
1660 // ----------------------------------------------------------------------------
1661 // standard handlers for standard edit menu events
1662 // ----------------------------------------------------------------------------
1664 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1669 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1674 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1679 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1684 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1689 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1691 event
.Enable( CanCut() );
1694 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1696 event
.Enable( CanCopy() );
1699 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1701 event
.Enable( CanPaste() );
1704 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1706 event
.Enable( CanUndo() );
1709 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1711 event
.Enable( CanRedo() );
1714 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1719 // user pane implementation
1721 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1725 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1727 return kControlNoPart
;
1730 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1732 return kControlNoPart
;
1735 void wxTextCtrl::MacControlUserPaneIdleProc()
1739 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1741 return kControlNoPart
;
1744 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1748 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1750 return kControlNoPart
;
1753 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)