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
64 #if TARGET_API_MAC_OSX
65 #define wxMAC_USE_MLTE 1
66 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
67 #define wxMAC_USE_MLTE_HIVIEW 1
69 #define wxMAC_USE_MLTE_HIVIEW 0
72 // there is no unicodetextctrl on classic, and hopefully MLTE works better there
73 #define wxMAC_USE_MLTE 1
74 #define wxMAC_USE_MLTE_HIVIEW 0
79 TXNFrameOptions
FrameOptionsFromWXStyle( long wxStyle
)
81 TXNFrameOptions frameOptions
=
82 kTXNDontDrawCaretWhenInactiveMask
;
83 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
84 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
86 if ( wxStyle
& wxTE_MULTILINE
)
88 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
89 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
92 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
93 frameOptions
|= kTXNWantHScrollBarMask
;
96 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
97 frameOptions
|= kTXNWantVScrollBarMask
;
100 frameOptions
|= kTXNSingleLineOnlyMask
;
101 return frameOptions
;
104 void AdjustAttributesFromWXStyle( TXNObject txn
, long wxStyle
, bool visible
)
106 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
107 TXNControlData iControlData
[3] = { {false}, {kTXNNoAutoWrap
} };
109 #if TARGET_API_MAC_OSX
110 iControlTags
[2] = kTXNVisibilityTag
;
111 iControlData
[2].uValue
= visible
;
115 if ( wxStyle
& wxTE_MULTILINE
)
117 if (wxStyle
& wxTE_DONTWRAP
)
118 iControlData
[1].uValue
= kTXNNoAutoWrap
;
120 iControlData
[1].uValue
= kTXNAutoWrap
;
123 verify_noerr( TXNSetTXNObjectControls( txn
, false, toptag
,
124 iControlTags
, iControlData
)) ;
130 GetThemeFont(kThemeSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
132 TXNTypeAttributes typeAttr
[] =
134 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
135 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
136 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
139 verify_noerr( TXNSetTypeAttributes (txn
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
145 #if !wxMAC_USE_MLTE_HIVIEW
147 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
148 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
149 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
150 // an alternate path for carbon key events that routes automatically into the same wx flow of events
154 /* kmUPTextPart is the part code we return to indicate the user has clicked
155 in the text area of our control */
156 #define kmUPTextPart 1
159 /* routines for using existing user pane controls.
160 These routines are useful for cases where you would like to use an
161 existing user pane control in, say, a dialog window as a scrolling
164 /* Utility Routines */
166 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
167 routine. In our focus switching routine this part code is understood
168 as meaning 'the user has clicked in the control and we need to switch
169 the current focus to ourselves before we can continue'. */
170 #define kUserClickedToFocusPart 100
172 /* STPTextPaneVars is a structure used for storing the the mUP Control's
173 internal variables and state information. A handle to this record is
174 stored in the pane control's reference value field using the
175 SetControlReference routine. */
178 /* OS records referenced */
179 TXNObject fTXNRec
; /* the txn record */
180 TXNFrameID fTXNFrame
; /* the txn frame ID */
181 ControlRef fUserPaneRec
; /* handle to the user pane control */
182 WindowPtr fOwner
; /* window containing control */
183 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
185 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
186 Boolean fIsActive
; /* true while the control is drawn in the active state */
187 Boolean fTXNObjectActive
; /* reflects the activation state of the text edit record */
188 Boolean fFocusDrawState
; /* true if focus is drawn (default: true) */
189 /* calculated locations */
190 Rect fRBounds
; /* control bounds */
191 Rect fRTextArea
; /* area where the text is drawn */
192 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
193 Rect fRTextOutline
; /* rectangle used to draw the border */
194 RgnHandle fRTextOutlineRegion
; /* background region for the text, erased before calling TEUpdate */
195 /* our focus advance override routine */
196 EventHandlerUPP handlerUPP
;
197 EventHandlerRef handlerRef
;
203 /* mUPOpenControl initializes a user pane control so it will be drawn
204 and will behave as a scrolling text edit field inside of a window.
205 This routine performs all of the initialization steps necessary,
206 except it does not create the user pane control itself. theControl
207 should refer to a user pane control that you have either created
208 yourself or extracted from a dialog's control heirarchy using
209 the GetDialogItemAsControl routine. */
210 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
);
215 /* Univerals Procedure Pointer variables used by the
216 mUP Control. These variables are set up
217 the first time that mUPOpenControl is called. */
218 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
219 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
220 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
221 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
222 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
223 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
224 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
226 // one place for calculating all
227 static void TPCalculateBounds(STPTextPaneVars
*varsp
, const Rect
& bounds
)
229 SetRect(&varsp
->fRBounds
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
230 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
231 // eventually make TextOutline inset 1,1
232 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
233 if ( !varsp
->fNoBorders
)
235 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
236 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
240 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
241 bounds
.right
, bounds
.bottom
);
245 OSStatus
MLTESetObjectVisibility( STPTextPaneVars
*varsp
, Boolean vis
, long wxStyle
)
247 OSStatus err
= noErr
;
248 #if TARGET_API_MAC_OSX
249 TXNControlTag iControlTags
[1] = { kTXNVisibilityTag
};
250 TXNControlData iControlData
[1] = {{ vis
}};
251 err
= ::TXNSetTXNObjectControls( varsp
->fTXNRec
, false, 1, iControlTags
, iControlData
);
253 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
254 if ( vis
&& textctrl
)
257 UMAGetControlBoundsInWindowCoords( varsp
->fUserPaneRec
, &bounds
);
258 TPCalculateBounds( varsp
, bounds
) ;
259 wxMacWindowClipper
cl(textctrl
) ;
260 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
261 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
262 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
267 // make sure we don't miss changes as carbon events are not available for these under classic
268 static void TPUpdateVisibility(ControlRef theControl
) {
269 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
270 if ( textctrl
== NULL
)
273 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
276 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
277 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
279 // invalidate old position
280 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
281 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
283 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
286 Rect oldBounds
= varsp
->fRBounds
;
287 TPCalculateBounds( varsp
, bounds
) ;
288 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
289 if ( varsp
->fVisible
)
291 wxMacWindowClipper
cl(textctrl
) ;
292 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
293 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
295 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
296 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
300 // make correct activations
301 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
303 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
304 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
306 varsp
->fTXNObjectActive
= setActive
;
307 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
309 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
313 // update focus outlines
314 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
317 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
319 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
320 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
324 // update TXN focus state
325 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
326 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
328 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
329 varsp
->fInFocus
= setFocus
;
330 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
335 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
336 /* set up our globals */
338 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
339 if ( textctrl
== NULL
)
341 TPUpdateVisibility( theControl
) ;
343 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
344 if ( textctrl
->MacIsReallyShown() )
346 wxMacWindowClipper
clipper( textctrl
) ;
347 TXNDraw(varsp
->fTXNRec
, NULL
);
348 if ( !varsp
->fNoBorders
)
349 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
350 TPRedrawFocusOutline( varsp
) ;
356 /* TPPaneHitTestProc is called when the control manager would
357 like to determine what part of the control the mouse resides over.
358 We also call this routine from our tracking proc to determine how
359 to handle mouse clicks. */
360 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
361 ControlPartCode result
;
362 /* set up our locals and lock down our globals*/
364 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
365 if ( textctrl
== NULL
)
367 TPUpdateVisibility( theControl
) ;
368 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
369 if (textctrl
->MacIsReallyShown() )
371 if (PtInRect(where
, &varsp
->fRBounds
))
372 result
= kmUPTextPart
;
383 /* TPPaneTrackingProc is called when the mouse is being held down
384 over our control. This routine handles clicks in the text area
385 and in the scroll bar. */
386 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
388 ControlPartCode partCodeResult
;
389 /* make sure we have some variables... */
391 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
392 if ( textctrl
== NULL
)
394 TPUpdateVisibility( theControl
) ;
395 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
396 if (textctrl
->MacIsReallyShown() )
398 /* we don't do any of these functions unless we're in focus */
399 if ( ! varsp
->fInFocus
) {
401 owner
= GetControlOwner(theControl
);
402 ClearKeyboardFocus(owner
);
403 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
405 /* find the location for the click */
406 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
407 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
410 textctrl
->MacClientToRootWindow( &x
, &y
) ;
415 switch (TPPaneHitTestProc(theControl
, startPt
))
418 /* handle clicks in the text part */
421 wxMacWindowClipper
clipper( textctrl
) ;
424 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
425 TXNClick( varsp
->fTXNRec
, &rec
);
432 return partCodeResult
;
436 /* TPPaneIdleProc is our user pane idle routine. When our text field
437 is active and in focus, we use this routine to set the cursor. */
438 static pascal void TPPaneIdleProc(ControlRef theControl
) {
440 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
441 if ( textctrl
== NULL
)
443 TPUpdateVisibility( theControl
) ;
444 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
445 if (textctrl
->MacIsReallyShown()) {
446 /* if we're not active, then we have nothing to say about the cursor */
447 if (varsp
->fIsActive
) {
451 wxMacWindowClipper
clipper( textctrl
) ;
453 /* there's a 'focus thing' and an 'unfocused thing' */
454 if (varsp
->fInFocus
) {
455 /* flash the cursor */
456 SetPort(varsp
->fDrawingEnvironment
);
457 TXNIdle(varsp
->fTXNRec
);
459 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
461 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
462 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
467 // SetThemeCursor(kThemeArrowCursor);
470 /* if it's in our bounds, set the cursor */
471 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
472 if (PtInRect(mousep
, &bounds
))
474 // SetThemeCursor(kThemeArrowCursor);
482 /* TPPaneKeyDownProc is called whenever a keydown event is directed
483 at our control. Here, we direct the keydown event to the text
484 edit record and redraw the scroll bar and text field as appropriate. */
485 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
486 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
488 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
489 if ( textctrl
== NULL
)
491 TPUpdateVisibility( theControl
) ;
493 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
496 /* turn autoscrolling on and send the key event to text edit */
497 wxMacWindowClipper
clipper( textctrl
) ;
499 memset( &ev
, 0 , sizeof( ev
) ) ;
501 ev
.modifiers
= modifiers
;
502 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
503 TXNKeyDown( varsp
->fTXNRec
, &ev
);
505 return kControlEntireControl
;
509 /* TPPaneActivateProc is called when the window containing
510 the user pane control receives activate events. Here, we redraw
511 the control and it's text as necessary for the activation state. */
512 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
514 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
516 if ( textctrl
== NULL
)
518 TPUpdateVisibility( theControl
) ;
520 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
522 varsp
->fIsActive
= activating
;
523 wxMacWindowClipper
clipper( textctrl
) ;
524 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
525 /* redraw the frame */
526 if ( textctrl
->MacIsReallyShown() )
528 if ( !varsp
->fNoBorders
)
529 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
530 TPRedrawFocusOutline( varsp
) ;
535 /* TPPaneFocusProc is called when every the focus changes to or
536 from our control. Herein, switch the focus appropriately
537 according to the parameters and redraw the control as
539 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
540 ControlPartCode focusResult
;
542 focusResult
= kControlFocusNoPart
;
543 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
544 if ( textctrl
== NULL
)
546 TPUpdateVisibility( theControl
) ;
547 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
548 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
549 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
550 and kControlFocusNextPart will be received. When the user clicks in our field
551 and it is not the current focus, then the constant kUserClickedToFocusPart will
552 be received. The constant kControlFocusNoPart will be received when our control
553 is the current focus and the user clicks in another control. In your focus routine,
554 you should respond to these codes as follows:
556 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
557 the control and the focus rectangle as necessary.
559 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
560 depending on its current state. redraw the control and the focus rectangle
561 as appropriate for the new focus state. If the focus state is 'off', return the constant
562 kControlFocusNoPart, otherwise return a non-zero part code.
563 kUserClickedToFocusPart - is a constant defined for this example. You should
564 define your own value for handling click-to-focus type events. */
565 /* calculate the next highlight state */
568 case kControlFocusNoPart
:
569 TPFocusPaneText(varsp
, false);
570 focusResult
= kControlFocusNoPart
;
572 case kUserClickedToFocusPart
:
573 TPFocusPaneText(varsp
, true);
576 case kControlFocusPrevPart
:
577 case kControlFocusNextPart
:
578 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
579 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
582 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
583 /* redraw the text fram and focus rectangle to indicate the
585 if ( textctrl
->MacIsReallyShown() )
587 wxMacWindowClipper
c( textctrl
) ;
588 if ( !varsp
->fNoBorders
)
589 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
590 TPRedrawFocusOutline( varsp
) ;
596 /* mUPOpenControl initializes a user pane control so it will be drawn
597 and will behave as a scrolling text edit field inside of a window.
598 This routine performs all of the initialization steps necessary,
599 except it does not create the user pane control itself. theControl
600 should refer to a user pane control that you have either created
601 yourself or extracted from a dialog's control heirarchy using
602 the GetDialogItemAsControl routine. */
603 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
)
607 STPTextPaneVars
*varsp
;
608 OSStatus err
= noErr
;
610 /* set up our globals */
611 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
612 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
613 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
614 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
615 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
616 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
617 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
619 /* allocate our private storage */
620 varsp
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
623 /* set the initial settings for our private data */
624 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
625 varsp
->fNoBorders
= wxStyle
& wxNO_BORDER
;
626 varsp
->fInFocus
= false;
627 varsp
->fIsActive
= true;
628 varsp
->fTXNObjectActive
= false;
629 varsp
->fFocusDrawState
= false ;
630 varsp
->fUserPaneRec
= theControl
;
631 varsp
->fVisible
= true ;
633 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
635 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
637 /* set up the user pane procedures */
638 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
639 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
640 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
641 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
642 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
643 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
644 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
646 /* calculate the rectangles used by the control */
647 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
648 varsp
->fRTextOutlineRegion
= NewRgn() ;
649 TPCalculateBounds( varsp
, bounds
) ;
651 /* set up the drawing environment */
652 SetPort(varsp
->fDrawingEnvironment
);
654 /* create the new edit field */
656 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( wxStyle
) ;
658 verify_noerr(TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
660 kTXNTextEditStyleFrameType
,
662 kTXNSystemDefaultEncoding
,
663 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) varsp
));
665 AdjustAttributesFromWXStyle( varsp
->fTXNRec
, wxStyle
, varsp
->fVisible
) ;
666 /* perform final activations and setup for our text field. Here,
667 we assume that the window is going to be the 'active' window. */
668 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
674 struct STPTextPaneVars
680 static void SetTXNData( STPTextPaneVars
*varsp
, TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
683 #if SIZEOF_WCHAR_T == 2
684 size_t len
= st
.Len() ;
685 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
688 wxMBConvUTF16BE converter
;
689 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
690 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
691 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
692 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
697 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
698 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
706 #if !USE_SHARED_LIBRARY
707 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
709 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
710 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
711 EVT_CHAR(wxTextCtrl::OnChar
)
712 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
713 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
714 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
715 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
716 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
718 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
719 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
720 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
721 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
722 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
727 void wxTextCtrl::Init()
730 m_macTXNvars
= NULL
;
735 m_maxLength
= TE_UNLIMITED_LENGTH
;
738 wxTextCtrl::~wxTextCtrl()
741 SetControlReference((ControlRef
)m_macControl
, 0) ;
742 #if !wxMAC_USE_MLTE_HIVIEW
743 TXNDeleteObject((TXNObject
)m_macTXN
);
745 /* delete our private storage */
747 /* zero the control reference */
752 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
755 const wxSize
& size
, long style
,
756 const wxValidator
& validator
,
757 const wxString
& name
)
759 m_macIsUserPane
= FALSE
;
762 m_macTXNvars
= NULL
;
765 // base initialization
766 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
769 wxSize mySize
= size
;
771 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
773 if ( m_windowStyle
& wxTE_MULTILINE
)
775 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
776 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
778 m_windowStyle
|= wxTE_PROCESS_ENTER
;
782 wxMacConvertNewlines13To10( &st
) ;
785 #if wxMAC_USE_MLTE_HIVIEW
786 HIRect hr
= { bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
} ;
787 HITextViewCreate( &hr
, 0, FrameOptionsFromWXStyle( m_windowStyle
) , (ControlRef
*) &m_macControl
) ;
788 m_macTXN
= HITextViewGetTXNObject((ControlRef
) m_macControl
) ;
789 AdjustAttributesFromWXStyle( (TXNObject
) m_macTXN
, m_windowStyle
, true ) ;
790 HIViewSetVisible( (ControlRef
) m_macControl
, true ) ;
794 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
795 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
796 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
797 /* create the control */
798 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, "\p", true , featurSet
, 0, featurSet
, kControlUserPaneProc
, (long) this );
799 /* set up the mUP specific features and data */
800 wxMacWindowClipper
c(this) ;
801 STPTextPaneVars
*varsp
;
802 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
803 m_macTXNvars
= varsp
;
804 m_macTXN
= varsp
->fTXNRec
;
807 if ( style
& wxTE_PASSWORD
)
810 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
813 MacPostControlCreate(pos
,size
) ;
815 #if !wxMAC_USE_MLTE_HIVIEW
816 if ( MacIsReallyShown() )
817 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
821 wxMacWindowClipper
clipper( this ) ;
822 #if !wxMAC_USE_MLTE_HIVIEW
823 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
825 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
827 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
828 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
831 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
832 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
834 SetBackgroundColour( *wxWHITE
) ;
837 tback
.bgType
= kTXNBackgroundTypeRGB
;
838 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
839 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
841 if ( m_windowStyle
& wxTE_READONLY
)
843 SetEditable( false ) ;
846 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding()) ;
847 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cf
, style
& wxTE_PASSWORD
, NULL
, (ControlRef
*) &m_macControl
) ;
848 MacPostControlCreate(pos
,size
) ;
855 void wxTextCtrl::MacVisibilityChanged()
857 #if wxMAC_USE_MLTE && !wxMAC_USE_MLTE_HIVIEW
858 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
859 if ( !MacIsReallyShown() )
860 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
864 void wxTextCtrl::MacEnabledStateChanged()
869 wxString
wxTextCtrl::GetValue() const
878 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
886 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
887 if ( actualSize
> 0 )
890 #if SIZEOF_WCHAR_T == 2
891 ptr
= new wxChar
[actualSize
+ 1 ] ;
892 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
895 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
897 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
898 wxMBConvUTF16BE converter
;
899 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
900 ptr
= new wxChar
[noChars
+ 1] ;
902 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
906 ptr
[actualSize
] = 0 ;
907 result
= wxString( ptr
) ;
910 DisposeHandle( theText
) ;
914 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
922 actualSize
= GetHandleSize( theText
) ;
923 if ( actualSize
> 0 )
926 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
929 DisposeHandle( theText
) ;
934 CFStringRef value
= NULL
;
935 Size actualSize
= 0 ;
937 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
938 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
939 sizeof(CFStringRef
), &value
, &actualSize
) );
942 wxMacCFStringHolder
cf(value
) ;
943 result
= cf
.AsString() ;
946 wxMacConvertNewlines10To13( &result
) ;
950 void wxTextCtrl::GetSelection(long* from
, long* to
) const
953 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
955 ControlEditTextSelectionRec sel
;
957 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
958 sizeof(ControlEditTextSelectionRec
), &sel
, &actualSize
) );
959 if ( from
) *from
= sel
.selStart
;
960 if ( to
) *to
= sel
.selEnd
;
964 void wxTextCtrl::SetValue(const wxString
& str
)
967 if ( GetValue() == str
)
971 wxMacConvertNewlines13To10( &st
) ;
974 wxMacWindowClipper
c( this ) ;
975 bool formerEditable
= m_editable
;
976 if ( !formerEditable
)
979 #if !wxMAC_USE_MLTE_HIVIEW
980 // otherwise scrolling might have problems ?
981 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
983 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
984 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
985 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
986 if ( !formerEditable
)
987 SetEditable(formerEditable
) ;
990 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
991 CFStringRef value
= cf
;
992 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
993 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
994 sizeof(CFStringRef
), &value
) );
998 void wxTextCtrl::SetMaxLength(unsigned long len
)
1003 bool wxTextCtrl::SetFont( const wxFont
& font
)
1005 if ( !wxTextCtrlBase::SetFont( font
) )
1009 wxMacWindowClipper
c( this ) ;
1010 bool formerEditable
= m_editable
;
1011 if ( !formerEditable
)
1014 TXNTypeAttributes typeAttr
[4] ;
1015 Str255 fontName
= "\pMonaco" ;
1016 SInt16 fontSize
= 12 ;
1017 Style fontStyle
= normal
;
1018 int attrCounter
= 0 ;
1020 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1021 fontSize
= font
.MacGetFontSize() ;
1022 fontStyle
= font
.MacGetFontStyle() ;
1024 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1025 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1026 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1027 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1028 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1029 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1030 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1031 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1032 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1035 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1036 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1037 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1038 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
1041 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
1043 if ( !formerEditable
)
1044 SetEditable(formerEditable
) ;
1049 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1052 bool formerEditable
= m_editable
;
1053 if ( !formerEditable
)
1055 TXNTypeAttributes typeAttr
[4] ;
1056 Str255 fontName
= "\pMonaco" ;
1057 SInt16 fontSize
= 12 ;
1058 Style fontStyle
= normal
;
1060 int attrCounter
= 0 ;
1061 if ( style
.HasFont() )
1063 const wxFont
&font
= style
.GetFont() ;
1064 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1065 fontSize
= font
.GetPointSize() ;
1066 if ( font
.GetUnderlined() )
1067 fontStyle
|= underline
;
1068 if ( font
.GetWeight() == wxBOLD
)
1070 if ( font
.GetStyle() == wxITALIC
)
1071 fontStyle
|= italic
;
1073 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1074 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1075 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1076 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1077 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1078 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1079 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1080 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1081 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1085 if ( style
.HasTextColour() )
1087 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1088 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1089 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1090 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1094 if ( attrCounter
> 0 )
1096 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1098 if ( !formerEditable
)
1099 SetEditable(formerEditable
) ;
1104 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1106 wxTextCtrlBase::SetDefaultStyle( style
) ;
1107 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1111 // Clipboard operations
1112 void wxTextCtrl::Copy()
1117 ClearCurrentScrap();
1118 TXNCopy((TXNObject
)m_macTXN
);
1119 TXNConvertToPublicScrap();
1124 void wxTextCtrl::Cut()
1129 ClearCurrentScrap();
1130 TXNCut((TXNObject
)m_macTXN
);
1131 TXNConvertToPublicScrap();
1133 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1134 event
.SetString( GetValue() ) ;
1135 event
.SetEventObject( this );
1136 GetEventHandler()->ProcessEvent(event
);
1140 void wxTextCtrl::Paste()
1145 TXNConvertFromPublicScrap();
1146 TXNPaste((TXNObject
)m_macTXN
);
1147 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1149 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1150 event
.SetString( GetValue() ) ;
1151 event
.SetEventObject( this );
1152 GetEventHandler()->ProcessEvent(event
);
1156 bool wxTextCtrl::CanCopy() const
1158 // Can copy if there's a selection
1160 GetSelection(& from
, & to
);
1161 return (from
!= to
);
1164 bool wxTextCtrl::CanCut() const
1166 if ( !IsEditable() )
1170 // Can cut if there's a selection
1172 GetSelection(& from
, & to
);
1173 return (from
!= to
);
1176 bool wxTextCtrl::CanPaste() const
1182 return TXNIsScrapPastable() ;
1188 void wxTextCtrl::SetEditable(bool editable
)
1190 if ( editable
!= m_editable
)
1192 m_editable
= editable
;
1194 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1195 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1196 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1201 void wxTextCtrl::SetInsertionPoint(long pos
)
1203 SetSelection( pos
, pos
) ;
1206 void wxTextCtrl::SetInsertionPointEnd()
1208 long pos
= GetLastPosition();
1209 SetInsertionPoint(pos
);
1212 long wxTextCtrl::GetInsertionPoint() const
1215 GetSelection( &begin
, &end
) ;
1219 long wxTextCtrl::GetLastPosition() const
1222 long actualsize
= 0 ;
1224 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1232 actualsize
= GetHandleSize( theText
) ;
1233 DisposeHandle( theText
) ;
1239 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1242 wxString value
= str
;
1243 wxMacConvertNewlines13To10( &value
) ;
1245 bool formerEditable
= m_editable
;
1246 if ( !formerEditable
)
1248 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1249 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1250 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1251 if ( !formerEditable
)
1252 SetEditable( formerEditable
) ;
1258 void wxTextCtrl::Remove(long from
, long to
)
1261 bool formerEditable
= m_editable
;
1262 if ( !formerEditable
)
1264 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1265 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1266 if ( !formerEditable
)
1267 SetEditable( formerEditable
) ;
1273 void wxTextCtrl::SetSelection(long from
, long to
)
1276 /* change the selection */
1277 if ((from
== -1) && (to
== -1))
1278 TXNSelectAll((TXNObject
) m_macTXN
);
1280 TXNSetSelection( (TXNObject
) m_macTXN
, from
, to
);
1281 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1283 ControlEditTextSelectionRec sel
;
1284 sel
.selStart
= from
;
1286 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
1287 sizeof(ControlEditTextSelectionRec
), &sel
) );
1292 bool wxTextCtrl::LoadFile(const wxString
& file
)
1294 if ( wxTextCtrlBase::LoadFile(file
) )
1302 void wxTextCtrl::WriteText(const wxString
& str
)
1305 wxMacConvertNewlines13To10( &st
) ;
1307 bool formerEditable
= m_editable
;
1308 if ( !formerEditable
)
1311 wxMacWindowStateSaver( this ) ;
1312 long start
, end
, dummy
;
1313 GetSelection( &start
, &dummy
) ;
1314 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1315 GetSelection( &dummy
, &end
) ;
1316 SetStyle( start
, end
, GetDefaultStyle() ) ;
1318 if ( !formerEditable
)
1319 SetEditable( formerEditable
) ;
1321 MacRedrawControl() ;
1323 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1324 CFStringRef value
= cf
;
1325 SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextInsertCFStringRefTag
,
1326 sizeof(CFStringRef
), &value
);
1330 void wxTextCtrl::AppendText(const wxString
& text
)
1332 SetInsertionPointEnd();
1336 void wxTextCtrl::Clear()
1339 bool formerEditable
= m_editable
;
1340 if ( !formerEditable
)
1342 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1343 TXNClear((TXNObject
)m_macTXN
);
1345 if ( !formerEditable
)
1346 SetEditable( formerEditable
) ;
1350 SetValue(wxEmptyString
) ;
1354 bool wxTextCtrl::IsModified() const
1359 bool wxTextCtrl::IsEditable() const
1361 return IsEnabled() && m_editable
;
1364 bool wxTextCtrl::AcceptsFocus() const
1366 // we don't want focus if we can't be edited
1367 return /*IsEditable() && */ wxControl::AcceptsFocus();
1370 wxSize
wxTextCtrl::DoGetBestSize() const
1376 switch( m_windowVariant
)
1378 case wxWINDOW_VARIANT_NORMAL
:
1381 case wxWINDOW_VARIANT_SMALL
:
1384 case wxWINDOW_VARIANT_MINI
:
1392 if ( m_windowStyle
& wxTE_MULTILINE
)
1397 return wxSize(wText
, hText
);
1400 // ----------------------------------------------------------------------------
1402 // ----------------------------------------------------------------------------
1404 void wxTextCtrl::Undo()
1409 TXNUndo((TXNObject
)m_macTXN
);
1414 void wxTextCtrl::Redo()
1419 TXNRedo((TXNObject
)m_macTXN
);
1424 bool wxTextCtrl::CanUndo() const
1426 if ( !IsEditable() )
1431 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1437 bool wxTextCtrl::CanRedo() const
1439 if ( !IsEditable() )
1444 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1450 // Makes modifie or unmodified
1451 void wxTextCtrl::MarkDirty()
1456 void wxTextCtrl::DiscardEdits()
1461 int wxTextCtrl::GetNumberOfLines() const
1463 ItemCount lines
= 0 ;
1465 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1470 long wxTextCtrl::XYToPosition(long x
, long y
) const
1475 long lastpos
= GetLastPosition() ;
1477 // TODO find a better implementation : while we can get the
1478 // line metrics of a certain line, we don't get its starting
1479 // position, so it would probably be rather a binary search
1480 // for the start position
1483 int lastHeight
= 0 ;
1486 for ( n
= 0 ; n
<= lastpos
; ++n
)
1488 if ( y
== ypos
&& x
== xpos
)
1491 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1493 if ( curpt
.v
> lastHeight
)
1498 lastHeight
= curpt
.v
;
1507 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1512 long lastpos
= GetLastPosition() ;
1517 if ( pos
<= lastpos
)
1519 // TODO find a better implementation : while we can get the
1520 // line metrics of a certain line, we don't get its starting
1521 // position, so it would probably be rather a binary search
1522 // for the start position
1525 int lastHeight
= 0 ;
1528 for ( n
= 0 ; n
<= pos
; ++n
)
1530 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1532 if ( curpt
.v
> lastHeight
)
1537 lastHeight
= curpt
.v
;
1542 if ( y
) *y
= ypos
;
1543 if ( x
) *x
= xpos
;
1552 void wxTextCtrl::ShowPosition(long pos
)
1555 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1559 TXNOffset selstart
, selend
;
1560 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1561 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1562 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1563 //TODO use HIPoints for 10.3 and above
1564 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1566 OSErr theErr
= noErr
;
1567 SInt32 dv
= desired
.v
- current
.v
;
1568 SInt32 dh
= desired
.h
- current
.h
;
1569 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1570 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1571 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1578 int wxTextCtrl::GetLineLength(long lineNo
) const
1582 if ( lineNo
< GetNumberOfLines() )
1584 // TODO find a better implementation : while we can get the
1585 // line metrics of a certain line, we don't get its starting
1586 // position, so it would probably be rather a binary search
1587 // for the start position
1590 int lastHeight
= 0 ;
1591 long lastpos
= GetLastPosition() ;
1594 for ( n
= 0 ; n
<= lastpos
; ++n
)
1596 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1598 if ( curpt
.v
> lastHeight
)
1600 if ( ypos
== lineNo
)
1606 lastHeight
= curpt
.v
;
1616 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1621 wxString content
= GetValue() ;
1623 if ( lineNo
< GetNumberOfLines() )
1625 // TODO find a better implementation : while we can get the
1626 // line metrics of a certain line, we don't get its starting
1627 // position, so it would probably be rather a binary search
1628 // for the start position
1631 int lastHeight
= 0 ;
1632 long lastpos
= GetLastPosition() ;
1635 for ( n
= 0 ; n
<= lastpos
; ++n
)
1637 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1639 if ( curpt
.v
> lastHeight
)
1641 if ( ypos
== lineNo
)
1647 lastHeight
= curpt
.v
;
1651 if ( ypos
== lineNo
)
1652 line
+= content
[n
] ;
1665 void wxTextCtrl::Command(wxCommandEvent
& event
)
1667 SetValue (event
.GetString());
1668 ProcessCommand (event
);
1671 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1673 // By default, load the first file into the text window.
1674 if (event
.GetNumberOfFiles() > 0)
1676 LoadFile(event
.GetFiles()[0]);
1680 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1682 int key
= event
.GetKeyCode() ;
1683 bool eat_key
= false ;
1685 if ( key
== 'c' && event
.MetaDown() )
1692 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1693 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1694 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1701 // assume that any key not processed yet is going to modify the control
1704 if ( key
== 'v' && event
.MetaDown() )
1710 if ( key
== 'x' && event
.MetaDown() )
1719 if (m_windowStyle
& wxPROCESS_ENTER
)
1721 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1722 event
.SetEventObject( this );
1723 event
.SetString( GetValue() );
1724 if ( GetEventHandler()->ProcessEvent(event
) )
1727 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1729 wxWindow
*parent
= GetParent();
1730 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1731 parent
= parent
->GetParent() ;
1733 if ( parent
&& parent
->GetDefaultItem() )
1735 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1737 if ( def
&& def
->IsEnabled() )
1739 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1740 event
.SetEventObject(def
);
1741 def
->Command(event
);
1746 // this will make wxWindows eat the ENTER key so that
1747 // we actually prevent line wrapping in a single line
1755 // always produce navigation event - even if we process TAB
1756 // ourselves the fact that we got here means that the user code
1757 // decided to skip processing of this TAB - probably to let it
1758 // do its default job.
1760 wxNavigationKeyEvent eventNav
;
1761 eventNav
.SetDirection(!event
.ShiftDown());
1762 eventNav
.SetWindowChange(event
.ControlDown());
1763 eventNav
.SetEventObject(this);
1765 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1776 // perform keystroke handling
1777 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1778 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1782 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1784 EventRecord
*ev
= &rec
;
1787 keychar
= short(ev
->message
& charCodeMask
);
1788 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1790 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1794 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1795 key
== WXK_RETURN
||
1796 key
== WXK_DELETE
||
1799 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1800 event1
.SetString( GetValue() ) ;
1801 event1
.SetEventObject( this );
1802 wxPostEvent(GetEventHandler(),event1
);
1806 // ----------------------------------------------------------------------------
1807 // standard handlers for standard edit menu events
1808 // ----------------------------------------------------------------------------
1810 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1815 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1820 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1825 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1830 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1835 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1837 event
.Enable( CanCut() );
1840 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1842 event
.Enable( CanCopy() );
1845 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1847 event
.Enable( CanPaste() );
1850 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1852 event
.Enable( CanUndo() );
1855 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1857 event
.Enable( CanRedo() );
1860 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1865 // user pane implementation
1867 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1871 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1873 return kControlNoPart
;
1876 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1878 return kControlNoPart
;
1881 void wxTextCtrl::MacControlUserPaneIdleProc()
1885 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1887 return kControlNoPart
;
1890 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1894 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1896 return kControlNoPart
;
1899 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)