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
);
862 if ( m_windowStyle
& wxTE_READONLY
)
864 SetEditable( false ) ;
867 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding()) ;
868 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cf
, style
& wxTE_PASSWORD
, NULL
, (ControlRef
*) &m_macControl
) ;
869 MacPostControlCreate(pos
,size
) ;
876 void wxTextCtrl::MacVisibilityChanged()
878 #if wxMAC_USE_MLTE && !wxMAC_USE_MLTE_HIVIEW
879 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
880 if ( !MacIsReallyShown() )
881 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
885 void wxTextCtrl::MacEnabledStateChanged()
890 wxString
wxTextCtrl::GetValue() const
899 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
907 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
908 if ( actualSize
> 0 )
911 #if SIZEOF_WCHAR_T == 2
912 ptr
= new wxChar
[actualSize
+ 1 ] ;
913 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
916 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
918 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
919 wxMBConvUTF16BE converter
;
920 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
921 ptr
= new wxChar
[noChars
+ 1] ;
923 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
927 ptr
[actualSize
] = 0 ;
928 result
= wxString( ptr
) ;
931 DisposeHandle( theText
) ;
935 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
943 actualSize
= GetHandleSize( theText
) ;
944 if ( actualSize
> 0 )
947 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
950 DisposeHandle( theText
) ;
955 CFStringRef value
= NULL
;
956 Size actualSize
= 0 ;
958 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
959 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
960 sizeof(CFStringRef
), &value
, &actualSize
) );
963 wxMacCFStringHolder
cf(value
) ;
964 result
= cf
.AsString() ;
967 wxMacConvertNewlines10To13( &result
) ;
971 void wxTextCtrl::GetSelection(long* from
, long* to
) const
974 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
976 ControlEditTextSelectionRec sel
;
978 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
979 sizeof(ControlEditTextSelectionRec
), &sel
, &actualSize
) );
980 if ( from
) *from
= sel
.selStart
;
981 if ( to
) *to
= sel
.selEnd
;
985 void wxTextCtrl::SetValue(const wxString
& str
)
988 if ( GetValue() == str
)
992 wxMacConvertNewlines13To10( &st
) ;
995 wxMacWindowClipper
c( this ) ;
996 bool formerEditable
= m_editable
;
997 if ( !formerEditable
)
1000 #if !wxMAC_USE_MLTE_HIVIEW
1001 // otherwise scrolling might have problems ?
1002 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
1004 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
1005 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
1006 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1007 if ( !formerEditable
)
1008 SetEditable(formerEditable
) ;
1011 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1012 CFStringRef value
= cf
;
1013 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
1014 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
1015 sizeof(CFStringRef
), &value
) );
1019 void wxTextCtrl::SetMaxLength(unsigned long len
)
1024 bool wxTextCtrl::SetFont( const wxFont
& font
)
1026 if ( !wxTextCtrlBase::SetFont( font
) )
1030 wxMacWindowClipper
c( this ) ;
1031 bool formerEditable
= m_editable
;
1032 if ( !formerEditable
)
1035 TXNTypeAttributes typeAttr
[4] ;
1036 Str255 fontName
= "\pMonaco" ;
1037 SInt16 fontSize
= 12 ;
1038 Style fontStyle
= normal
;
1039 int attrCounter
= 0 ;
1041 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1042 fontSize
= font
.MacGetFontSize() ;
1043 fontStyle
= font
.MacGetFontStyle() ;
1045 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1046 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1047 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1048 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1049 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1050 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1051 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1052 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1053 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1056 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1057 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1058 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1059 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
1062 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
1064 if ( !formerEditable
)
1065 SetEditable(formerEditable
) ;
1070 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1073 bool formerEditable
= m_editable
;
1074 if ( !formerEditable
)
1076 TXNTypeAttributes typeAttr
[4] ;
1077 Str255 fontName
= "\pMonaco" ;
1078 SInt16 fontSize
= 12 ;
1079 Style fontStyle
= normal
;
1081 int attrCounter
= 0 ;
1082 if ( style
.HasFont() )
1084 const wxFont
&font
= style
.GetFont() ;
1085 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1086 fontSize
= font
.GetPointSize() ;
1087 if ( font
.GetUnderlined() )
1088 fontStyle
|= underline
;
1089 if ( font
.GetWeight() == wxBOLD
)
1091 if ( font
.GetStyle() == wxITALIC
)
1092 fontStyle
|= italic
;
1094 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1095 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1096 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1097 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1098 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1099 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1100 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1101 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1102 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1106 if ( style
.HasTextColour() )
1108 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1109 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1110 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1111 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1115 if ( attrCounter
> 0 )
1117 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1119 if ( !formerEditable
)
1120 SetEditable(formerEditable
) ;
1125 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1127 wxTextCtrlBase::SetDefaultStyle( style
) ;
1128 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1132 // Clipboard operations
1133 void wxTextCtrl::Copy()
1138 ClearCurrentScrap();
1139 TXNCopy((TXNObject
)m_macTXN
);
1140 TXNConvertToPublicScrap();
1145 void wxTextCtrl::Cut()
1150 ClearCurrentScrap();
1151 TXNCut((TXNObject
)m_macTXN
);
1152 TXNConvertToPublicScrap();
1154 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1155 event
.SetString( GetValue() ) ;
1156 event
.SetEventObject( this );
1157 GetEventHandler()->ProcessEvent(event
);
1161 void wxTextCtrl::Paste()
1166 TXNConvertFromPublicScrap();
1167 TXNPaste((TXNObject
)m_macTXN
);
1168 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1170 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1171 event
.SetString( GetValue() ) ;
1172 event
.SetEventObject( this );
1173 GetEventHandler()->ProcessEvent(event
);
1177 bool wxTextCtrl::CanCopy() const
1179 // Can copy if there's a selection
1181 GetSelection(& from
, & to
);
1182 return (from
!= to
);
1185 bool wxTextCtrl::CanCut() const
1187 if ( !IsEditable() )
1191 // Can cut if there's a selection
1193 GetSelection(& from
, & to
);
1194 return (from
!= to
);
1197 bool wxTextCtrl::CanPaste() const
1203 return TXNIsScrapPastable() ;
1209 void wxTextCtrl::SetEditable(bool editable
)
1211 if ( editable
!= m_editable
)
1213 m_editable
= editable
;
1215 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1216 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1217 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1222 void wxTextCtrl::SetInsertionPoint(long pos
)
1224 SetSelection( pos
, pos
) ;
1227 void wxTextCtrl::SetInsertionPointEnd()
1229 long pos
= GetLastPosition();
1230 SetInsertionPoint(pos
);
1233 long wxTextCtrl::GetInsertionPoint() const
1236 GetSelection( &begin
, &end
) ;
1240 long wxTextCtrl::GetLastPosition() const
1242 long actualsize
= 0 ;
1245 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1253 actualsize
= GetHandleSize( theText
) ;
1254 DisposeHandle( theText
) ;
1260 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1263 wxString value
= str
;
1264 wxMacConvertNewlines13To10( &value
) ;
1266 bool formerEditable
= m_editable
;
1267 if ( !formerEditable
)
1269 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1270 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1271 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1272 if ( !formerEditable
)
1273 SetEditable( formerEditable
) ;
1279 void wxTextCtrl::Remove(long from
, long to
)
1282 bool formerEditable
= m_editable
;
1283 if ( !formerEditable
)
1285 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1286 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1287 if ( !formerEditable
)
1288 SetEditable( formerEditable
) ;
1294 void wxTextCtrl::SetSelection(long from
, long to
)
1297 /* change the selection */
1298 if ((from
== -1) && (to
== -1))
1299 TXNSelectAll((TXNObject
) m_macTXN
);
1301 TXNSetSelection( (TXNObject
) m_macTXN
, from
, to
);
1302 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1304 ControlEditTextSelectionRec sel
;
1305 sel
.selStart
= from
;
1307 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
1308 sizeof(ControlEditTextSelectionRec
), &sel
) );
1313 bool wxTextCtrl::LoadFile(const wxString
& file
)
1315 if ( wxTextCtrlBase::LoadFile(file
) )
1327 virtual ~wxMacFunctor() {}
1328 virtual void* operator()() = 0 ;
1329 static void* CallBackProc(void *param
)
1331 wxMacFunctor
* f
= (wxMacFunctor
*) param
;
1332 void *result
= (*f
)() ;
1337 template<typename classtype
,typename param1type
>
1338 class wxMacObjectFunctor1
: public wxMacFunctor
1340 typedef void (classtype::*function
)( param1type p1
) ;
1341 typedef void (classtype::*ref_function
)( const param1type
& p1
) ;
1343 wxMacObjectFunctor1( classtype
*obj
, function f
, param1type p1
) :
1351 wxMacObjectFunctor1( classtype
*obj
, ref_function f
, param1type p1
) :
1359 ~wxMacObjectFunctor1() {}
1361 virtual void* operator()()
1363 (m_object
->*m_function
)(m_param1
) ;
1367 classtype
* m_object
;
1368 param1type m_param1
;
1371 function m_function
;
1372 ref_function m_refFunction
;
1376 template<typename classtype
, typename param1type
>
1377 void* wxMacMPRemoteCall( classtype
*object
, void (classtype::*function
)( param1type p1
) , param1type p1
)
1379 wxMacObjectFunctor1
<classtype
,param1type
> params(object
,function
,p1
) ;
1381 MPRemoteCall( wxMacFunctor::CallBackProc
, ¶ms
, kMPOwningProcessRemoteContext
) ;
1385 template<typename classtype
, typename param1type
>
1386 void* wxMacMPRemoteCall( classtype
*object
, void (classtype::*function
)( const param1type
& p1
) , param1type p1
)
1388 wxMacObjectFunctor1
<classtype
,param1type
> params(object
,function
,p1
) ;
1390 MPRemoteCall( wxMacFunctor::CallBackProc
, ¶ms
, kMPOwningProcessRemoteContext
) ;
1394 template<typename classtype
, typename param1type
>
1395 void* wxMacMPRemoteGUICall( classtype
*object
, void (classtype::*function
)( param1type p1
) , param1type p1
)
1398 void *result
= wxMacMPRemoteCall( object
, function
, p1
) ;
1403 template<typename classtype
, typename param1type
>
1404 void* wxMacMPRemoteGUICall( classtype
*object
, void (classtype::*function
)( const param1type
& p1
) , param1type p1
)
1407 void *result
= wxMacMPRemoteCall( object
, function
, p1
) ;
1412 void wxTextCtrl::WriteText(const wxString
& str
)
1414 if ( !wxIsMainThread() )
1416 wxMacMPRemoteGUICall( this , &wxTextCtrl::WriteText
, str
) ;
1422 wxMacConvertNewlines13To10( &st
) ;
1424 bool formerEditable
= m_editable
;
1425 if ( !formerEditable
)
1428 wxMacWindowStateSaver
s( this ) ;
1429 long start
, end
, dummy
;
1430 GetSelection( &start
, &dummy
) ;
1431 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1432 GetSelection( &dummy
, &end
) ;
1433 SetStyle( start
, end
, GetDefaultStyle() ) ;
1435 if ( !formerEditable
)
1436 SetEditable( formerEditable
) ;
1438 MacRedrawControl() ;
1440 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1441 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1442 CFStringRef value
= cf
;
1443 SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextInsertCFStringRefTag
,
1444 sizeof(CFStringRef
), &value
);
1446 wxString val
= GetValue() ;
1448 GetSelection( &start
, &end
) ;
1449 val
.Remove( start
, end
- start
) ;
1450 val
.insert( start
, str
) ;
1457 void wxTextCtrl::AppendText(const wxString
& text
)
1459 SetInsertionPointEnd();
1463 void wxTextCtrl::Clear()
1466 bool formerEditable
= m_editable
;
1467 if ( !formerEditable
)
1469 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1470 TXNClear((TXNObject
)m_macTXN
);
1472 if ( !formerEditable
)
1473 SetEditable( formerEditable
) ;
1477 SetValue(wxEmptyString
) ;
1481 bool wxTextCtrl::IsModified() const
1486 bool wxTextCtrl::IsEditable() const
1488 return IsEnabled() && m_editable
;
1491 bool wxTextCtrl::AcceptsFocus() const
1493 // we don't want focus if we can't be edited
1494 return /*IsEditable() && */ wxControl::AcceptsFocus();
1497 wxSize
wxTextCtrl::DoGetBestSize() const
1503 switch( m_windowVariant
)
1505 case wxWINDOW_VARIANT_NORMAL
:
1508 case wxWINDOW_VARIANT_SMALL
:
1511 case wxWINDOW_VARIANT_MINI
:
1519 if ( m_windowStyle
& wxTE_MULTILINE
)
1524 return wxSize(wText
, hText
);
1527 // ----------------------------------------------------------------------------
1529 // ----------------------------------------------------------------------------
1531 void wxTextCtrl::Undo()
1536 TXNUndo((TXNObject
)m_macTXN
);
1541 void wxTextCtrl::Redo()
1546 TXNRedo((TXNObject
)m_macTXN
);
1551 bool wxTextCtrl::CanUndo() const
1553 if ( !IsEditable() )
1558 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1564 bool wxTextCtrl::CanRedo() const
1566 if ( !IsEditable() )
1571 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1577 // Makes modifie or unmodified
1578 void wxTextCtrl::MarkDirty()
1583 void wxTextCtrl::DiscardEdits()
1588 int wxTextCtrl::GetNumberOfLines() const
1590 ItemCount lines
= 0 ;
1592 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1597 long wxTextCtrl::XYToPosition(long x
, long y
) const
1602 long lastpos
= GetLastPosition() ;
1604 // TODO find a better implementation : while we can get the
1605 // line metrics of a certain line, we don't get its starting
1606 // position, so it would probably be rather a binary search
1607 // for the start position
1610 int lastHeight
= 0 ;
1613 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1615 if ( y
== ypos
&& x
== xpos
)
1618 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1620 if ( curpt
.v
> lastHeight
)
1625 lastHeight
= curpt
.v
;
1634 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1639 long lastpos
= GetLastPosition() ;
1644 if ( pos
<= lastpos
)
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
) pos
; ++n
)
1657 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1659 if ( curpt
.v
> lastHeight
)
1664 lastHeight
= curpt
.v
;
1669 if ( y
) *y
= ypos
;
1670 if ( x
) *x
= xpos
;
1679 void wxTextCtrl::ShowPosition(long pos
)
1682 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1686 TXNOffset selstart
, selend
;
1687 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1688 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1689 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1690 //TODO use HIPoints for 10.3 and above
1691 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1693 OSErr theErr
= noErr
;
1694 SInt32 dv
= desired
.v
- current
.v
;
1695 SInt32 dh
= desired
.h
- current
.h
;
1696 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1697 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1698 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1705 int wxTextCtrl::GetLineLength(long lineNo
) const
1709 if ( lineNo
< GetNumberOfLines() )
1711 // TODO find a better implementation : while we can get the
1712 // line metrics of a certain line, we don't get its starting
1713 // position, so it would probably be rather a binary search
1714 // for the start position
1717 int lastHeight
= 0 ;
1718 long lastpos
= GetLastPosition() ;
1721 for ( n
= 0 ; n
<= (ItemCount
) lastpos
; ++n
)
1723 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1725 if ( curpt
.v
> lastHeight
)
1727 if ( ypos
== lineNo
)
1733 lastHeight
= curpt
.v
;
1743 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1748 wxString content
= GetValue() ;
1750 if ( lineNo
< GetNumberOfLines() )
1752 // TODO find a better implementation : while we can get the
1753 // line metrics of a certain line, we don't get its starting
1754 // position, so it would probably be rather a binary search
1755 // for the start position
1758 int lastHeight
= 0 ;
1759 long lastpos
= GetLastPosition() ;
1762 for ( n
= 0 ; n
<= (ItemCount
)lastpos
; ++n
)
1764 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1766 if ( curpt
.v
> lastHeight
)
1768 if ( ypos
== lineNo
)
1774 lastHeight
= curpt
.v
;
1778 if ( ypos
== lineNo
)
1779 line
+= content
[n
] ;
1792 void wxTextCtrl::Command(wxCommandEvent
& event
)
1794 SetValue (event
.GetString());
1795 ProcessCommand (event
);
1798 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1800 // By default, load the first file into the text window.
1801 if (event
.GetNumberOfFiles() > 0)
1803 LoadFile(event
.GetFiles()[0]);
1807 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1809 int key
= event
.GetKeyCode() ;
1810 bool eat_key
= false ;
1812 if ( key
== 'c' && event
.MetaDown() )
1819 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1820 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1821 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1828 // assume that any key not processed yet is going to modify the control
1831 if ( key
== 'v' && event
.MetaDown() )
1837 if ( key
== 'x' && event
.MetaDown() )
1846 if (m_windowStyle
& wxPROCESS_ENTER
)
1848 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1849 event
.SetEventObject( this );
1850 event
.SetString( GetValue() );
1851 if ( GetEventHandler()->ProcessEvent(event
) )
1854 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1856 wxWindow
*parent
= GetParent();
1857 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1858 parent
= parent
->GetParent() ;
1860 if ( parent
&& parent
->GetDefaultItem() )
1862 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1864 if ( def
&& def
->IsEnabled() )
1866 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1867 event
.SetEventObject(def
);
1868 def
->Command(event
);
1873 // this will make wxWindows eat the ENTER key so that
1874 // we actually prevent line wrapping in a single line
1882 // always produce navigation event - even if we process TAB
1883 // ourselves the fact that we got here means that the user code
1884 // decided to skip processing of this TAB - probably to let it
1885 // do its default job.
1887 wxNavigationKeyEvent eventNav
;
1888 eventNav
.SetDirection(!event
.ShiftDown());
1889 eventNav
.SetWindowChange(event
.ControlDown());
1890 eventNav
.SetEventObject(this);
1892 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1903 // perform keystroke handling
1904 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1905 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1909 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1911 EventRecord
*ev
= &rec
;
1914 keychar
= short(ev
->message
& charCodeMask
);
1915 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1917 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1921 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1922 key
== WXK_RETURN
||
1923 key
== WXK_DELETE
||
1926 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1927 event1
.SetString( GetValue() ) ;
1928 event1
.SetEventObject( this );
1929 wxPostEvent(GetEventHandler(),event1
);
1933 // ----------------------------------------------------------------------------
1934 // standard handlers for standard edit menu events
1935 // ----------------------------------------------------------------------------
1937 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1942 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1947 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1952 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1957 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1962 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1964 event
.Enable( CanCut() );
1967 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1969 event
.Enable( CanCopy() );
1972 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1974 event
.Enable( CanPaste() );
1977 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1979 event
.Enable( CanUndo() );
1982 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1984 event
.Enable( CanRedo() );
1987 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1992 // user pane implementation
1994 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1998 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
2000 return kControlNoPart
;
2003 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
2005 return kControlNoPart
;
2008 void wxTextCtrl::MacControlUserPaneIdleProc()
2012 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
2014 return kControlNoPart
;
2017 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
2021 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
2023 return kControlNoPart
;
2026 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)