1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
21 #include <sys/types.h>
27 #include "wx/msgdlg.h"
29 #if wxUSE_STD_IOSTREAM
39 #include "wx/button.h"
40 #include "wx/toplevel.h"
41 #include "wx/textctrl.h"
42 #include "wx/notebook.h"
43 #include "wx/tabctrl.h"
44 #include "wx/settings.h"
45 #include "wx/filefn.h"
48 #if defined(__BORLANDC__) && !defined(__WIN32__)
50 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
57 #include <MacTextEditor.h>
58 #include <ATSUnicode.h>
59 #include <TextCommon.h>
60 #include <TextEncodingConverter.h>
61 #include "wx/mac/uma.h"
63 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
64 #if TARGET_API_MAC_OSX
65 #define wxMAC_USE_MLTE 1
66 #define wxMAC_USE_MLTE_HIVIEW 1
68 // there is no unicodetextctrl on classic, and hopefully MLTE works better there
69 #define wxMAC_USE_MLTE 1
70 #define wxMAC_USE_MLTE_HIVIEW 0
75 TXNFrameOptions
FrameOptionsFromWXStyle( long wxStyle
)
77 TXNFrameOptions frameOptions
=
78 kTXNDontDrawCaretWhenInactiveMask
;
79 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
80 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
82 if ( wxStyle
& wxTE_MULTILINE
)
84 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
85 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
88 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
89 frameOptions
|= kTXNWantHScrollBarMask
;
92 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
93 frameOptions
|= kTXNWantVScrollBarMask
;
96 frameOptions
|= kTXNSingleLineOnlyMask
;
100 void AdjustAttributesFromWXStyle( TXNObject txn
, long wxStyle
, bool visible
)
102 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
103 TXNControlData iControlData
[3] = { {false}, {kTXNNoAutoWrap
} };
105 #if TARGET_API_MAC_OSX
106 iControlTags
[2] = kTXNVisibilityTag
;
107 iControlData
[2].uValue
= visible
;
111 if ( wxStyle
& wxTE_MULTILINE
)
113 if (wxStyle
& wxTE_DONTWRAP
)
114 iControlData
[1].uValue
= kTXNNoAutoWrap
;
116 iControlData
[1].uValue
= kTXNAutoWrap
;
119 verify_noerr( TXNSetTXNObjectControls( txn
, false, toptag
,
120 iControlTags
, iControlData
)) ;
126 GetThemeFont(kThemeSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
128 TXNTypeAttributes typeAttr
[] =
130 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
131 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
132 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
135 verify_noerr( TXNSetTypeAttributes (txn
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
141 #if !wxMAC_USE_MLTE_HIVIEW
143 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
144 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
145 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
146 // an alternate path for carbon key events that routes automatically into the same wx flow of events
150 /* kmUPTextPart is the part code we return to indicate the user has clicked
151 in the text area of our control */
152 #define kmUPTextPart 1
155 /* routines for using existing user pane controls.
156 These routines are useful for cases where you would like to use an
157 existing user pane control in, say, a dialog window as a scrolling
160 /* Utility Routines */
162 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
163 routine. In our focus switching routine this part code is understood
164 as meaning 'the user has clicked in the control and we need to switch
165 the current focus to ourselves before we can continue'. */
166 #define kUserClickedToFocusPart 100
168 /* STPTextPaneVars is a structure used for storing the the mUP Control's
169 internal variables and state information. A handle to this record is
170 stored in the pane control's reference value field using the
171 SetControlReference routine. */
174 /* OS records referenced */
175 TXNObject fTXNRec
; /* the txn record */
176 TXNFrameID fTXNFrame
; /* the txn frame ID */
177 ControlRef fUserPaneRec
; /* handle to the user pane control */
178 WindowPtr fOwner
; /* window containing control */
179 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
181 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
182 Boolean fIsActive
; /* true while the control is drawn in the active state */
183 Boolean fTXNObjectActive
; /* reflects the activation state of the text edit record */
184 Boolean fFocusDrawState
; /* true if focus is drawn (default: true) */
185 /* calculated locations */
186 Rect fRBounds
; /* control bounds */
187 Rect fRTextArea
; /* area where the text is drawn */
188 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
189 Rect fRTextOutline
; /* rectangle used to draw the border */
190 RgnHandle fRTextOutlineRegion
; /* background region for the text, erased before calling TEUpdate */
191 /* our focus advance override routine */
192 EventHandlerUPP handlerUPP
;
193 EventHandlerRef handlerRef
;
199 /* mUPOpenControl initializes a user pane control so it will be drawn
200 and will behave as a scrolling text edit field inside of a window.
201 This routine performs all of the initialization steps necessary,
202 except it does not create the user pane control itself. theControl
203 should refer to a user pane control that you have either created
204 yourself or extracted from a dialog's control heirarchy using
205 the GetDialogItemAsControl routine. */
206 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
);
211 /* Univerals Procedure Pointer variables used by the
212 mUP Control. These variables are set up
213 the first time that mUPOpenControl is called. */
214 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
215 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
216 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
217 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
218 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
219 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
220 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
222 // one place for calculating all
223 static void TPCalculateBounds(STPTextPaneVars
*varsp
, const Rect
& bounds
)
225 SetRect(&varsp
->fRBounds
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
226 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
227 // eventually make TextOutline inset 1,1
228 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
229 if ( !varsp
->fNoBorders
)
231 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
232 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
236 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
237 bounds
.right
, bounds
.bottom
);
241 OSStatus
MLTESetObjectVisibility( STPTextPaneVars
*varsp
, Boolean vis
, long wxStyle
)
243 OSStatus err
= noErr
;
244 #if TARGET_API_MAC_OSX
245 TXNControlTag iControlTags
[1] = { kTXNVisibilityTag
};
246 TXNControlData iControlData
[1] = {{ vis
}};
247 err
= ::TXNSetTXNObjectControls( varsp
->fTXNRec
, false, 1, iControlTags
, iControlData
);
249 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
250 if ( vis
&& textctrl
)
253 UMAGetControlBoundsInWindowCoords( varsp
->fUserPaneRec
, &bounds
);
254 TPCalculateBounds( varsp
, bounds
) ;
255 wxMacWindowClipper
cl(textctrl
) ;
256 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
257 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
258 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
263 // make sure we don't miss changes as carbon events are not available for these under classic
264 static void TPUpdateVisibility(ControlRef theControl
) {
265 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
266 if ( textctrl
== NULL
)
269 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
272 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
273 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
275 // invalidate old position
276 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
277 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
279 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
282 Rect oldBounds
= varsp
->fRBounds
;
283 TPCalculateBounds( varsp
, bounds
) ;
284 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
285 if ( varsp
->fVisible
)
287 wxMacWindowClipper
cl(textctrl
) ;
288 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
289 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
291 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
292 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
296 // make correct activations
297 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
299 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
300 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
302 varsp
->fTXNObjectActive
= setActive
;
303 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
305 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
309 // update focus outlines
310 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
313 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
315 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
316 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
320 // update TXN focus state
321 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
322 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
324 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
325 varsp
->fInFocus
= setFocus
;
326 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
331 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
332 /* set up our globals */
334 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
335 if ( textctrl
== NULL
)
337 TPUpdateVisibility( theControl
) ;
339 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
340 if ( textctrl
->MacIsReallyShown() )
342 wxMacWindowClipper
clipper( textctrl
) ;
343 TXNDraw(varsp
->fTXNRec
, NULL
);
344 if ( !varsp
->fNoBorders
)
345 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
346 TPRedrawFocusOutline( varsp
) ;
352 /* TPPaneHitTestProc is called when the control manager would
353 like to determine what part of the control the mouse resides over.
354 We also call this routine from our tracking proc to determine how
355 to handle mouse clicks. */
356 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
357 ControlPartCode result
;
358 /* set up our locals and lock down our globals*/
360 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
361 if ( textctrl
== NULL
)
363 TPUpdateVisibility( theControl
) ;
364 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
365 if (textctrl
->MacIsReallyShown() )
367 if (PtInRect(where
, &varsp
->fRBounds
))
368 result
= kmUPTextPart
;
379 /* TPPaneTrackingProc is called when the mouse is being held down
380 over our control. This routine handles clicks in the text area
381 and in the scroll bar. */
382 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
384 ControlPartCode partCodeResult
;
385 /* make sure we have some variables... */
387 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
388 if ( textctrl
== NULL
)
390 TPUpdateVisibility( theControl
) ;
391 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
392 if (textctrl
->MacIsReallyShown() )
394 /* we don't do any of these functions unless we're in focus */
395 if ( ! varsp
->fInFocus
) {
397 owner
= GetControlOwner(theControl
);
398 ClearKeyboardFocus(owner
);
399 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
401 /* find the location for the click */
402 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
403 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
406 textctrl
->MacClientToRootWindow( &x
, &y
) ;
411 switch (TPPaneHitTestProc(theControl
, startPt
))
414 /* handle clicks in the text part */
417 wxMacWindowClipper
clipper( textctrl
) ;
420 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
421 TXNClick( varsp
->fTXNRec
, &rec
);
428 return partCodeResult
;
432 /* TPPaneIdleProc is our user pane idle routine. When our text field
433 is active and in focus, we use this routine to set the cursor. */
434 static pascal void TPPaneIdleProc(ControlRef theControl
) {
436 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
437 if ( textctrl
== NULL
)
439 TPUpdateVisibility( theControl
) ;
440 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
441 if (textctrl
->MacIsReallyShown()) {
442 /* if we're not active, then we have nothing to say about the cursor */
443 if (varsp
->fIsActive
) {
447 wxMacWindowClipper
clipper( textctrl
) ;
449 /* there's a 'focus thing' and an 'unfocused thing' */
450 if (varsp
->fInFocus
) {
451 /* flash the cursor */
452 SetPort(varsp
->fDrawingEnvironment
);
453 TXNIdle(varsp
->fTXNRec
);
455 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
457 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
458 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
463 // SetThemeCursor(kThemeArrowCursor);
466 /* if it's in our bounds, set the cursor */
467 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
468 if (PtInRect(mousep
, &bounds
))
470 // SetThemeCursor(kThemeArrowCursor);
478 /* TPPaneKeyDownProc is called whenever a keydown event is directed
479 at our control. Here, we direct the keydown event to the text
480 edit record and redraw the scroll bar and text field as appropriate. */
481 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
482 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
484 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
485 if ( textctrl
== NULL
)
487 TPUpdateVisibility( theControl
) ;
489 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
492 /* turn autoscrolling on and send the key event to text edit */
493 wxMacWindowClipper
clipper( textctrl
) ;
495 memset( &ev
, 0 , sizeof( ev
) ) ;
497 ev
.modifiers
= modifiers
;
498 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
499 TXNKeyDown( varsp
->fTXNRec
, &ev
);
501 return kControlEntireControl
;
505 /* TPPaneActivateProc is called when the window containing
506 the user pane control receives activate events. Here, we redraw
507 the control and it's text as necessary for the activation state. */
508 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
510 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
512 if ( textctrl
== NULL
)
514 TPUpdateVisibility( theControl
) ;
516 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
518 varsp
->fIsActive
= activating
;
519 wxMacWindowClipper
clipper( textctrl
) ;
520 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
521 /* redraw the frame */
522 if ( textctrl
->MacIsReallyShown() )
524 if ( !varsp
->fNoBorders
)
525 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
526 TPRedrawFocusOutline( varsp
) ;
531 /* TPPaneFocusProc is called when every the focus changes to or
532 from our control. Herein, switch the focus appropriately
533 according to the parameters and redraw the control as
535 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
536 ControlPartCode focusResult
;
538 focusResult
= kControlFocusNoPart
;
539 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
540 if ( textctrl
== NULL
)
542 TPUpdateVisibility( theControl
) ;
543 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
544 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
545 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
546 and kControlFocusNextPart will be received. When the user clicks in our field
547 and it is not the current focus, then the constant kUserClickedToFocusPart will
548 be received. The constant kControlFocusNoPart will be received when our control
549 is the current focus and the user clicks in another control. In your focus routine,
550 you should respond to these codes as follows:
552 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
553 the control and the focus rectangle as necessary.
555 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
556 depending on its current state. redraw the control and the focus rectangle
557 as appropriate for the new focus state. If the focus state is 'off', return the constant
558 kControlFocusNoPart, otherwise return a non-zero part code.
559 kUserClickedToFocusPart - is a constant defined for this example. You should
560 define your own value for handling click-to-focus type events. */
561 /* calculate the next highlight state */
564 case kControlFocusNoPart
:
565 TPFocusPaneText(varsp
, false);
566 focusResult
= kControlFocusNoPart
;
568 case kUserClickedToFocusPart
:
569 TPFocusPaneText(varsp
, true);
572 case kControlFocusPrevPart
:
573 case kControlFocusNextPart
:
574 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
575 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
578 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
579 /* redraw the text fram and focus rectangle to indicate the
581 if ( textctrl
->MacIsReallyShown() )
583 wxMacWindowClipper
c( textctrl
) ;
584 if ( !varsp
->fNoBorders
)
585 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
586 TPRedrawFocusOutline( varsp
) ;
592 /* mUPOpenControl initializes a user pane control so it will be drawn
593 and will behave as a scrolling text edit field inside of a window.
594 This routine performs all of the initialization steps necessary,
595 except it does not create the user pane control itself. theControl
596 should refer to a user pane control that you have either created
597 yourself or extracted from a dialog's control heirarchy using
598 the GetDialogItemAsControl routine. */
599 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
)
603 STPTextPaneVars
*varsp
;
604 OSStatus err
= noErr
;
606 /* set up our globals */
607 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
608 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
609 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
610 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
611 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
612 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
613 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
615 /* allocate our private storage */
616 varsp
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
619 /* set the initial settings for our private data */
620 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
621 varsp
->fNoBorders
= wxStyle
& wxNO_BORDER
;
622 varsp
->fInFocus
= false;
623 varsp
->fIsActive
= true;
624 varsp
->fTXNObjectActive
= false;
625 varsp
->fFocusDrawState
= false ;
626 varsp
->fUserPaneRec
= theControl
;
627 varsp
->fVisible
= true ;
629 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
631 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
633 /* set up the user pane procedures */
634 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
635 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
636 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
637 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
638 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
639 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
640 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
642 /* calculate the rectangles used by the control */
643 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
644 varsp
->fRTextOutlineRegion
= NewRgn() ;
645 TPCalculateBounds( varsp
, bounds
) ;
647 /* set up the drawing environment */
648 SetPort(varsp
->fDrawingEnvironment
);
650 /* create the new edit field */
652 TXNFrameOptions frameOptions
= FrameOptionsFromWXStyle( wxStyle
) ;
654 verify_noerr(TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
656 kTXNTextEditStyleFrameType
,
658 kTXNSystemDefaultEncoding
,
659 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) varsp
));
661 AdjustAttributesFromWXStyle( varsp
->fTXNRec
, wxStyle
, varsp
->fVisible
) ;
662 /* perform final activations and setup for our text field. Here,
663 we assume that the window is going to be the 'active' window. */
664 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
670 struct STPTextPaneVars
676 static void SetTXNData( STPTextPaneVars
*varsp
, TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
679 #if SIZEOF_WCHAR_T == 2
680 size_t len
= st
.Len() ;
681 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
684 wxMBConvUTF16BE converter
;
685 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
686 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
687 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
688 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
693 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
694 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
702 #if !USE_SHARED_LIBRARY
703 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
705 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
706 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
707 EVT_CHAR(wxTextCtrl::OnChar
)
708 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
709 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
710 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
711 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
712 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
714 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
715 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
716 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
717 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
718 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
723 void wxTextCtrl::Init()
726 m_macTXNvars
= NULL
;
731 m_maxLength
= TE_UNLIMITED_LENGTH
;
734 wxTextCtrl::~wxTextCtrl()
737 SetControlReference((ControlRef
)m_macControl
, 0) ;
738 #if !wxMAC_USE_MLTE_HIVIEW
739 TXNDeleteObject((TXNObject
)m_macTXN
);
741 /* delete our private storage */
743 /* zero the control reference */
748 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
751 const wxSize
& size
, long style
,
752 const wxValidator
& validator
,
753 const wxString
& name
)
755 m_macIsUserPane
= FALSE
;
758 m_macTXNvars
= NULL
;
761 // base initialization
762 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
765 wxSize mySize
= size
;
767 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
769 if ( m_windowStyle
& wxTE_MULTILINE
)
771 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
772 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
774 m_windowStyle
|= wxTE_PROCESS_ENTER
;
778 wxMacConvertNewlines13To10( &st
) ;
781 #if wxMAC_USE_MLTE_HIVIEW
782 HIRect hr
= { bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
} ;
783 HITextViewCreate( &hr
, 0, FrameOptionsFromWXStyle( m_windowStyle
) , (ControlRef
*) &m_macControl
) ;
784 m_macTXN
= HITextViewGetTXNObject((ControlRef
) m_macControl
) ;
785 AdjustAttributesFromWXStyle( (TXNObject
) m_macTXN
, m_windowStyle
, true ) ;
786 HIViewSetVisible( (ControlRef
) m_macControl
, true ) ;
790 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
791 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
792 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
793 /* create the control */
794 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, "\p", true , featurSet
, 0, featurSet
, kControlUserPaneProc
, (long) this );
795 /* set up the mUP specific features and data */
796 wxMacWindowClipper
c(this) ;
797 STPTextPaneVars
*varsp
;
798 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
799 m_macTXNvars
= varsp
;
800 m_macTXN
= varsp
->fTXNRec
;
803 if ( style
& wxTE_PASSWORD
)
806 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
809 MacPostControlCreate(pos
,size
) ;
811 #if !wxMAC_USE_MLTE_HIVIEW
812 if ( MacIsReallyShown() )
813 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
817 wxMacWindowClipper
clipper( this ) ;
818 #if !wxMAC_USE_MLTE_HIVIEW
819 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
821 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
823 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
824 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
827 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
828 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
830 SetBackgroundColour( *wxWHITE
) ;
833 tback
.bgType
= kTXNBackgroundTypeRGB
;
834 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
835 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
837 if ( m_windowStyle
& wxTE_READONLY
)
839 SetEditable( false ) ;
842 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding()) ;
843 CreateEditUnicodeTextControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, cf
, style
& wxTE_PASSWORD
, NULL
, (ControlRef
*) &m_macControl
) ;
844 MacPostControlCreate(pos
,size
) ;
851 void wxTextCtrl::MacVisibilityChanged()
853 #if wxMAC_USE_MLTE && !wxMAC_USE_MLTE_HIVIEW
854 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
855 if ( !MacIsReallyShown() )
856 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
860 void wxTextCtrl::MacEnabledStateChanged()
865 wxString
wxTextCtrl::GetValue() const
874 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
882 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
883 if ( actualSize
> 0 )
886 #if SIZEOF_WCHAR_T == 2
887 ptr
= new wxChar
[actualSize
+ 1 ] ;
888 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
891 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
893 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
894 wxMBConvUTF16BE converter
;
895 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
896 ptr
= new wxChar
[noChars
+ 1] ;
898 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
902 ptr
[actualSize
] = 0 ;
903 result
= wxString( ptr
) ;
906 DisposeHandle( theText
) ;
910 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
918 actualSize
= GetHandleSize( theText
) ;
919 if ( actualSize
> 0 )
922 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
925 DisposeHandle( theText
) ;
930 CFStringRef value
= NULL
;
931 Size actualSize
= 0 ;
933 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
934 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
935 sizeof(CFStringRef
), &value
, &actualSize
) );
938 wxMacCFStringHolder
cf(value
) ;
939 result
= cf
.AsString() ;
942 wxMacConvertNewlines10To13( &result
) ;
946 void wxTextCtrl::GetSelection(long* from
, long* to
) const
949 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
951 ControlEditTextSelectionRec sel
;
953 verify_noerr( GetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
954 sizeof(ControlEditTextSelectionRec
), &sel
, &actualSize
) );
955 if ( from
) *from
= sel
.selStart
;
956 if ( to
) *to
= sel
.selEnd
;
960 void wxTextCtrl::SetValue(const wxString
& str
)
963 if ( GetValue() == str
)
967 wxMacConvertNewlines13To10( &st
) ;
970 wxMacWindowClipper
c( this ) ;
971 bool formerEditable
= m_editable
;
972 if ( !formerEditable
)
975 #if !wxMAC_USE_MLTE_HIVIEW
976 // otherwise scrolling might have problems ?
977 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
979 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
980 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
981 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
982 if ( !formerEditable
)
983 SetEditable(formerEditable
) ;
986 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
987 CFStringRef value
= cf
;
988 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, GetWindowStyle() & wxTE_PASSWORD
?
989 kControlEditTextPasswordCFStringTag
: kControlEditTextCFStringTag
,
990 sizeof(CFStringRef
), &value
) );
994 void wxTextCtrl::SetMaxLength(unsigned long len
)
999 bool wxTextCtrl::SetFont( const wxFont
& font
)
1001 if ( !wxTextCtrlBase::SetFont( font
) )
1005 wxMacWindowClipper
c( this ) ;
1006 bool formerEditable
= m_editable
;
1007 if ( !formerEditable
)
1010 TXNTypeAttributes typeAttr
[4] ;
1011 Str255 fontName
= "\pMonaco" ;
1012 SInt16 fontSize
= 12 ;
1013 Style fontStyle
= normal
;
1014 int attrCounter
= 0 ;
1016 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1017 fontSize
= font
.MacGetFontSize() ;
1018 fontStyle
= font
.MacGetFontStyle() ;
1020 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1021 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1022 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1023 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1024 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1025 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1026 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1027 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1028 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1031 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1032 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1033 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1034 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
1037 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
1039 if ( !formerEditable
)
1040 SetEditable(formerEditable
) ;
1045 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
1048 bool formerEditable
= m_editable
;
1049 if ( !formerEditable
)
1051 TXNTypeAttributes typeAttr
[4] ;
1052 Str255 fontName
= "\pMonaco" ;
1053 SInt16 fontSize
= 12 ;
1054 Style fontStyle
= normal
;
1056 int attrCounter
= 0 ;
1057 if ( style
.HasFont() )
1059 const wxFont
&font
= style
.GetFont() ;
1060 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
1061 fontSize
= font
.GetPointSize() ;
1062 if ( font
.GetUnderlined() )
1063 fontStyle
|= underline
;
1064 if ( font
.GetWeight() == wxBOLD
)
1066 if ( font
.GetStyle() == wxITALIC
)
1067 fontStyle
|= italic
;
1069 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
1070 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
1071 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
1072 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
1073 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
1074 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
1075 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
1076 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
1077 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
1081 if ( style
.HasTextColour() )
1083 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
1084 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
1085 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
1086 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
1090 if ( attrCounter
> 0 )
1092 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
1094 if ( !formerEditable
)
1095 SetEditable(formerEditable
) ;
1100 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1102 wxTextCtrlBase::SetDefaultStyle( style
) ;
1103 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1107 // Clipboard operations
1108 void wxTextCtrl::Copy()
1113 ClearCurrentScrap();
1114 TXNCopy((TXNObject
)m_macTXN
);
1115 TXNConvertToPublicScrap();
1120 void wxTextCtrl::Cut()
1125 ClearCurrentScrap();
1126 TXNCut((TXNObject
)m_macTXN
);
1127 TXNConvertToPublicScrap();
1129 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1130 event
.SetString( GetValue() ) ;
1131 event
.SetEventObject( this );
1132 GetEventHandler()->ProcessEvent(event
);
1136 void wxTextCtrl::Paste()
1141 TXNConvertFromPublicScrap();
1142 TXNPaste((TXNObject
)m_macTXN
);
1143 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1145 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1146 event
.SetString( GetValue() ) ;
1147 event
.SetEventObject( this );
1148 GetEventHandler()->ProcessEvent(event
);
1152 bool wxTextCtrl::CanCopy() const
1154 // Can copy if there's a selection
1156 GetSelection(& from
, & to
);
1157 return (from
!= to
);
1160 bool wxTextCtrl::CanCut() const
1162 if ( !IsEditable() )
1166 // Can cut if there's a selection
1168 GetSelection(& from
, & to
);
1169 return (from
!= to
);
1172 bool wxTextCtrl::CanPaste() const
1178 return TXNIsScrapPastable() ;
1184 void wxTextCtrl::SetEditable(bool editable
)
1186 if ( editable
!= m_editable
)
1188 m_editable
= editable
;
1190 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1191 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1192 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1197 void wxTextCtrl::SetInsertionPoint(long pos
)
1199 SetSelection( pos
, pos
) ;
1202 void wxTextCtrl::SetInsertionPointEnd()
1204 long pos
= GetLastPosition();
1205 SetInsertionPoint(pos
);
1208 long wxTextCtrl::GetInsertionPoint() const
1211 GetSelection( &begin
, &end
) ;
1215 long wxTextCtrl::GetLastPosition() const
1218 long actualsize
= 0 ;
1220 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1228 actualsize
= GetHandleSize( theText
) ;
1229 DisposeHandle( theText
) ;
1235 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1238 wxString value
= str
;
1239 wxMacConvertNewlines13To10( &value
) ;
1241 bool formerEditable
= m_editable
;
1242 if ( !formerEditable
)
1244 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1245 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1246 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1247 if ( !formerEditable
)
1248 SetEditable( formerEditable
) ;
1254 void wxTextCtrl::Remove(long from
, long to
)
1257 bool formerEditable
= m_editable
;
1258 if ( !formerEditable
)
1260 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1261 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1262 if ( !formerEditable
)
1263 SetEditable( formerEditable
) ;
1269 void wxTextCtrl::SetSelection(long from
, long to
)
1272 /* change the selection */
1273 if ((from
== -1) && (to
== -1))
1274 TXNSelectAll((TXNObject
) m_macTXN
);
1276 TXNSetSelection( (TXNObject
) m_macTXN
, from
, to
);
1277 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1279 ControlEditTextSelectionRec sel
;
1280 sel
.selStart
= from
;
1282 verify_noerr( SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextSelectionTag
,
1283 sizeof(ControlEditTextSelectionRec
), &sel
) );
1288 bool wxTextCtrl::LoadFile(const wxString
& file
)
1290 if ( wxTextCtrlBase::LoadFile(file
) )
1298 void wxTextCtrl::WriteText(const wxString
& str
)
1301 wxMacConvertNewlines13To10( &st
) ;
1303 bool formerEditable
= m_editable
;
1304 if ( !formerEditable
)
1307 wxMacWindowStateSaver( this ) ;
1308 long start
, end
, dummy
;
1309 GetSelection( &start
, &dummy
) ;
1310 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1311 GetSelection( &dummy
, &end
) ;
1312 SetStyle( start
, end
, GetDefaultStyle() ) ;
1314 if ( !formerEditable
)
1315 SetEditable( formerEditable
) ;
1317 MacRedrawControl() ;
1319 wxMacCFStringHolder
cf(st
, m_font
.GetEncoding() ) ;
1320 CFStringRef value
= cf
;
1321 SetControlData( (ControlRef
) m_macControl
, 0, kControlEditTextInsertCFStringRefTag
,
1322 sizeof(CFStringRef
), &value
);
1326 void wxTextCtrl::AppendText(const wxString
& text
)
1328 SetInsertionPointEnd();
1332 void wxTextCtrl::Clear()
1335 bool formerEditable
= m_editable
;
1336 if ( !formerEditable
)
1338 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1339 TXNClear((TXNObject
)m_macTXN
);
1341 if ( !formerEditable
)
1342 SetEditable( formerEditable
) ;
1346 SetValue(wxEmptyString
) ;
1350 bool wxTextCtrl::IsModified() const
1355 bool wxTextCtrl::IsEditable() const
1357 return IsEnabled() && m_editable
;
1360 bool wxTextCtrl::AcceptsFocus() const
1362 // we don't want focus if we can't be edited
1363 return /*IsEditable() && */ wxControl::AcceptsFocus();
1366 wxSize
wxTextCtrl::DoGetBestSize() const
1372 switch( m_windowVariant
)
1374 case wxWINDOW_VARIANT_NORMAL
:
1377 case wxWINDOW_VARIANT_SMALL
:
1380 case wxWINDOW_VARIANT_MINI
:
1388 if ( m_windowStyle
& wxTE_MULTILINE
)
1393 return wxSize(wText
, hText
);
1396 // ----------------------------------------------------------------------------
1398 // ----------------------------------------------------------------------------
1400 void wxTextCtrl::Undo()
1405 TXNUndo((TXNObject
)m_macTXN
);
1410 void wxTextCtrl::Redo()
1415 TXNRedo((TXNObject
)m_macTXN
);
1420 bool wxTextCtrl::CanUndo() const
1422 if ( !IsEditable() )
1427 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1433 bool wxTextCtrl::CanRedo() const
1435 if ( !IsEditable() )
1440 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1446 // Makes modifie or unmodified
1447 void wxTextCtrl::MarkDirty()
1452 void wxTextCtrl::DiscardEdits()
1457 int wxTextCtrl::GetNumberOfLines() const
1459 ItemCount lines
= 0 ;
1461 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1466 long wxTextCtrl::XYToPosition(long x
, long y
) const
1471 long lastpos
= GetLastPosition() ;
1473 // TODO find a better implementation : while we can get the
1474 // line metrics of a certain line, we don't get its starting
1475 // position, so it would probably be rather a binary search
1476 // for the start position
1479 int lastHeight
= 0 ;
1482 for ( n
= 0 ; n
<= lastpos
; ++n
)
1484 if ( y
== ypos
&& x
== xpos
)
1487 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1489 if ( curpt
.v
> lastHeight
)
1494 lastHeight
= curpt
.v
;
1503 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1508 long lastpos
= GetLastPosition() ;
1513 if ( pos
<= lastpos
)
1515 // TODO find a better implementation : while we can get the
1516 // line metrics of a certain line, we don't get its starting
1517 // position, so it would probably be rather a binary search
1518 // for the start position
1521 int lastHeight
= 0 ;
1524 for ( n
= 0 ; n
<= pos
; ++n
)
1526 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1528 if ( curpt
.v
> lastHeight
)
1533 lastHeight
= curpt
.v
;
1538 if ( y
) *y
= ypos
;
1539 if ( x
) *x
= xpos
;
1548 void wxTextCtrl::ShowPosition(long pos
)
1551 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1555 TXNOffset selstart
, selend
;
1556 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1557 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1558 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1559 //TODO use HIPoints for 10.3 and above
1560 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1562 OSErr theErr
= noErr
;
1563 SInt32 dv
= desired
.v
- current
.v
;
1564 SInt32 dh
= desired
.h
- current
.h
;
1565 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1566 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1567 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1574 int wxTextCtrl::GetLineLength(long lineNo
) const
1578 if ( lineNo
< GetNumberOfLines() )
1580 // TODO find a better implementation : while we can get the
1581 // line metrics of a certain line, we don't get its starting
1582 // position, so it would probably be rather a binary search
1583 // for the start position
1586 int lastHeight
= 0 ;
1587 long lastpos
= GetLastPosition() ;
1590 for ( n
= 0 ; n
<= lastpos
; ++n
)
1592 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1594 if ( curpt
.v
> lastHeight
)
1596 if ( ypos
== lineNo
)
1602 lastHeight
= curpt
.v
;
1612 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1617 wxString content
= GetValue() ;
1619 if ( lineNo
< GetNumberOfLines() )
1621 // TODO find a better implementation : while we can get the
1622 // line metrics of a certain line, we don't get its starting
1623 // position, so it would probably be rather a binary search
1624 // for the start position
1627 int lastHeight
= 0 ;
1628 long lastpos
= GetLastPosition() ;
1631 for ( n
= 0 ; n
<= lastpos
; ++n
)
1633 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1635 if ( curpt
.v
> lastHeight
)
1637 if ( ypos
== lineNo
)
1643 lastHeight
= curpt
.v
;
1647 if ( ypos
== lineNo
)
1648 line
+= content
[n
] ;
1661 void wxTextCtrl::Command(wxCommandEvent
& event
)
1663 SetValue (event
.GetString());
1664 ProcessCommand (event
);
1667 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1669 // By default, load the first file into the text window.
1670 if (event
.GetNumberOfFiles() > 0)
1672 LoadFile(event
.GetFiles()[0]);
1676 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1678 int key
= event
.GetKeyCode() ;
1679 bool eat_key
= false ;
1681 if ( key
== 'c' && event
.MetaDown() )
1688 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1689 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1690 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1697 // assume that any key not processed yet is going to modify the control
1700 if ( key
== 'v' && event
.MetaDown() )
1706 if ( key
== 'x' && event
.MetaDown() )
1715 if (m_windowStyle
& wxPROCESS_ENTER
)
1717 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1718 event
.SetEventObject( this );
1719 event
.SetString( GetValue() );
1720 if ( GetEventHandler()->ProcessEvent(event
) )
1723 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1725 wxWindow
*parent
= GetParent();
1726 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1727 parent
= parent
->GetParent() ;
1729 if ( parent
&& parent
->GetDefaultItem() )
1731 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1733 if ( def
&& def
->IsEnabled() )
1735 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1736 event
.SetEventObject(def
);
1737 def
->Command(event
);
1742 // this will make wxWindows eat the ENTER key so that
1743 // we actually prevent line wrapping in a single line
1751 // always produce navigation event - even if we process TAB
1752 // ourselves the fact that we got here means that the user code
1753 // decided to skip processing of this TAB - probably to let it
1754 // do its default job.
1756 wxNavigationKeyEvent eventNav
;
1757 eventNav
.SetDirection(!event
.ShiftDown());
1758 eventNav
.SetWindowChange(event
.ControlDown());
1759 eventNav
.SetEventObject(this);
1761 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1772 // perform keystroke handling
1773 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1774 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1778 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1780 EventRecord
*ev
= &rec
;
1783 keychar
= short(ev
->message
& charCodeMask
);
1784 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1786 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1790 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1791 key
== WXK_RETURN
||
1792 key
== WXK_DELETE
||
1795 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1796 event1
.SetString( GetValue() ) ;
1797 event1
.SetEventObject( this );
1798 wxPostEvent(GetEventHandler(),event1
);
1802 // ----------------------------------------------------------------------------
1803 // standard handlers for standard edit menu events
1804 // ----------------------------------------------------------------------------
1806 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1811 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1816 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1821 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1826 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1831 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1833 event
.Enable( CanCut() );
1836 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1838 event
.Enable( CanCopy() );
1841 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1843 event
.Enable( CanPaste() );
1846 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1848 event
.Enable( CanUndo() );
1851 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1853 event
.Enable( CanRedo() );
1856 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1861 // user pane implementation
1863 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1867 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1869 return kControlNoPart
;
1872 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1874 return kControlNoPart
;
1877 void wxTextCtrl::MacControlUserPaneIdleProc()
1881 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1883 return kControlNoPart
;
1886 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1890 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1892 return kControlNoPart
;
1895 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)