1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
21 #include <sys/types.h>
27 #include "wx/msgdlg.h"
29 #if wxUSE_STD_IOSTREAM
39 #include "wx/button.h"
40 #include "wx/toplevel.h"
41 #include "wx/textctrl.h"
42 #include "wx/notebook.h"
43 #include "wx/tabctrl.h"
44 #include "wx/settings.h"
45 #include "wx/filefn.h"
48 #if defined(__BORLANDC__) && !defined(__WIN32__)
50 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
57 #include <MacTextEditor.h>
58 #include <ATSUnicode.h>
59 #include <TextCommon.h>
60 #include <TextEncodingConverter.h>
61 #include "wx/mac/uma.h"
63 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
65 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
66 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
67 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
68 // an alternate path for carbon key events that routes automatically into the same wx flow of events
72 /* kmUPTextPart is the part code we return to indicate the user has clicked
73 in the text area of our control */
74 #define kmUPTextPart 1
77 /* routines for using existing user pane controls.
78 These routines are useful for cases where you would like to use an
79 existing user pane control in, say, a dialog window as a scrolling
82 /* Utility Routines */
84 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
85 routine. In our focus switching routine this part code is understood
86 as meaning 'the user has clicked in the control and we need to switch
87 the current focus to ourselves before we can continue'. */
88 #define kUserClickedToFocusPart 100
90 /* STPTextPaneVars is a structure used for storing the the mUP Control's
91 internal variables and state information. A handle to this record is
92 stored in the pane control's reference value field using the
93 SetControlReference routine. */
96 /* OS records referenced */
97 TXNObject fTXNRec
; /* the txn record */
98 TXNFrameID fTXNFrame
; /* the txn frame ID */
99 ControlRef fUserPaneRec
; /* handle to the user pane control */
100 WindowPtr fOwner
; /* window containing control */
101 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
103 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
104 Boolean fIsActive
; /* true while the control is drawn in the active state */
105 Boolean fTXNObjectActive
; /* reflects the activation state of the text edit record */
106 Boolean fFocusDrawState
; /* true if focus is drawn (default: true) */
107 /* calculated locations */
108 Rect fRBounds
; /* control bounds */
109 Rect fRTextArea
; /* area where the text is drawn */
110 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
111 Rect fRTextOutline
; /* rectangle used to draw the border */
112 RgnHandle fRTextOutlineRegion
; /* background region for the text, erased before calling TEUpdate */
113 /* our focus advance override routine */
114 EventHandlerUPP handlerUPP
;
115 EventHandlerRef handlerRef
;
121 /* mUPOpenControl initializes a user pane control so it will be drawn
122 and will behave as a scrolling text edit field inside of a window.
123 This routine performs all of the initialization steps necessary,
124 except it does not create the user pane control itself. theControl
125 should refer to a user pane control that you have either created
126 yourself or extracted from a dialog's control heirarchy using
127 the GetDialogItemAsControl routine. */
128 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
);
133 /* Univerals Procedure Pointer variables used by the
134 mUP Control. These variables are set up
135 the first time that mUPOpenControl is called. */
136 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
137 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
138 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
139 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
140 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
141 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
142 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
144 // one place for calculating all
145 static void TPCalculateBounds(STPTextPaneVars
*varsp
, const Rect
& bounds
)
147 SetRect(&varsp
->fRBounds
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
148 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
149 // eventually make TextOutline inset 1,1
150 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
151 if ( !varsp
->fNoBorders
)
153 SetRect(&varsp
->fRTextArea
, bounds
.left
+ 2 , bounds
.top
+ (varsp
->fMultiline
? 0 : 2) ,
154 bounds
.right
- (varsp
->fMultiline
? 0 : 2), bounds
.bottom
- (varsp
->fMultiline
? 0 : 2));
158 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
,
159 bounds
.right
, bounds
.bottom
);
163 OSStatus
MLTESetObjectVisibility( STPTextPaneVars
*varsp
, Boolean vis
, long wxStyle
)
165 OSStatus err
= noErr
;
166 #if TARGET_API_MAC_OSX
167 TXNControlTag iControlTags
[1] = { kTXNVisibilityTag
};
168 TXNControlData iControlData
[1] = {{ vis
}};
169 err
= ::TXNSetTXNObjectControls( varsp
->fTXNRec
, false, 1, iControlTags
, iControlData
);
174 UMAGetControlBoundsInWindowCoords( varsp
->fUserPaneRec
, &bounds
);
175 TPCalculateBounds( varsp
, bounds
) ;
176 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
177 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
178 TXNShowSelection( varsp
->fTXNRec
, kTXNShowStart
);
183 // make sure we don't miss changes as carbon events are not available for these under classic
184 static void TPUpdateVisibility(ControlRef theControl
) {
185 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
186 if ( textctrl
== NULL
)
189 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
192 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
193 if ( textctrl
->MacIsReallyShown() != varsp
->fVisible
)
195 // invalidate old position
196 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
197 varsp
->fVisible
= textctrl
->MacIsReallyShown() ;
199 if ( !EqualRect( &bounds
, &varsp
->fRBounds
) )
202 Rect oldBounds
= varsp
->fRBounds
;
203 TPCalculateBounds( varsp
, bounds
) ;
204 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
205 if ( varsp
->fVisible
)
207 TXNSetFrameBounds( varsp
->fTXNRec
, varsp
->fRTextArea
.top
, varsp
->fRTextArea
.left
,
208 varsp
->fRTextArea
.bottom
, varsp
->fRTextArea
.right
, varsp
->fTXNFrame
);
210 InvalWindowRect( GetControlOwner( theControl
) , &oldBounds
) ;
211 InvalWindowRect( GetControlOwner( theControl
) , &varsp
->fRBounds
) ;
215 // make correct activations
216 static void TPActivatePaneText(STPTextPaneVars
*varsp
, Boolean setActive
) {
218 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
219 if (varsp
->fTXNObjectActive
!= setActive
&& textctrl
->MacIsReallyShown() )
221 varsp
->fTXNObjectActive
= setActive
;
222 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTXNObjectActive
);
224 TXNFocus( varsp
->fTXNRec
, varsp
->fTXNObjectActive
);
228 // update focus outlines
229 static void TPRedrawFocusOutline(STPTextPaneVars
*varsp
) {
232 if (varsp
->fFocusDrawState
!= (varsp
->fIsActive
&& varsp
->fInFocus
))
234 varsp
->fFocusDrawState
= (varsp
->fIsActive
&& varsp
->fInFocus
);
235 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fFocusDrawState
);
239 // update TXN focus state
240 static void TPFocusPaneText(STPTextPaneVars
*varsp
, Boolean setFocus
) {
241 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(varsp
->fUserPaneRec
);
243 if (varsp
->fInFocus
!= setFocus
&& textctrl
->MacIsReallyShown()) {
244 varsp
->fInFocus
= setFocus
;
245 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
250 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
251 /* set up our globals */
253 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
254 if ( textctrl
== NULL
)
256 TPUpdateVisibility( theControl
) ;
258 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
259 if ( textctrl
->MacIsReallyShown() )
261 wxMacWindowClipper
clipper( textctrl
) ;
262 TXNDraw(varsp
->fTXNRec
, NULL
);
263 if ( !varsp
->fNoBorders
)
264 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
265 TPRedrawFocusOutline( varsp
) ;
271 /* TPPaneHitTestProc is called when the control manager would
272 like to determine what part of the control the mouse resides over.
273 We also call this routine from our tracking proc to determine how
274 to handle mouse clicks. */
275 static pascal ControlPartCode
TPPaneHitTestProc(ControlRef theControl
, Point where
) {
276 ControlPartCode result
;
277 /* set up our locals and lock down our globals*/
279 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
280 if ( textctrl
== NULL
)
282 TPUpdateVisibility( theControl
) ;
283 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
284 if (textctrl
->MacIsReallyShown() )
286 if (PtInRect(where
, &varsp
->fRBounds
))
287 result
= kmUPTextPart
;
298 /* TPPaneTrackingProc is called when the mouse is being held down
299 over our control. This routine handles clicks in the text area
300 and in the scroll bar. */
301 static pascal ControlPartCode
TPPaneTrackingProc(ControlRef theControl
, Point startPt
, ControlActionUPP actionProc
) {
303 ControlPartCode partCodeResult
;
304 /* make sure we have some variables... */
306 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
307 if ( textctrl
== NULL
)
309 TPUpdateVisibility( theControl
) ;
310 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
311 if (textctrl
->MacIsReallyShown() )
313 /* we don't do any of these functions unless we're in focus */
314 if ( ! varsp
->fInFocus
) {
316 owner
= GetControlOwner(theControl
);
317 ClearKeyboardFocus(owner
);
318 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
320 /* find the location for the click */
321 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
322 if ( textctrl
->MacGetTopLevelWindow()->MacUsesCompositing() )
325 textctrl
->MacClientToRootWindow( &x
, &y
) ;
330 switch (TPPaneHitTestProc(theControl
, startPt
))
333 /* handle clicks in the text part */
336 wxMacWindowClipper
clipper( textctrl
) ;
339 ConvertEventRefToEventRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) ;
340 TXNClick( varsp
->fTXNRec
, &rec
);
347 return partCodeResult
;
351 /* TPPaneIdleProc is our user pane idle routine. When our text field
352 is active and in focus, we use this routine to set the cursor. */
353 static pascal void TPPaneIdleProc(ControlRef theControl
) {
355 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
356 if ( textctrl
== NULL
)
358 TPUpdateVisibility( theControl
) ;
359 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
360 if (textctrl
->MacIsReallyShown()) {
361 /* if we're not active, then we have nothing to say about the cursor */
362 if (varsp
->fIsActive
) {
366 wxMacWindowClipper
clipper( textctrl
) ;
368 /* there's a 'focus thing' and an 'unfocused thing' */
369 if (varsp
->fInFocus
) {
370 /* flash the cursor */
371 SetPort(varsp
->fDrawingEnvironment
);
372 TXNIdle(varsp
->fTXNRec
);
374 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
376 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
377 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
382 // SetThemeCursor(kThemeArrowCursor);
385 /* if it's in our bounds, set the cursor */
386 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
387 if (PtInRect(mousep
, &bounds
))
389 // SetThemeCursor(kThemeArrowCursor);
397 /* TPPaneKeyDownProc is called whenever a keydown event is directed
398 at our control. Here, we direct the keydown event to the text
399 edit record and redraw the scroll bar and text field as appropriate. */
400 static pascal ControlPartCode
TPPaneKeyDownProc(ControlRef theControl
,
401 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
403 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
404 if ( textctrl
== NULL
)
406 TPUpdateVisibility( theControl
) ;
408 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
411 /* turn autoscrolling on and send the key event to text edit */
412 wxMacWindowClipper
clipper( textctrl
) ;
414 memset( &ev
, 0 , sizeof( ev
) ) ;
416 ev
.modifiers
= modifiers
;
417 ev
.message
= (( keyCode
<< 8 ) & keyCodeMask
) + ( charCode
& charCodeMask
) ;
418 TXNKeyDown( varsp
->fTXNRec
, &ev
);
420 return kControlEntireControl
;
424 /* TPPaneActivateProc is called when the window containing
425 the user pane control receives activate events. Here, we redraw
426 the control and it's text as necessary for the activation state. */
427 static pascal void TPPaneActivateProc(ControlRef theControl
, Boolean activating
) {
429 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
431 if ( textctrl
== NULL
)
433 TPUpdateVisibility( theControl
) ;
435 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
437 varsp
->fIsActive
= activating
;
438 wxMacWindowClipper
clipper( textctrl
) ;
439 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
440 /* redraw the frame */
441 if ( textctrl
->MacIsReallyShown() )
443 if ( !varsp
->fNoBorders
)
444 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
445 TPRedrawFocusOutline( varsp
) ;
450 /* TPPaneFocusProc is called when every the focus changes to or
451 from our control. Herein, switch the focus appropriately
452 according to the parameters and redraw the control as
454 static pascal ControlPartCode
TPPaneFocusProc(ControlRef theControl
, ControlFocusPart action
) {
455 ControlPartCode focusResult
;
457 focusResult
= kControlFocusNoPart
;
458 wxTextCtrl
* textctrl
= (wxTextCtrl
*) GetControlReference(theControl
);
459 if ( textctrl
== NULL
)
461 TPUpdateVisibility( theControl
) ;
462 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) textctrl
->m_macTXNvars
;
463 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
464 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
465 and kControlFocusNextPart will be received. When the user clicks in our field
466 and it is not the current focus, then the constant kUserClickedToFocusPart will
467 be received. The constant kControlFocusNoPart will be received when our control
468 is the current focus and the user clicks in another control. In your focus routine,
469 you should respond to these codes as follows:
471 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
472 the control and the focus rectangle as necessary.
474 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
475 depending on its current state. redraw the control and the focus rectangle
476 as appropriate for the new focus state. If the focus state is 'off', return the constant
477 kControlFocusNoPart, otherwise return a non-zero part code.
478 kUserClickedToFocusPart - is a constant defined for this example. You should
479 define your own value for handling click-to-focus type events. */
480 /* calculate the next highlight state */
483 case kControlFocusNoPart
:
484 TPFocusPaneText(varsp
, false);
485 focusResult
= kControlFocusNoPart
;
487 case kUserClickedToFocusPart
:
488 TPFocusPaneText(varsp
, true);
491 case kControlFocusPrevPart
:
492 case kControlFocusNextPart
:
493 TPFocusPaneText(varsp
, ( ! varsp
->fInFocus
));
494 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
497 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
498 /* redraw the text fram and focus rectangle to indicate the
500 if ( textctrl
->MacIsReallyShown() )
502 wxMacWindowClipper
c( textctrl
) ;
503 if ( !varsp
->fNoBorders
)
504 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
505 TPRedrawFocusOutline( varsp
) ;
511 /* mUPOpenControl initializes a user pane control so it will be drawn
512 and will behave as a scrolling text edit field inside of a window.
513 This routine performs all of the initialization steps necessary,
514 except it does not create the user pane control itself. theControl
515 should refer to a user pane control that you have either created
516 yourself or extracted from a dialog's control heirarchy using
517 the GetDialogItemAsControl routine. */
518 OSStatus
mUPOpenControl(STPTextPaneVars
* &handle
, ControlRef theControl
, long wxStyle
)
522 STPTextPaneVars
*varsp
;
523 OSStatus err
= noErr
;
525 /* set up our globals */
526 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
527 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
528 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
529 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
530 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
531 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
532 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
534 /* allocate our private storage */
535 varsp
= (STPTextPaneVars
*) malloc(sizeof(STPTextPaneVars
));
538 /* set the initial settings for our private data */
539 varsp
->fMultiline
= wxStyle
& wxTE_MULTILINE
;
540 varsp
->fNoBorders
= wxStyle
& wxNO_BORDER
;
541 varsp
->fInFocus
= false;
542 varsp
->fIsActive
= true;
543 varsp
->fTXNObjectActive
= false;
544 varsp
->fFocusDrawState
= false ;
545 varsp
->fUserPaneRec
= theControl
;
546 varsp
->fVisible
= true ;
548 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
550 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(theWindow
);
552 /* set up the user pane procedures */
553 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
554 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
555 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
556 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
557 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
558 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
559 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
561 /* calculate the rectangles used by the control */
562 UMAGetControlBoundsInWindowCoords(theControl
, &bounds
);
563 varsp
->fRTextOutlineRegion
= NewRgn() ;
564 TPCalculateBounds( varsp
, bounds
) ;
566 /* set up the drawing environment */
567 SetPort(varsp
->fDrawingEnvironment
);
569 /* create the new edit field */
571 TXNFrameOptions frameOptions
=
572 kTXNDontDrawCaretWhenInactiveMask
;
573 if ( ! ( wxStyle
& wxTE_NOHIDESEL
) )
574 frameOptions
|= kTXNDontDrawSelectionWhenInactiveMask
;
576 if ( wxStyle
& wxTE_MULTILINE
)
578 if ( ! ( wxStyle
& wxTE_DONTWRAP
) )
579 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
582 frameOptions
|= kTXNAlwaysWrapAtViewEdgeMask
;
583 frameOptions
|= kTXNWantHScrollBarMask
;
586 if ( !(wxStyle
& wxTE_NO_VSCROLL
) )
587 frameOptions
|= kTXNWantVScrollBarMask
;
590 frameOptions
|= kTXNSingleLineOnlyMask
;
592 verify_noerr(TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
594 kTXNTextEditStyleFrameType
,
596 kTXNSystemDefaultEncoding
,
597 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) varsp
));
599 TXNControlTag iControlTags
[3] = { kTXNDoFontSubstitution
, kTXNWordWrapStateTag
};
600 TXNControlData iControlData
[3] = { {false}, {kTXNAutoWrap
} };
602 #if TARGET_API_MAC_OSX
603 iControlTags
[2] = kTXNVisibilityTag
;
604 iControlData
[2].uValue
= false ;
607 iControlData
[1].uValue
= varsp
->fVisible
;
609 if ( (wxStyle
& wxTE_MULTILINE
) && (wxStyle
& wxTE_DONTWRAP
) )
610 iControlData
[2].uValue
= kTXNNoAutoWrap
;
612 verify_noerr( TXNSetTXNObjectControls( varsp
->fTXNRec
, false, toptag
,
613 iControlTags
, iControlData
)) ;
619 GetThemeFont(kThemeSmallSystemFont
, GetApplicationScript() , fontName
, &fontSize
, &fontStyle
) ;
621 TXNTypeAttributes typeAttr
[] =
623 { kTXNQDFontNameAttribute
, kTXNQDFontNameAttributeSize
, { (void*) fontName
} } ,
624 { kTXNQDFontSizeAttribute
, kTXNFontSizeAttributeSize
, { (void*) (fontSize
<< 16) } } ,
625 { kTXNQDFontStyleAttribute
, kTXNQDFontStyleAttributeSize
, { (void*) normal
} } ,
628 err
= TXNSetTypeAttributes (varsp
->fTXNRec
, sizeof( typeAttr
) / sizeof(TXNTypeAttributes
) , typeAttr
,
633 /* perform final activations and setup for our text field. Here,
634 we assume that the window is going to be the 'active' window. */
635 TPActivatePaneText(varsp
, varsp
->fIsActive
&& varsp
->fInFocus
);
643 #if !USE_SHARED_LIBRARY
644 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
646 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
647 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
648 EVT_CHAR(wxTextCtrl::OnChar
)
649 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
650 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
651 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
652 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
653 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
655 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
656 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
657 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
658 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
659 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
663 static void SetTXNData( STPTextPaneVars
*varsp
, TXNObject txn
, const wxString
& st
, TXNOffset start
, TXNOffset end
)
666 #if SIZEOF_WCHAR_T == 2
667 size_t len
= st
.Len() ;
668 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)st
.wc_str(), len
* 2,
671 wxMBConvUTF16BE converter
;
672 ByteCount byteBufferLen
= converter
.WC2MB( NULL
, st
.wc_str() , 0 ) ;
673 UniChar
*unibuf
= (UniChar
*) malloc(byteBufferLen
) ;
674 converter
.WC2MB( (char*) unibuf
, st
.wc_str() , byteBufferLen
) ;
675 TXNSetData( txn
, kTXNUnicodeTextData
, (void*)unibuf
, byteBufferLen
,
680 wxCharBuffer text
= st
.mb_str(wxConvLocal
) ;
681 TXNSetData( txn
, kTXNTextData
, (void*)text
.data(), strlen( text
) ,
687 void wxTextCtrl::Init()
690 m_macTXNvars
= NULL
;
695 m_maxLength
= TE_UNLIMITED_LENGTH
;
698 wxTextCtrl::~wxTextCtrl()
700 SetControlReference((ControlRef
)m_macControl
, 0) ;
701 TXNDeleteObject((TXNObject
)m_macTXN
);
702 /* delete our private storage */
704 /* zero the control reference */
708 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
711 const wxSize
& size
, long style
,
712 const wxValidator
& validator
,
713 const wxString
& name
)
715 m_macIsUserPane
= FALSE
;
718 m_macTXNvars
= NULL
;
721 // base initialization
722 if ( !wxTextCtrlBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
725 wxSize mySize
= size
;
727 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
729 if ( m_windowStyle
& wxTE_MULTILINE
)
731 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
732 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
734 m_windowStyle
|= wxTE_PROCESS_ENTER
;
738 wxMacConvertNewlines13To10( &st
) ;
742 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
743 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
744 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
745 /* create the control */
746 m_macControl
= (WXWidget
) ::NewControl(MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, "\p", true , featurSet
, 0, featurSet
, kControlUserPaneProc
, (long) this );
747 /* set up the mUP specific features and data */
748 wxMacWindowClipper
c(this) ;
749 STPTextPaneVars
*varsp
;
750 mUPOpenControl( varsp
, (ControlRef
) m_macControl
, m_windowStyle
);
751 m_macTXNvars
= varsp
;
752 m_macTXN
= varsp
->fTXNRec
;
753 if ( style
& wxTE_PASSWORD
)
756 verify_noerr(TXNEchoMode( (TXNObject
) m_macTXN
, c
, 0 , true )) ;
759 MacPostControlCreate(pos
,size
) ;
761 if ( MacIsReallyShown() )
762 MLTESetObjectVisibility( (STPTextPaneVars
*) m_macTXNvars
, true , GetWindowStyle() ) ;
765 wxMacWindowClipper
clipper( this ) ;
766 TPUpdateVisibility( (ControlRef
) m_macControl
) ;
767 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
769 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
770 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
773 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
774 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
776 SetBackgroundColour( *wxWHITE
) ;
779 tback
.bgType
= kTXNBackgroundTypeRGB
;
780 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
781 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
783 if ( m_windowStyle
& wxTE_READONLY
)
785 SetEditable( false ) ;
791 void wxTextCtrl::MacVisibilityChanged()
793 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
794 if ( !MacIsReallyShown() )
795 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
799 void wxTextCtrl::MacEnabledStateChanged()
804 wxString
wxTextCtrl::GetValue() const
813 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
821 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
822 if ( actualSize
> 0 )
825 #if SIZEOF_WCHAR_T == 2
826 ptr
= new wxChar
[actualSize
+ 1 ] ;
827 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
830 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
832 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
833 wxMBConvUTF16BE converter
;
834 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
835 ptr
= new wxChar
[noChars
+ 1] ;
837 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
841 ptr
[actualSize
] = 0 ;
842 result
= wxString( ptr
) ;
845 DisposeHandle( theText
) ;
849 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
857 actualSize
= GetHandleSize( theText
) ;
858 if ( actualSize
> 0 )
861 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
864 DisposeHandle( theText
) ;
868 wxMacConvertNewlines10To13( &result
) ;
872 void wxTextCtrl::GetSelection(long* from
, long* to
) const
874 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
877 void wxTextCtrl::SetValue(const wxString
& str
)
880 if ( GetValue() == str
)
884 wxMacConvertNewlines13To10( &st
) ;
887 wxMacWindowClipper
c( this ) ;
888 bool formerEditable
= m_editable
;
889 if ( !formerEditable
)
892 // otherwise scrolling might have problems ?
893 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
894 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
895 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
896 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
897 if ( !formerEditable
)
898 SetEditable(formerEditable
) ;
902 void wxTextCtrl::SetMaxLength(unsigned long len
)
907 bool wxTextCtrl::SetFont( const wxFont
& font
)
909 if ( !wxTextCtrlBase::SetFont( font
) )
912 wxMacWindowClipper
c( this ) ;
913 bool formerEditable
= m_editable
;
914 if ( !formerEditable
)
917 TXNTypeAttributes typeAttr
[4] ;
918 Str255 fontName
= "\pMonaco" ;
919 SInt16 fontSize
= 12 ;
920 Style fontStyle
= normal
;
921 int attrCounter
= 0 ;
923 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
924 fontSize
= font
.MacGetFontSize() ;
925 fontStyle
= font
.MacGetFontStyle() ;
927 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
928 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
929 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
930 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
931 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
932 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
933 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
934 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
935 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
938 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
939 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
940 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
941 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
944 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
946 if ( !formerEditable
)
947 SetEditable(formerEditable
) ;
951 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
953 bool formerEditable
= m_editable
;
954 if ( !formerEditable
)
956 TXNTypeAttributes typeAttr
[4] ;
957 Str255 fontName
= "\pMonaco" ;
958 SInt16 fontSize
= 12 ;
959 Style fontStyle
= normal
;
961 int attrCounter
= 0 ;
962 if ( style
.HasFont() )
964 const wxFont
&font
= style
.GetFont() ;
965 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
966 fontSize
= font
.GetPointSize() ;
967 if ( font
.GetUnderlined() )
968 fontStyle
|= underline
;
969 if ( font
.GetWeight() == wxBOLD
)
971 if ( font
.GetStyle() == wxITALIC
)
972 fontStyle
|= italic
;
974 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
975 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
976 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
977 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
978 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
979 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
980 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
981 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
982 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
986 if ( style
.HasTextColour() )
988 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
989 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
990 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
991 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
995 if ( attrCounter
> 0 )
997 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
999 if ( !formerEditable
)
1000 SetEditable(formerEditable
) ;
1005 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1007 wxTextCtrlBase::SetDefaultStyle( style
) ;
1008 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1012 // Clipboard operations
1013 void wxTextCtrl::Copy()
1017 ClearCurrentScrap();
1018 TXNCopy((TXNObject
)m_macTXN
);
1019 TXNConvertToPublicScrap();
1023 void wxTextCtrl::Cut()
1027 ClearCurrentScrap();
1028 TXNCut((TXNObject
)m_macTXN
);
1029 TXNConvertToPublicScrap();
1031 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1032 event
.SetString( GetValue() ) ;
1033 event
.SetEventObject( this );
1034 GetEventHandler()->ProcessEvent(event
);
1038 void wxTextCtrl::Paste()
1043 TXNConvertFromPublicScrap();
1044 TXNPaste((TXNObject
)m_macTXN
);
1045 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1047 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1048 event
.SetString( GetValue() ) ;
1049 event
.SetEventObject( this );
1050 GetEventHandler()->ProcessEvent(event
);
1054 bool wxTextCtrl::CanCopy() const
1056 // Can copy if there's a selection
1058 GetSelection(& from
, & to
);
1059 return (from
!= to
);
1062 bool wxTextCtrl::CanCut() const
1064 if ( !IsEditable() )
1068 // Can cut if there's a selection
1070 GetSelection(& from
, & to
);
1071 return (from
!= to
);
1074 bool wxTextCtrl::CanPaste() const
1079 return TXNIsScrapPastable() ;
1082 void wxTextCtrl::SetEditable(bool editable
)
1084 if ( editable
!= m_editable
)
1086 m_editable
= editable
;
1088 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1089 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1090 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1095 void wxTextCtrl::SetInsertionPoint(long pos
)
1097 SetSelection( pos
, pos
) ;
1100 void wxTextCtrl::SetInsertionPointEnd()
1102 long pos
= GetLastPosition();
1103 SetInsertionPoint(pos
);
1106 long wxTextCtrl::GetInsertionPoint() const
1109 GetSelection( &begin
, &end
) ;
1113 long wxTextCtrl::GetLastPosition() const
1117 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1125 actualsize
= GetHandleSize( theText
) ;
1126 DisposeHandle( theText
) ;
1131 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1133 wxString value
= str
;
1134 wxMacConvertNewlines13To10( &value
) ;
1136 bool formerEditable
= m_editable
;
1137 if ( !formerEditable
)
1139 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1140 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1141 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1142 if ( !formerEditable
)
1143 SetEditable( formerEditable
) ;
1148 void wxTextCtrl::Remove(long from
, long to
)
1150 bool formerEditable
= m_editable
;
1151 if ( !formerEditable
)
1153 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1154 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1155 if ( !formerEditable
)
1156 SetEditable( formerEditable
) ;
1161 void wxTextCtrl::SetSelection(long from
, long to
)
1163 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) m_macTXNvars
;
1164 /* and our drawing environment as the operation
1165 may force a redraw in the text area. */
1166 SetPort(varsp
->fDrawingEnvironment
);
1167 /* change the selection */
1168 if ((from
== -1) && (to
== -1))
1169 TXNSelectAll((TXNObject
) m_macTXN
);
1171 TXNSetSelection( varsp
->fTXNRec
, from
, to
);
1172 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1175 bool wxTextCtrl::LoadFile(const wxString
& file
)
1177 if ( wxTextCtrlBase::LoadFile(file
) )
1185 void wxTextCtrl::WriteText(const wxString
& str
)
1188 wxMacConvertNewlines13To10( &st
) ;
1190 bool formerEditable
= m_editable
;
1191 if ( !formerEditable
)
1193 long start
, end
, dummy
;
1194 GetSelection( &start
, &dummy
) ;
1195 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1196 GetSelection( &dummy
, &end
) ;
1197 SetStyle( start
, end
, GetDefaultStyle() ) ;
1198 if ( !formerEditable
)
1199 SetEditable( formerEditable
) ;
1201 MacRedrawControl() ;
1204 void wxTextCtrl::AppendText(const wxString
& text
)
1206 SetInsertionPointEnd();
1210 void wxTextCtrl::Clear()
1212 bool formerEditable
= m_editable
;
1213 if ( !formerEditable
)
1215 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1216 TXNClear((TXNObject
)m_macTXN
);
1218 if ( !formerEditable
)
1219 SetEditable( formerEditable
) ;
1224 bool wxTextCtrl::IsModified() const
1229 bool wxTextCtrl::IsEditable() const
1231 return IsEnabled() && m_editable
;
1234 bool wxTextCtrl::AcceptsFocus() const
1236 // we don't want focus if we can't be edited
1237 return /*IsEditable() && */ wxControl::AcceptsFocus();
1240 wxSize
wxTextCtrl::DoGetBestSize() const
1246 switch( m_windowVariant
)
1248 case wxWINDOW_VARIANT_NORMAL
:
1251 case wxWINDOW_VARIANT_SMALL
:
1254 case wxWINDOW_VARIANT_MINI
:
1262 if ( m_windowStyle
& wxTE_MULTILINE
)
1267 return wxSize(wText
, hText
);
1270 // ----------------------------------------------------------------------------
1272 // ----------------------------------------------------------------------------
1274 void wxTextCtrl::Undo()
1278 TXNUndo((TXNObject
)m_macTXN
);
1282 void wxTextCtrl::Redo()
1286 TXNRedo((TXNObject
)m_macTXN
);
1290 bool wxTextCtrl::CanUndo() const
1292 if ( !IsEditable() )
1296 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1299 bool wxTextCtrl::CanRedo() const
1301 if ( !IsEditable() )
1305 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1308 // Makes modifie or unmodified
1309 void wxTextCtrl::MarkDirty()
1314 void wxTextCtrl::DiscardEdits()
1319 int wxTextCtrl::GetNumberOfLines() const
1322 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1326 long wxTextCtrl::XYToPosition(long x
, long y
) const
1330 long lastpos
= GetLastPosition() ;
1332 // TODO find a better implementation : while we can get the
1333 // line metrics of a certain line, we don't get its starting
1334 // position, so it would probably be rather a binary search
1335 // for the start position
1338 int lastHeight
= 0 ;
1341 for ( n
= 0 ; n
<= lastpos
; ++n
)
1343 if ( y
== ypos
&& x
== xpos
)
1346 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1348 if ( curpt
.v
> lastHeight
)
1353 lastHeight
= curpt
.v
;
1362 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1366 long lastpos
= GetLastPosition() ;
1371 if ( pos
<= lastpos
)
1373 // TODO find a better implementation : while we can get the
1374 // line metrics of a certain line, we don't get its starting
1375 // position, so it would probably be rather a binary search
1376 // for the start position
1379 int lastHeight
= 0 ;
1382 for ( n
= 0 ; n
<= pos
; ++n
)
1384 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1386 if ( curpt
.v
> lastHeight
)
1391 lastHeight
= curpt
.v
;
1396 if ( y
) *y
= ypos
;
1397 if ( x
) *x
= xpos
;
1403 void wxTextCtrl::ShowPosition(long pos
)
1405 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1409 TXNOffset selstart
, selend
;
1410 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1411 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1412 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1413 //TODO use HIPoints for 10.3 and above
1414 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1416 OSErr theErr
= noErr
;
1417 SInt32 dv
= desired
.v
- current
.v
;
1418 SInt32 dh
= desired
.h
- current
.h
;
1419 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1420 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1421 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1427 int wxTextCtrl::GetLineLength(long lineNo
) const
1430 if ( lineNo
< GetNumberOfLines() )
1432 // TODO find a better implementation : while we can get the
1433 // line metrics of a certain line, we don't get its starting
1434 // position, so it would probably be rather a binary search
1435 // for the start position
1438 int lastHeight
= 0 ;
1439 long lastpos
= GetLastPosition() ;
1442 for ( n
= 0 ; n
<= lastpos
; ++n
)
1444 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1446 if ( curpt
.v
> lastHeight
)
1448 if ( ypos
== lineNo
)
1454 lastHeight
= curpt
.v
;
1464 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1468 wxString content
= GetValue() ;
1470 if ( lineNo
< GetNumberOfLines() )
1472 // TODO find a better implementation : while we can get the
1473 // line metrics of a certain line, we don't get its starting
1474 // position, so it would probably be rather a binary search
1475 // for the start position
1478 int lastHeight
= 0 ;
1479 long lastpos
= GetLastPosition() ;
1482 for ( n
= 0 ; n
<= lastpos
; ++n
)
1484 TXNOffsetToPoint( (TXNObject
) m_macTXN
, n
, &curpt
);
1486 if ( curpt
.v
> lastHeight
)
1488 if ( ypos
== lineNo
)
1494 lastHeight
= curpt
.v
;
1498 if ( ypos
== lineNo
)
1499 line
+= content
[n
] ;
1512 void wxTextCtrl::Command(wxCommandEvent
& event
)
1514 SetValue (event
.GetString());
1515 ProcessCommand (event
);
1518 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1520 // By default, load the first file into the text window.
1521 if (event
.GetNumberOfFiles() > 0)
1523 LoadFile(event
.GetFiles()[0]);
1527 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1529 int key
= event
.GetKeyCode() ;
1530 bool eat_key
= false ;
1532 if ( key
== 'c' && event
.MetaDown() )
1539 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1540 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1541 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1548 // assume that any key not processed yet is going to modify the control
1551 if ( key
== 'v' && event
.MetaDown() )
1557 if ( key
== 'x' && event
.MetaDown() )
1566 if (m_windowStyle
& wxPROCESS_ENTER
)
1568 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1569 event
.SetEventObject( this );
1570 event
.SetString( GetValue() );
1571 if ( GetEventHandler()->ProcessEvent(event
) )
1574 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1576 wxWindow
*parent
= GetParent();
1577 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1578 parent
= parent
->GetParent() ;
1580 if ( parent
&& parent
->GetDefaultItem() )
1582 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1584 if ( def
&& def
->IsEnabled() )
1586 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1587 event
.SetEventObject(def
);
1588 def
->Command(event
);
1593 // this will make wxWindows eat the ENTER key so that
1594 // we actually prevent line wrapping in a single line
1602 // always produce navigation event - even if we process TAB
1603 // ourselves the fact that we got here means that the user code
1604 // decided to skip processing of this TAB - probably to let it
1605 // do its default job.
1607 wxNavigationKeyEvent eventNav
;
1608 eventNav
.SetDirection(!event
.ShiftDown());
1609 eventNav
.SetWindowChange(event
.ControlDown());
1610 eventNav
.SetEventObject(this);
1612 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1623 // perform keystroke handling
1624 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1625 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1629 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1631 EventRecord
*ev
= &rec
;
1634 keychar
= short(ev
->message
& charCodeMask
);
1635 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1637 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1641 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1642 key
== WXK_RETURN
||
1643 key
== WXK_DELETE
||
1646 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1647 event1
.SetString( GetValue() ) ;
1648 event1
.SetEventObject( this );
1649 wxPostEvent(GetEventHandler(),event1
);
1653 // ----------------------------------------------------------------------------
1654 // standard handlers for standard edit menu events
1655 // ----------------------------------------------------------------------------
1657 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1662 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1667 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1672 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1677 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1682 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1684 event
.Enable( CanCut() );
1687 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1689 event
.Enable( CanCopy() );
1692 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1694 event
.Enable( CanPaste() );
1697 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1699 event
.Enable( CanUndo() );
1702 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1704 event
.Enable( CanRedo() );
1707 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1712 // user pane implementation
1714 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1718 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1720 return kControlNoPart
;
1723 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1725 return kControlNoPart
;
1728 void wxTextCtrl::MacControlUserPaneIdleProc()
1732 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1734 return kControlNoPart
;
1737 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1741 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1743 return kControlNoPart
;
1746 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)