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 0
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 HIViewRef scrollView
= NULL
;
788 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( style
) ;
790 if ( frameOptions
& (kTXNWantVScrollBarMask
|kTXNWantHScrollBarMask
) )
792 HIScrollViewCreate(( frameOptions
& kTXNWantHScrollBarMask
? kHIScrollViewOptionsHorizScroll
: 0) |
793 ( frameOptions
& kTXNWantVScrollBarMask
? kHIScrollViewOptionsVertScroll
: 0 ) , &scrollView
) ;
795 HIViewSetFrame( scrollView
, &hr
);
796 HIViewSetVisible( scrollView
, true );
799 HITextViewCreate( NULL
, 0, frameOptions
, (ControlRef
*) &textView
) ;
800 m_macTXN
= HITextViewGetTXNObject( textView
) ;
801 AdjustAttributesFromWXStyle( (TXNObject
) m_macTXN
, style
, true ) ;
802 HIViewSetVisible( (ControlRef
) textView
, true ) ;
805 HIViewAddSubview( scrollView
, textView
) ;
806 m_macControl
= (WXWidget
) scrollView
;
810 m_macControl
= (WXWidget
) textView
;
815 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
816 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
817 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
818 /* create the control */
819 verify_noerr( CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, featurSet
, (ControlRef
*) &m_macControl
) ) ;
821 wxMacWindowClipper
c(this) ;
822 STPTextPaneVars
*varsp
;
823 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
824 m_macTXNvars
= varsp
;
825 m_macTXN
= varsp
->fTXNRec
;
828 if ( style
& wxTE_PASSWORD
)
831 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
834 MacPostControlCreate(pos
,size
) ;
836 #if !wxMAC_USE_MLTE_HIVIEW
837 if ( MacIsReallyShown() )
838 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
842 wxMacWindowClipper
clipper( this ) ;
843 #if !wxMAC_USE_MLTE_HIVIEW
844 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
846 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
848 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
849 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
852 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
853 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
855 SetBackgroundColour( *wxWHITE
) ;
858 tback
.bgType
= kTXNBackgroundTypeRGB
;
859 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
860 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
863 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding()) ;
864 CFStringRef cfr
= cf
;
865 Boolean isPassword
= ( m_windowStyle
& wxTE_PASSWORD
) != 0 ;
866 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cfr
, isPassword
, NULL
, (ControlRef
*) &m_macControl
) ;
867 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
869 Boolean singleline
= true ;
870 ::SetControlData( (ControlHandle
) m_macControl
, kControlEditTextPart
, kControlEditTextSingleLineTag
, sizeof( singleline
) , &singleline
) ;
872 MacPostControlCreate(pos
,size
) ;
875 if ( m_windowStyle
& wxTE_READONLY
)
877 SetEditable( false ) ;
884 void wxTextCtrl::MacVisibilityChanged()
887 #if !wxMAC_USE_MLTE_HIVIEW
888 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
889 if ( !MacIsReallyShown() )
890 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
893 if ( !(m_windowStyle
& wxTE_MULTILINE
) && MacIsReallyShown() )
895 // work around a refresh issue insofar as not always the entire content is shown even if this would be possible
896 ControlEditTextSelectionRec sel
;
897 CFStringRef value
= NULL
;
898 Size actualSize
= 0 ;
899 ResType datatag
= GetWindowStyle() & wxTE_PASSWORD
?
900 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
;
902 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
903 sizeof(ControlEditTextSelectionRec
), &sel
, &actualSize
) );
904 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, datatag
, sizeof(CFStringRef
), &value
, &actualSize
) );
906 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, datatag
, sizeof(CFStringRef
), &value
) );
907 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
, sizeof(ControlEditTextSelectionRec
), &sel
) );
914 void wxTextCtrl::MacEnabledStateChanged()
919 wxString
wxTextCtrl::GetValue() const
928 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
936 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
937 if ( actualSize
> 0 )
940 #if SIZEOF_WCHAR_T == 2
941 ptr
= new wxChar
[actualSize
+ 1 ] ;
942 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
945 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
947 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
948 wxMBConvUTF16BE converter
;
949 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
950 ptr
= new wxChar
[noChars
+ 1] ;
952 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
956 ptr
[actualSize
] = 0 ;
957 result
= wxString( ptr
) ;
960 DisposeHandle( theText
) ;
964 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
972 actualSize
= GetHandleSize( theText
) ;
973 if ( actualSize
> 0 )
976 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
979 DisposeHandle( theText
) ;
984 CFStringRef value
= NULL
;
985 Size actualSize
= 0 ;
987 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
988 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
989 sizeof(CFStringRef
), &value
, &actualSize
) );
992 wxMacCFStringHolder
cf(value
) ;
993 result
= cf
.AsString() ;
996 wxMacConvertNewlines10To13( &result
) ;
1000 void wxTextCtrl::GetSelection(long* from
, long* to
) const
1003 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1005 ControlEditTextSelectionRec sel
;
1007 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
1008 sizeof(ControlEditTextSelectionRec
), &sel
, &actualSize
) );
1009 if ( from
) *from
= sel
.selStart
;
1010 if ( to
) *to
= sel
.selEnd
;
1014 void wxTextCtrl::SetValue(const wxString
& str
)
1017 if ( GetValue() == str
)
1021 wxMacConvertNewlines13To10( &st
) ;
1024 wxMacWindowClipper
c( this ) ;
1025 bool formerEditable
= m_editable
;
1026 if ( !formerEditable
)
1029 #if !wxMAC_USE_MLTE_HIVIEW
1030 // otherwise scrolling might have problems ?
1031 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
1033 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
1034 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
1035 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1036 if ( !formerEditable
)
1037 SetEditable(formerEditable
) ;
1040 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1041 CFStringRef value
= cf
;
1042 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
1043 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
1044 sizeof(CFStringRef
), &value
) );
1048 void wxTextCtrl::SetMaxLength(unsigned long len
)
1053 bool wxTextCtrl::SetFont( const wxFont
& font
)
1055 if ( !wxTextCtrlBase::SetFont( font
) )
1059 wxMacWindowClipper
c( this ) ;
1060 bool formerEditable
= m_editable
;
1061 if ( !formerEditable
)
1064 TXNTypeAttributes typeAttr
[4] ;
1065 Str255 fontName
= "\pMonaco" ;
1066 SInt16 fontSize
= 12 ;
1067 Style fontStyle
= normal
;
1068 int attrCounter
= 0 ;
1070 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1071 fontSize
= font
.MacGetFontSize() ;
1072 fontStyle
= font
.MacGetFontStyle() ;
1074 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1075 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1076 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1077 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1078 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1079 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1080 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1081 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1082 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1085 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1086 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1087 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1088 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
1091 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
1093 if ( !formerEditable
)
1094 SetEditable(formerEditable
) ;
1099 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1102 bool formerEditable
= m_editable
;
1103 if ( !formerEditable
)
1105 TXNTypeAttributes typeAttr
[4] ;
1106 Str255 fontName
= "\pMonaco" ;
1107 SInt16 fontSize
= 12 ;
1108 Style fontStyle
= normal
;
1110 int attrCounter
= 0 ;
1111 if ( style
.HasFont() )
1113 const wxFont
&font
= style
.GetFont() ;
1114 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1115 fontSize
= font
.GetPointSize() ;
1116 if ( font
.GetUnderlined() )
1117 fontStyle
|= underline
;
1118 if ( font
.GetWeight() == wxBOLD
)
1120 if ( font
.GetStyle() == wxITALIC
)
1121 fontStyle
|= italic
;
1123 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1124 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1125 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1126 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1127 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1128 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1129 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1130 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1131 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1135 if ( style
.HasTextColour() )
1137 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1138 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1139 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1140 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1144 if ( attrCounter
> 0 )
1146 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1148 if ( !formerEditable
)
1149 SetEditable(formerEditable
) ;
1154 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1156 wxTextCtrlBase::SetDefaultStyle( style
) ;
1157 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1161 // Clipboard operations
1162 void wxTextCtrl::Copy()
1167 ClearCurrentScrap();
1168 TXNCopy((TXNObject
)m_macTXN
);
1169 TXNConvertToPublicScrap();
1174 void wxTextCtrl::Cut()
1179 ClearCurrentScrap();
1180 TXNCut((TXNObject
)m_macTXN
);
1181 TXNConvertToPublicScrap();
1183 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1184 event
.SetString( GetValue() ) ;
1185 event
.SetEventObject( this );
1186 GetEventHandler()->ProcessEvent(event
);
1190 void wxTextCtrl::Paste()
1195 TXNConvertFromPublicScrap();
1196 TXNPaste((TXNObject
)m_macTXN
);
1197 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1199 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1200 event
.SetString( GetValue() ) ;
1201 event
.SetEventObject( this );
1202 GetEventHandler()->ProcessEvent(event
);
1206 bool wxTextCtrl::CanCopy() const
1208 // Can copy if there's a selection
1210 GetSelection(& from
, & to
);
1211 return (from
!= to
);
1214 bool wxTextCtrl::CanCut() const
1216 if ( !IsEditable() )
1220 // Can cut if there's a selection
1222 GetSelection(& from
, & to
);
1223 return (from
!= to
);
1226 bool wxTextCtrl::CanPaste() const
1232 return TXNIsScrapPastable() ;
1238 void wxTextCtrl::SetEditable(bool editable
)
1240 if ( editable
!= m_editable
)
1242 m_editable
= editable
;
1244 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1245 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1246 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1248 Boolean value
= !editable
;
1249 ::SetControlData( (ControlHandle
) m_macControl
, 0, kControlEditTextLockedTag
, sizeof( value
) , &value
) ;
1254 void wxTextCtrl::SetInsertionPoint(long pos
)
1256 SetSelection( pos
, pos
) ;
1259 void wxTextCtrl::SetInsertionPointEnd()
1261 long pos
= GetLastPosition();
1262 SetInsertionPoint(pos
);
1265 long wxTextCtrl::GetInsertionPoint() const
1268 GetSelection( &begin
, &end
) ;
1272 long wxTextCtrl::GetLastPosition() const
1274 long actualsize
= 0 ;
1277 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1285 actualsize
= GetHandleSize( theText
) ;
1286 DisposeHandle( theText
) ;
1292 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1295 wxString value
= str
;
1296 wxMacConvertNewlines13To10( &value
) ;
1298 bool formerEditable
= m_editable
;
1299 if ( !formerEditable
)
1301 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1302 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1303 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1304 if ( !formerEditable
)
1305 SetEditable( formerEditable
) ;
1311 void wxTextCtrl::Remove(long from
, long to
)
1314 bool formerEditable
= m_editable
;
1315 if ( !formerEditable
)
1317 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1318 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1319 if ( !formerEditable
)
1320 SetEditable( formerEditable
) ;
1326 void wxTextCtrl::SetSelection(long from
, long to
)
1329 /* change the selection */
1330 if ((from
== -1) && (to
== -1))
1331 TXNSelectAll((TXNObject
) m_macTXN
);
1333 TXNSetSelection( (TXNObject
) m_macTXN
, from
, to
);
1334 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1336 ControlEditTextSelectionRec sel
;
1337 sel
.selStart
= from
;
1339 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
1340 sizeof(ControlEditTextSelectionRec
), &sel
) );
1345 bool wxTextCtrl::LoadFile(const wxString
& file
)
1347 if ( wxTextCtrlBase::LoadFile(file
) )
1359 virtual ~wxMacFunctor() {}
1360 virtual void* operator()() = 0 ;
1361 static void* CallBackProc(void *param
)
1363 wxMacFunctor
* f
= (wxMacFunctor
*) param
;
1364 void *result
= (*f
)() ;
1369 template<typename classtype
,typename param1type
>
1370 class wxMacObjectFunctor1
: public wxMacFunctor
1372 typedef void (classtype::*function
)( param1type p1
) ;
1373 typedef void (classtype::*ref_function
)( const param1type
& p1
) ;
1375 wxMacObjectFunctor1( classtype
*obj
, function f
, param1type p1
) :
1383 wxMacObjectFunctor1( classtype
*obj
, ref_function f
, param1type p1
) :
1391 ~wxMacObjectFunctor1() {}
1393 virtual void* operator()()
1395 (m_object
->*m_function
)(m_param1
) ;
1399 classtype
* m_object
;
1400 param1type m_param1
;
1403 function m_function
;
1404 ref_function m_refFunction
;
1408 template<typename classtype
, typename param1type
>
1409 void* wxMacMPRemoteCall( classtype
*object
, void (classtype::*function
)( param1type p1
) , param1type p1
)
1411 wxMacObjectFunctor1
<classtype
,param1type
> params(object
,function
,p1
) ;
1413 MPRemoteCall( wxMacFunctor::CallBackProc
, ¶ms
, kMPOwningProcessRemoteContext
) ;
1417 template<typename classtype
, typename param1type
>
1418 void* wxMacMPRemoteCall( classtype
*object
, void (classtype::*function
)( const param1type
& p1
) , param1type p1
)
1420 wxMacObjectFunctor1
<classtype
,param1type
> params(object
,function
,p1
) ;
1422 MPRemoteCall( wxMacFunctor::CallBackProc
, ¶ms
, kMPOwningProcessRemoteContext
) ;
1426 template<typename classtype
, typename param1type
>
1427 void* wxMacMPRemoteGUICall( classtype
*object
, void (classtype::*function
)( param1type p1
) , param1type p1
)
1430 void *result
= wxMacMPRemoteCall( object
, function
, p1
) ;
1435 template<typename classtype
, typename param1type
>
1436 void* wxMacMPRemoteGUICall( classtype
*object
, void (classtype::*function
)( const param1type
& p1
) , param1type p1
)
1439 void *result
= wxMacMPRemoteCall( object
, function
, p1
) ;
1444 void wxTextCtrl::WriteText(const wxString
& str
)
1446 if ( !wxIsMainThread() )
1448 // unfortunately CW 8 is not able to correctly deduce the template types, so we have
1449 // to instantiate explicitely
1450 wxMacMPRemoteGUICall
<wxTextCtrl
,wxString
>( this , &wxTextCtrl::WriteText
, str
) ;
1456 wxMacConvertNewlines13To10( &st
) ;
1458 bool formerEditable
= m_editable
;
1459 if ( !formerEditable
)
1462 wxMacWindowStateSaver
s( this ) ;
1463 long start
, end
, dummy
;
1464 GetSelection( &start
, &dummy
) ;
1465 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1466 GetSelection( &dummy
, &end
) ;
1467 SetStyle( start
, end
, GetDefaultStyle() ) ;
1469 if ( !formerEditable
)
1470 SetEditable( formerEditable
) ;
1472 MacRedrawControl() ;
1474 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1475 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1476 CFStringRef value
= cf
;
1477 SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextInsertCFStringRefTag
,
1478 sizeof(CFStringRef
), &value
);
1480 wxString val
= GetValue() ;
1482 GetSelection( &start
, &end
) ;
1483 val
.Remove( start
, end
- start
) ;
1484 val
.insert( start
, str
) ;
1486 SetInsertionPoint( start
+ str
.Length() ) ;
1492 void wxTextCtrl::AppendText(const wxString
& text
)
1494 SetInsertionPointEnd();
1498 void wxTextCtrl::Clear()
1501 bool formerEditable
= m_editable
;
1502 if ( !formerEditable
)
1504 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1505 TXNClear((TXNObject
)m_macTXN
);
1507 if ( !formerEditable
)
1508 SetEditable( formerEditable
) ;
1512 SetValue(wxEmptyString
) ;
1516 bool wxTextCtrl::IsModified() const
1521 bool wxTextCtrl::IsEditable() const
1523 return IsEnabled() && m_editable
;
1526 bool wxTextCtrl::AcceptsFocus() const
1528 // we don't want focus if we can't be edited
1529 return /*IsEditable() && */ wxControl::AcceptsFocus();
1532 wxSize
wxTextCtrl::DoGetBestSize() const
1538 switch( m_windowVariant
)
1540 case wxWINDOW_VARIANT_NORMAL
:
1543 case wxWINDOW_VARIANT_SMALL
:
1546 case wxWINDOW_VARIANT_MINI
:
1555 // unicode text control is using client size, ie 3 pixels on every side
1556 // TODO make this fit into normal window size concept, probably having
1557 // to reintroduce the margin vars
1561 if ( m_windowStyle
& wxTE_MULTILINE
)
1566 return wxSize(wText
, hText
);
1569 // ----------------------------------------------------------------------------
1571 // ----------------------------------------------------------------------------
1573 void wxTextCtrl::Undo()
1578 TXNUndo((TXNObject
)m_macTXN
);
1583 void wxTextCtrl::Redo()
1588 TXNRedo((TXNObject
)m_macTXN
);
1593 bool wxTextCtrl::CanUndo() const
1595 if ( !IsEditable() )
1600 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1606 bool wxTextCtrl::CanRedo() const
1608 if ( !IsEditable() )
1613 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1619 // Makes modifie or unmodified
1620 void wxTextCtrl::MarkDirty()
1625 void wxTextCtrl::DiscardEdits()
1630 int wxTextCtrl::GetNumberOfLines() const
1632 ItemCount lines
= 0 ;
1634 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1639 long wxTextCtrl::XYToPosition(long x
, long y
) const
1644 long lastpos
= GetLastPosition() ;
1646 // TODO find a better implementation : while we can get the
1647 // line metrics of a certain line, we don't get its starting
1648 // position, so it would probably be rather a binary search
1649 // for the start position
1652 int lastHeight
= 0 ;
1655 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1657 if ( y
== ypos
&& x
== xpos
)
1660 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1662 if ( curpt
.v
> lastHeight
)
1667 lastHeight
= curpt
.v
;
1676 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1681 long lastpos
= GetLastPosition() ;
1686 if ( pos
<= lastpos
)
1688 // TODO find a better implementation : while we can get the
1689 // line metrics of a certain line, we don't get its starting
1690 // position, so it would probably be rather a binary search
1691 // for the start position
1694 int lastHeight
= 0 ;
1697 for ( n
= 0 ; n
<= (ItemCount
) pos
; ++n
)
1699 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1701 if ( curpt
.v
> lastHeight
)
1706 lastHeight
= curpt
.v
;
1711 if ( y
) *y
= ypos
;
1712 if ( x
) *x
= xpos
;
1721 void wxTextCtrl::ShowPosition(long pos
)
1724 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1728 TXNOffset selstart
, selend
;
1729 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1730 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1731 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1732 //TODO use HIPoints for 10.3 and above
1733 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1735 OSErr theErr
= noErr
;
1736 SInt32 dv
= desired
.v
- current
.v
;
1737 SInt32 dh
= desired
.h
- current
.h
;
1738 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1739 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1740 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1747 int wxTextCtrl::GetLineLength(long lineNo
) const
1751 if ( lineNo
< GetNumberOfLines() )
1753 // TODO find a better implementation : while we can get the
1754 // line metrics of a certain line, we don't get its starting
1755 // position, so it would probably be rather a binary search
1756 // for the start position
1759 int lastHeight
= 0 ;
1760 long lastpos
= GetLastPosition() ;
1763 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1765 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1767 if ( curpt
.v
> lastHeight
)
1769 if ( ypos
== lineNo
)
1775 lastHeight
= curpt
.v
;
1785 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1790 wxString content
= GetValue() ;
1792 if ( lineNo
< GetNumberOfLines() )
1794 // TODO find a better implementation : while we can get the
1795 // line metrics of a certain line, we don't get its starting
1796 // position, so it would probably be rather a binary search
1797 // for the start position
1800 int lastHeight
= 0 ;
1801 long lastpos
= GetLastPosition() ;
1804 for ( n
= 0 ; n
<= (ItemCount
)lastpos
; ++n
)
1806 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1808 if ( curpt
.v
> lastHeight
)
1810 if ( ypos
== lineNo
)
1816 lastHeight
= curpt
.v
;
1820 if ( ypos
== lineNo
)
1821 line
+= content
[n
] ;
1834 void wxTextCtrl::Command(wxCommandEvent
& event
)
1836 SetValue (event
.GetString());
1837 ProcessCommand (event
);
1840 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1842 // By default, load the first file into the text window.
1843 if (event
.GetNumberOfFiles() > 0)
1845 LoadFile(event
.GetFiles()[0]);
1849 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1851 int key
= event
.GetKeyCode() ;
1852 bool eat_key
= false ;
1854 if ( key
== 'c' && event
.MetaDown() )
1861 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1862 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1863 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1870 // assume that any key not processed yet is going to modify the control
1873 if ( key
== 'v' && event
.MetaDown() )
1879 if ( key
== 'x' && event
.MetaDown() )
1888 if (m_windowStyle
& wxPROCESS_ENTER
)
1890 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1891 event
.SetEventObject( this );
1892 event
.SetString( GetValue() );
1893 if ( GetEventHandler()->ProcessEvent(event
) )
1896 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1898 wxWindow
*parent
= GetParent();
1899 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1900 parent
= parent
->GetParent() ;
1902 if ( parent
&& parent
->GetDefaultItem() )
1904 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1906 if ( def
&& def
->IsEnabled() )
1908 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1909 event
.SetEventObject(def
);
1910 def
->Command(event
);
1915 // this will make wxWidgets eat the ENTER key so that
1916 // we actually prevent line wrapping in a single line
1924 // always produce navigation event - even if we process TAB
1925 // ourselves the fact that we got here means that the user code
1926 // decided to skip processing of this TAB - probably to let it
1927 // do its default job.
1929 wxNavigationKeyEvent eventNav
;
1930 eventNav
.SetDirection(!event
.ShiftDown());
1931 eventNav
.SetWindowChange(event
.ControlDown());
1932 eventNav
.SetEventObject(this);
1934 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1945 // perform keystroke handling
1946 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1947 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1951 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1953 EventRecord
*ev
= &rec
;
1956 keychar
= short(ev
->message
& charCodeMask
);
1957 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1959 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1963 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1964 key
== WXK_RETURN
||
1965 key
== WXK_DELETE
||
1968 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1969 event1
.SetString( GetValue() ) ;
1970 event1
.SetEventObject( this );
1971 wxPostEvent(GetEventHandler(),event1
);
1975 // ----------------------------------------------------------------------------
1976 // standard handlers for standard edit menu events
1977 // ----------------------------------------------------------------------------
1979 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1984 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1989 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1994 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1999 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2004 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2006 event
.Enable( CanCut() );
2009 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2011 event
.Enable( CanCopy() );
2014 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2016 event
.Enable( CanPaste() );
2019 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2021 event
.Enable( CanUndo() );
2024 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2026 event
.Enable( CanRedo() );
2029 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
2034 // user pane implementation
2036 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
2040 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
2042 return kControlNoPart
;
2045 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
2047 return kControlNoPart
;
2050 void wxTextCtrl::MacControlUserPaneIdleProc()
2054 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
2056 return kControlNoPart
;
2059 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
2063 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
2065 return kControlNoPart
;
2068 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)