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}, {kTXNNoAutoWrap
} };
605 #if TARGET_API_MAC_OSX
606 iControlTags
[2] = kTXNVisibilityTag
;
607 iControlData
[2].uValue
= varsp
->fVisible
;
611 if ( wxStyle
& wxTE_MULTILINE
)
613 if (wxStyle
& wxTE_DONTWRAP
)
614 iControlData
[1].uValue
= kTXNNoAutoWrap
;
616 iControlData
[1].uValue
= kTXNAutoWrap
;
619 verify_noerr( TXNSetTXNObjectControls( varsp
->fTXNRec
, false, toptag
,
620 iControlTags
, iControlData
)) ;
626 GetThemeFont(kThemeSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
628 TXNTypeAttributes typeAttr
[] =
630 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
631 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
632 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
635 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
640 /* perform final activations and setup for our text field. Here,
641 we assume that the window is going to be the 'active' window. */
642 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
650 #if !USE_SHARED_LIBRARY
651 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
653 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
654 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
655 EVT_CHAR(wxTextCtrl::OnChar
)
656 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
657 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
658 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
659 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
660 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
662 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
663 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
664 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
665 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
666 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
670 static void SetTXNData( STPTextPaneVars
*varsp
, TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
673 #if SIZEOF_WCHAR_T == 2
674 size_t len
= st
.Len() ;
675 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
678 wxMBConvUTF16BE converter
;
679 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
680 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
681 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
682 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
687 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
688 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
694 void wxTextCtrl::Init()
697 m_macTXNvars
= NULL
;
702 m_maxLength
= TE_UNLIMITED_LENGTH
;
705 wxTextCtrl::~wxTextCtrl()
707 SetControlReference((ControlRef
)m_macControl
, 0) ;
708 TXNDeleteObject((TXNObject
)m_macTXN
);
709 /* delete our private storage */
711 /* zero the control reference */
715 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
718 const wxSize
& size
, long style
,
719 const wxValidator
& validator
,
720 const wxString
& name
)
722 m_macIsUserPane
= FALSE
;
725 m_macTXNvars
= NULL
;
728 // base initialization
729 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
732 wxSize mySize
= size
;
734 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
736 if ( m_windowStyle
& wxTE_MULTILINE
)
738 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
739 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
741 m_windowStyle
|= wxTE_PROCESS_ENTER
;
745 wxMacConvertNewlines13To10( &st
) ;
750 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
751 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
752 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
753 /* create the control */
754 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, "\p", true , featurSet
, 0, featurSet
, kControlUserPaneProc
, (long) this );
755 /* set up the mUP specific features and data */
756 wxMacWindowClipper
c(this) ;
757 STPTextPaneVars
*varsp
;
758 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
759 m_macTXNvars
= varsp
;
760 m_macTXN
= varsp
->fTXNRec
;
761 if ( style
& wxTE_PASSWORD
)
764 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
767 MacPostControlCreate(pos
,size
) ;
769 if ( MacIsReallyShown() )
770 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
773 wxMacWindowClipper
clipper( this ) ;
774 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
775 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
777 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
778 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
781 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
782 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
784 SetBackgroundColour( *wxWHITE
) ;
787 tback
.bgType
= kTXNBackgroundTypeRGB
;
788 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
789 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
791 if ( m_windowStyle
& wxTE_READONLY
)
793 SetEditable( false ) ;
796 wxMacCFStringHolder cf
;
797 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cf
, style
& wxTE_PASSWORD
, NULL
, (ControlRef
*) &m_macControl
) ;
804 void wxTextCtrl::MacVisibilityChanged()
806 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
807 if ( !MacIsReallyShown() )
808 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
812 void wxTextCtrl::MacEnabledStateChanged()
817 wxString
wxTextCtrl::GetValue() const
826 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
834 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
835 if ( actualSize
> 0 )
838 #if SIZEOF_WCHAR_T == 2
839 ptr
= new wxChar
[actualSize
+ 1 ] ;
840 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
843 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
845 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
846 wxMBConvUTF16BE converter
;
847 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
848 ptr
= new wxChar
[noChars
+ 1] ;
850 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
854 ptr
[actualSize
] = 0 ;
855 result
= wxString( ptr
) ;
858 DisposeHandle( theText
) ;
862 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
870 actualSize
= GetHandleSize( theText
) ;
871 if ( actualSize
> 0 )
874 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
877 DisposeHandle( theText
) ;
881 wxMacConvertNewlines10To13( &result
) ;
885 void wxTextCtrl::GetSelection(long* from
, long* to
) const
887 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
890 void wxTextCtrl::SetValue(const wxString
& str
)
893 if ( GetValue() == str
)
897 wxMacConvertNewlines13To10( &st
) ;
900 wxMacWindowClipper
c( this ) ;
901 bool formerEditable
= m_editable
;
902 if ( !formerEditable
)
905 // otherwise scrolling might have problems ?
906 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
907 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
908 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
909 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
910 if ( !formerEditable
)
911 SetEditable(formerEditable
) ;
915 void wxTextCtrl::SetMaxLength(unsigned long len
)
920 bool wxTextCtrl::SetFont( const wxFont
& font
)
922 if ( !wxTextCtrlBase::SetFont( font
) )
925 wxMacWindowClipper
c( this ) ;
926 bool formerEditable
= m_editable
;
927 if ( !formerEditable
)
930 TXNTypeAttributes typeAttr
[4] ;
931 Str255 fontName
= "\pMonaco" ;
932 SInt16 fontSize
= 12 ;
933 Style fontStyle
= normal
;
934 int attrCounter
= 0 ;
936 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
937 fontSize
= font
.MacGetFontSize() ;
938 fontStyle
= font
.MacGetFontStyle() ;
940 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
941 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
942 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
943 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
944 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
945 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
946 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
947 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
948 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
951 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
952 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
953 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
954 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
957 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
959 if ( !formerEditable
)
960 SetEditable(formerEditable
) ;
964 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
966 bool formerEditable
= m_editable
;
967 if ( !formerEditable
)
969 TXNTypeAttributes typeAttr
[4] ;
970 Str255 fontName
= "\pMonaco" ;
971 SInt16 fontSize
= 12 ;
972 Style fontStyle
= normal
;
974 int attrCounter
= 0 ;
975 if ( style
.HasFont() )
977 const wxFont
&font
= style
.GetFont() ;
978 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
979 fontSize
= font
.GetPointSize() ;
980 if ( font
.GetUnderlined() )
981 fontStyle
|= underline
;
982 if ( font
.GetWeight() == wxBOLD
)
984 if ( font
.GetStyle() == wxITALIC
)
985 fontStyle
|= italic
;
987 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
988 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
989 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
990 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
991 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
992 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
993 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
994 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
995 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
999 if ( style
.HasTextColour() )
1001 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1002 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1003 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1004 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1008 if ( attrCounter
> 0 )
1010 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1012 if ( !formerEditable
)
1013 SetEditable(formerEditable
) ;
1018 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1020 wxTextCtrlBase::SetDefaultStyle( style
) ;
1021 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1025 // Clipboard operations
1026 void wxTextCtrl::Copy()
1030 ClearCurrentScrap();
1031 TXNCopy((TXNObject
)m_macTXN
);
1032 TXNConvertToPublicScrap();
1036 void wxTextCtrl::Cut()
1040 ClearCurrentScrap();
1041 TXNCut((TXNObject
)m_macTXN
);
1042 TXNConvertToPublicScrap();
1044 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1045 event
.SetString( GetValue() ) ;
1046 event
.SetEventObject( this );
1047 GetEventHandler()->ProcessEvent(event
);
1051 void wxTextCtrl::Paste()
1056 TXNConvertFromPublicScrap();
1057 TXNPaste((TXNObject
)m_macTXN
);
1058 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1060 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1061 event
.SetString( GetValue() ) ;
1062 event
.SetEventObject( this );
1063 GetEventHandler()->ProcessEvent(event
);
1067 bool wxTextCtrl::CanCopy() const
1069 // Can copy if there's a selection
1071 GetSelection(& from
, & to
);
1072 return (from
!= to
);
1075 bool wxTextCtrl::CanCut() const
1077 if ( !IsEditable() )
1081 // Can cut if there's a selection
1083 GetSelection(& from
, & to
);
1084 return (from
!= to
);
1087 bool wxTextCtrl::CanPaste() const
1092 return TXNIsScrapPastable() ;
1095 void wxTextCtrl::SetEditable(bool editable
)
1097 if ( editable
!= m_editable
)
1099 m_editable
= editable
;
1101 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1102 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1103 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1108 void wxTextCtrl::SetInsertionPoint(long pos
)
1110 SetSelection( pos
, pos
) ;
1113 void wxTextCtrl::SetInsertionPointEnd()
1115 long pos
= GetLastPosition();
1116 SetInsertionPoint(pos
);
1119 long wxTextCtrl::GetInsertionPoint() const
1122 GetSelection( &begin
, &end
) ;
1126 long wxTextCtrl::GetLastPosition() const
1130 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1138 actualsize
= GetHandleSize( theText
) ;
1139 DisposeHandle( theText
) ;
1144 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1146 wxString value
= str
;
1147 wxMacConvertNewlines13To10( &value
) ;
1149 bool formerEditable
= m_editable
;
1150 if ( !formerEditable
)
1152 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1153 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1154 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1155 if ( !formerEditable
)
1156 SetEditable( formerEditable
) ;
1161 void wxTextCtrl::Remove(long from
, long to
)
1163 bool formerEditable
= m_editable
;
1164 if ( !formerEditable
)
1166 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1167 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1168 if ( !formerEditable
)
1169 SetEditable( formerEditable
) ;
1174 void wxTextCtrl::SetSelection(long from
, long to
)
1176 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) m_macTXNvars
;
1177 /* and our drawing environment as the operation
1178 may force a redraw in the text area. */
1179 SetPort(varsp
->fDrawingEnvironment
);
1180 /* change the selection */
1181 if ((from
== -1) && (to
== -1))
1182 TXNSelectAll((TXNObject
) m_macTXN
);
1184 TXNSetSelection( varsp
->fTXNRec
, from
, to
);
1185 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1188 bool wxTextCtrl::LoadFile(const wxString
& file
)
1190 if ( wxTextCtrlBase::LoadFile(file
) )
1198 void wxTextCtrl::WriteText(const wxString
& str
)
1201 wxMacConvertNewlines13To10( &st
) ;
1203 bool formerEditable
= m_editable
;
1204 if ( !formerEditable
)
1206 long start
, end
, dummy
;
1207 GetSelection( &start
, &dummy
) ;
1208 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1209 GetSelection( &dummy
, &end
) ;
1210 SetStyle( start
, end
, GetDefaultStyle() ) ;
1211 if ( !formerEditable
)
1212 SetEditable( formerEditable
) ;
1214 MacRedrawControl() ;
1217 void wxTextCtrl::AppendText(const wxString
& text
)
1219 SetInsertionPointEnd();
1223 void wxTextCtrl::Clear()
1225 bool formerEditable
= m_editable
;
1226 if ( !formerEditable
)
1228 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1229 TXNClear((TXNObject
)m_macTXN
);
1231 if ( !formerEditable
)
1232 SetEditable( formerEditable
) ;
1237 bool wxTextCtrl::IsModified() const
1242 bool wxTextCtrl::IsEditable() const
1244 return IsEnabled() && m_editable
;
1247 bool wxTextCtrl::AcceptsFocus() const
1249 // we don't want focus if we can't be edited
1250 return /*IsEditable() && */ wxControl::AcceptsFocus();
1253 wxSize
wxTextCtrl::DoGetBestSize() const
1259 switch( m_windowVariant
)
1261 case wxWINDOW_VARIANT_NORMAL
:
1264 case wxWINDOW_VARIANT_SMALL
:
1267 case wxWINDOW_VARIANT_MINI
:
1275 if ( m_windowStyle
& wxTE_MULTILINE
)
1280 return wxSize(wText
, hText
);
1283 // ----------------------------------------------------------------------------
1285 // ----------------------------------------------------------------------------
1287 void wxTextCtrl::Undo()
1291 TXNUndo((TXNObject
)m_macTXN
);
1295 void wxTextCtrl::Redo()
1299 TXNRedo((TXNObject
)m_macTXN
);
1303 bool wxTextCtrl::CanUndo() const
1305 if ( !IsEditable() )
1309 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1312 bool wxTextCtrl::CanRedo() const
1314 if ( !IsEditable() )
1318 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1321 // Makes modifie or unmodified
1322 void wxTextCtrl::MarkDirty()
1327 void wxTextCtrl::DiscardEdits()
1332 int wxTextCtrl::GetNumberOfLines() const
1335 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1339 long wxTextCtrl::XYToPosition(long x
, long y
) const
1343 long lastpos
= GetLastPosition() ;
1345 // TODO find a better implementation : while we can get the
1346 // line metrics of a certain line, we don't get its starting
1347 // position, so it would probably be rather a binary search
1348 // for the start position
1351 int lastHeight
= 0 ;
1354 for ( n
= 0 ; n
<= lastpos
; ++n
)
1356 if ( y
== ypos
&& x
== xpos
)
1359 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1361 if ( curpt
.v
> lastHeight
)
1366 lastHeight
= curpt
.v
;
1375 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1379 long lastpos
= GetLastPosition() ;
1384 if ( pos
<= lastpos
)
1386 // TODO find a better implementation : while we can get the
1387 // line metrics of a certain line, we don't get its starting
1388 // position, so it would probably be rather a binary search
1389 // for the start position
1392 int lastHeight
= 0 ;
1395 for ( n
= 0 ; n
<= pos
; ++n
)
1397 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1399 if ( curpt
.v
> lastHeight
)
1404 lastHeight
= curpt
.v
;
1409 if ( y
) *y
= ypos
;
1410 if ( x
) *x
= xpos
;
1416 void wxTextCtrl::ShowPosition(long pos
)
1418 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1422 TXNOffset selstart
, selend
;
1423 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1424 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1425 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1426 //TODO use HIPoints for 10.3 and above
1427 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1429 OSErr theErr
= noErr
;
1430 SInt32 dv
= desired
.v
- current
.v
;
1431 SInt32 dh
= desired
.h
- current
.h
;
1432 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1433 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1434 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1440 int wxTextCtrl::GetLineLength(long lineNo
) const
1443 if ( lineNo
< GetNumberOfLines() )
1445 // TODO find a better implementation : while we can get the
1446 // line metrics of a certain line, we don't get its starting
1447 // position, so it would probably be rather a binary search
1448 // for the start position
1451 int lastHeight
= 0 ;
1452 long lastpos
= GetLastPosition() ;
1455 for ( n
= 0 ; n
<= lastpos
; ++n
)
1457 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1459 if ( curpt
.v
> lastHeight
)
1461 if ( ypos
== lineNo
)
1467 lastHeight
= curpt
.v
;
1477 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1481 wxString content
= GetValue() ;
1483 if ( lineNo
< GetNumberOfLines() )
1485 // TODO find a better implementation : while we can get the
1486 // line metrics of a certain line, we don't get its starting
1487 // position, so it would probably be rather a binary search
1488 // for the start position
1491 int lastHeight
= 0 ;
1492 long lastpos
= GetLastPosition() ;
1495 for ( n
= 0 ; n
<= lastpos
; ++n
)
1497 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1499 if ( curpt
.v
> lastHeight
)
1501 if ( ypos
== lineNo
)
1507 lastHeight
= curpt
.v
;
1511 if ( ypos
== lineNo
)
1512 line
+= content
[n
] ;
1525 void wxTextCtrl::Command(wxCommandEvent
& event
)
1527 SetValue (event
.GetString());
1528 ProcessCommand (event
);
1531 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1533 // By default, load the first file into the text window.
1534 if (event
.GetNumberOfFiles() > 0)
1536 LoadFile(event
.GetFiles()[0]);
1540 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1542 int key
= event
.GetKeyCode() ;
1543 bool eat_key
= false ;
1545 if ( key
== 'c' && event
.MetaDown() )
1552 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1553 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1554 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1561 // assume that any key not processed yet is going to modify the control
1564 if ( key
== 'v' && event
.MetaDown() )
1570 if ( key
== 'x' && event
.MetaDown() )
1579 if (m_windowStyle
& wxPROCESS_ENTER
)
1581 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1582 event
.SetEventObject( this );
1583 event
.SetString( GetValue() );
1584 if ( GetEventHandler()->ProcessEvent(event
) )
1587 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1589 wxWindow
*parent
= GetParent();
1590 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1591 parent
= parent
->GetParent() ;
1593 if ( parent
&& parent
->GetDefaultItem() )
1595 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1597 if ( def
&& def
->IsEnabled() )
1599 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1600 event
.SetEventObject(def
);
1601 def
->Command(event
);
1606 // this will make wxWindows eat the ENTER key so that
1607 // we actually prevent line wrapping in a single line
1615 // always produce navigation event - even if we process TAB
1616 // ourselves the fact that we got here means that the user code
1617 // decided to skip processing of this TAB - probably to let it
1618 // do its default job.
1620 wxNavigationKeyEvent eventNav
;
1621 eventNav
.SetDirection(!event
.ShiftDown());
1622 eventNav
.SetWindowChange(event
.ControlDown());
1623 eventNav
.SetEventObject(this);
1625 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1636 // perform keystroke handling
1637 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1638 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1642 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1644 EventRecord
*ev
= &rec
;
1647 keychar
= short(ev
->message
& charCodeMask
);
1648 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1650 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1654 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1655 key
== WXK_RETURN
||
1656 key
== WXK_DELETE
||
1659 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1660 event1
.SetString( GetValue() ) ;
1661 event1
.SetEventObject( this );
1662 wxPostEvent(GetEventHandler(),event1
);
1666 // ----------------------------------------------------------------------------
1667 // standard handlers for standard edit menu events
1668 // ----------------------------------------------------------------------------
1670 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1675 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1680 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1685 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1690 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1695 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1697 event
.Enable( CanCut() );
1700 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1702 event
.Enable( CanCopy() );
1705 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1707 event
.Enable( CanPaste() );
1710 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1712 event
.Enable( CanUndo() );
1715 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1717 event
.Enable( CanRedo() );
1720 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1725 // user pane implementation
1727 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1731 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1733 return kControlNoPart
;
1736 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1738 return kControlNoPart
;
1741 void wxTextCtrl::MacControlUserPaneIdleProc()
1745 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1747 return kControlNoPart
;
1750 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1754 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1756 return kControlNoPart
;
1759 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)