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 SetBackgroundColour( *wxWHITE
) ;
776 tback
.bgType
= kTXNBackgroundTypeRGB
;
777 tback
.bg
.color
= MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
778 TXNSetBackground( (TXNObject
) m_macTXN
, &tback
);
780 if ( m_windowStyle
& wxTE_READONLY
)
782 SetEditable( false ) ;
788 void wxTextCtrl::MacVisibilityChanged()
790 MLTESetObjectVisibility((STPTextPaneVars
*) m_macTXNvars
, MacIsReallyShown() , GetWindowStyle() ) ;
791 if ( !MacIsReallyShown() )
792 InvalWindowRect( GetControlOwner( (ControlHandle
) m_macControl
) , &((STPTextPaneVars
*)m_macTXNvars
)->fRBounds
) ;
796 void wxTextCtrl::MacEnabledStateChanged()
801 wxString
wxTextCtrl::GetValue() const
810 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNUnicodeTextData
);
818 actualSize
= GetHandleSize( theText
) / sizeof( UniChar
) ;
819 if ( actualSize
> 0 )
822 #if SIZEOF_WCHAR_T == 2
823 ptr
= new wxChar
[actualSize
+ 1 ] ;
824 wxStrncpy( ptr
, (wxChar
*) *theText
, actualSize
) ;
827 SetHandleSize( theText
, ( actualSize
+ 1 ) * sizeof( UniChar
) ) ;
829 (((UniChar
*)*theText
)[actualSize
]) = 0 ;
830 wxMBConvUTF16BE converter
;
831 size_t noChars
= converter
.MB2WC( NULL
, (const char*)*theText
, 0 ) ;
832 ptr
= new wxChar
[noChars
+ 1] ;
834 noChars
= converter
.MB2WC( ptr
, (const char*)*theText
, noChars
) ;
838 ptr
[actualSize
] = 0 ;
839 result
= wxString( ptr
) ;
842 DisposeHandle( theText
) ;
846 err
= TXNGetDataEncoded( ((TXNObject
) m_macTXN
), kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
854 actualSize
= GetHandleSize( theText
) ;
855 if ( actualSize
> 0 )
858 result
= wxString( *theText
, wxConvLocal
, actualSize
) ;
861 DisposeHandle( theText
) ;
865 wxMacConvertNewlines10To13( &result
) ;
869 void wxTextCtrl::GetSelection(long* from
, long* to
) const
871 TXNGetSelection( (TXNObject
) m_macTXN
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
874 void wxTextCtrl::SetValue(const wxString
& str
)
877 if ( GetValue() == str
)
881 wxMacConvertNewlines13To10( &st
) ;
884 wxMacWindowClipper
c( this ) ;
885 bool formerEditable
= m_editable
;
886 if ( !formerEditable
)
889 // otherwise scrolling might have problems ?
890 TPUpdateVisibility( ( (STPTextPaneVars
*)m_macTXNvars
)->fUserPaneRec
) ;
891 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNStartOffset
, kTXNEndOffset
) ;
892 TXNSetSelection( (TXNObject
) m_macTXN
, 0, 0);
893 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
894 if ( !formerEditable
)
895 SetEditable(formerEditable
) ;
899 void wxTextCtrl::SetMaxLength(unsigned long len
)
904 bool wxTextCtrl::SetFont( const wxFont
& font
)
906 if ( !wxTextCtrlBase::SetFont( font
) )
909 wxMacWindowClipper
c( this ) ;
910 bool formerEditable
= m_editable
;
911 if ( !formerEditable
)
914 TXNTypeAttributes typeAttr
[4] ;
915 Str255 fontName
= "\pMonaco" ;
916 SInt16 fontSize
= 12 ;
917 Style fontStyle
= normal
;
918 int attrCounter
= 0 ;
920 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
921 fontSize
= font
.MacGetFontSize() ;
922 fontStyle
= font
.MacGetFontStyle() ;
924 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
925 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
926 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
927 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
928 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
929 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
930 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
931 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
932 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
935 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
936 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
937 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
938 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
941 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, kTXNStartOffset
,kTXNEndOffset
) );
943 if ( !formerEditable
)
944 SetEditable(formerEditable
) ;
948 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
950 bool formerEditable
= m_editable
;
951 if ( !formerEditable
)
953 TXNTypeAttributes typeAttr
[4] ;
954 Str255 fontName
= "\pMonaco" ;
955 SInt16 fontSize
= 12 ;
956 Style fontStyle
= normal
;
958 int attrCounter
= 0 ;
959 if ( style
.HasFont() )
961 const wxFont
&font
= style
.GetFont() ;
962 wxMacStringToPascal( font
.GetFaceName() , fontName
) ;
963 fontSize
= font
.GetPointSize() ;
964 if ( font
.GetUnderlined() )
965 fontStyle
|= underline
;
966 if ( font
.GetWeight() == wxBOLD
)
968 if ( font
.GetStyle() == wxITALIC
)
969 fontStyle
|= italic
;
971 typeAttr
[attrCounter
].tag
= kTXNQDFontNameAttribute
;
972 typeAttr
[attrCounter
].size
= kTXNQDFontNameAttributeSize
;
973 typeAttr
[attrCounter
].data
.dataPtr
= (void*) fontName
;
974 typeAttr
[attrCounter
+1].tag
= kTXNQDFontSizeAttribute
;
975 typeAttr
[attrCounter
+1].size
= kTXNFontSizeAttributeSize
;
976 typeAttr
[attrCounter
+1].data
.dataValue
= (fontSize
<< 16) ;
977 typeAttr
[attrCounter
+2].tag
= kTXNQDFontStyleAttribute
;
978 typeAttr
[attrCounter
+2].size
= kTXNQDFontStyleAttributeSize
;
979 typeAttr
[attrCounter
+2].data
.dataValue
= fontStyle
;
983 if ( style
.HasTextColour() )
985 typeAttr
[attrCounter
].tag
= kTXNQDFontColorAttribute
;
986 typeAttr
[attrCounter
].size
= kTXNQDFontColorAttributeSize
;
987 typeAttr
[attrCounter
].data
.dataPtr
= (void*) &color
;
988 color
= MAC_WXCOLORREF(style
.GetTextColour().GetPixel()) ;
992 if ( attrCounter
> 0 )
994 verify_noerr( TXNSetTypeAttributes ((TXNObject
)m_macTXN
, attrCounter
, typeAttr
, start
,end
) );
996 if ( !formerEditable
)
997 SetEditable(formerEditable
) ;
1002 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr
& style
)
1004 wxTextCtrlBase::SetDefaultStyle( style
) ;
1005 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1009 // Clipboard operations
1010 void wxTextCtrl::Copy()
1014 ClearCurrentScrap();
1015 TXNCopy((TXNObject
)m_macTXN
);
1016 TXNConvertToPublicScrap();
1020 void wxTextCtrl::Cut()
1024 ClearCurrentScrap();
1025 TXNCut((TXNObject
)m_macTXN
);
1026 TXNConvertToPublicScrap();
1028 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1029 event
.SetString( GetValue() ) ;
1030 event
.SetEventObject( this );
1031 GetEventHandler()->ProcessEvent(event
);
1035 void wxTextCtrl::Paste()
1040 TXNConvertFromPublicScrap();
1041 TXNPaste((TXNObject
)m_macTXN
);
1042 SetStyle( kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, GetDefaultStyle() ) ;
1044 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1045 event
.SetString( GetValue() ) ;
1046 event
.SetEventObject( this );
1047 GetEventHandler()->ProcessEvent(event
);
1051 bool wxTextCtrl::CanCopy() const
1053 // Can copy if there's a selection
1055 GetSelection(& from
, & to
);
1056 return (from
!= to
);
1059 bool wxTextCtrl::CanCut() const
1061 if ( !IsEditable() )
1065 // Can cut if there's a selection
1067 GetSelection(& from
, & to
);
1068 return (from
!= to
);
1071 bool wxTextCtrl::CanPaste() const
1076 return TXNIsScrapPastable() ;
1079 void wxTextCtrl::SetEditable(bool editable
)
1081 if ( editable
!= m_editable
)
1083 m_editable
= editable
;
1085 TXNControlTag tag
[] = { kTXNIOPrivilegesTag
} ;
1086 TXNControlData data
[] = { { editable
? kTXNReadWrite
: kTXNReadOnly
} } ;
1087 TXNSetTXNObjectControls( (TXNObject
) m_macTXN
, false , sizeof(tag
) / sizeof (TXNControlTag
) , tag
, data
) ;
1092 void wxTextCtrl::SetInsertionPoint(long pos
)
1094 SetSelection( pos
, pos
) ;
1097 void wxTextCtrl::SetInsertionPointEnd()
1099 long pos
= GetLastPosition();
1100 SetInsertionPoint(pos
);
1103 long wxTextCtrl::GetInsertionPoint() const
1106 GetSelection( &begin
, &end
) ;
1110 long wxTextCtrl::GetLastPosition() const
1114 OSErr err
= TXNGetDataEncoded( (TXNObject
) m_macTXN
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1122 actualsize
= GetHandleSize( theText
) ;
1123 DisposeHandle( theText
) ;
1128 void wxTextCtrl::Replace(long from
, long to
, const wxString
& str
)
1130 wxString value
= str
;
1131 wxMacConvertNewlines13To10( &value
) ;
1133 bool formerEditable
= m_editable
;
1134 if ( !formerEditable
)
1136 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1137 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1138 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, str
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1139 if ( !formerEditable
)
1140 SetEditable( formerEditable
) ;
1145 void wxTextCtrl::Remove(long from
, long to
)
1147 bool formerEditable
= m_editable
;
1148 if ( !formerEditable
)
1150 TXNSetSelection( ((TXNObject
) m_macTXN
) , from
, to
) ;
1151 TXNClear( ((TXNObject
) m_macTXN
) ) ;
1152 if ( !formerEditable
)
1153 SetEditable( formerEditable
) ;
1158 void wxTextCtrl::SetSelection(long from
, long to
)
1160 STPTextPaneVars
*varsp
= (STPTextPaneVars
*) m_macTXNvars
;
1161 /* and our drawing environment as the operation
1162 may force a redraw in the text area. */
1163 SetPort(varsp
->fDrawingEnvironment
);
1164 /* change the selection */
1165 if ((from
== -1) && (to
== -1))
1166 TXNSelectAll((TXNObject
) m_macTXN
);
1168 TXNSetSelection( varsp
->fTXNRec
, from
, to
);
1169 TXNShowSelection( (TXNObject
) m_macTXN
, kTXNShowStart
);
1172 bool wxTextCtrl::LoadFile(const wxString
& file
)
1174 if ( wxTextCtrlBase::LoadFile(file
) )
1182 void wxTextCtrl::WriteText(const wxString
& str
)
1185 wxMacConvertNewlines13To10( &st
) ;
1187 bool formerEditable
= m_editable
;
1188 if ( !formerEditable
)
1190 long start
, end
, dummy
;
1191 GetSelection( &start
, &dummy
) ;
1192 SetTXNData( (STPTextPaneVars
*)m_macTXNvars
, (TXNObject
) m_macTXN
, st
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
) ;
1193 GetSelection( &dummy
, &end
) ;
1194 SetStyle( start
, end
, GetDefaultStyle() ) ;
1195 if ( !formerEditable
)
1196 SetEditable( formerEditable
) ;
1198 MacRedrawControl() ;
1201 void wxTextCtrl::AppendText(const wxString
& text
)
1203 SetInsertionPointEnd();
1207 void wxTextCtrl::Clear()
1209 bool formerEditable
= m_editable
;
1210 if ( !formerEditable
)
1212 TXNSetSelection( (TXNObject
)m_macTXN
, kTXNStartOffset
, kTXNEndOffset
) ;
1213 TXNClear((TXNObject
)m_macTXN
);
1215 if ( !formerEditable
)
1216 SetEditable( formerEditable
) ;
1221 bool wxTextCtrl::IsModified() const
1226 bool wxTextCtrl::IsEditable() const
1228 return IsEnabled() && m_editable
;
1231 bool wxTextCtrl::AcceptsFocus() const
1233 // we don't want focus if we can't be edited
1234 return /*IsEditable() && */ wxControl::AcceptsFocus();
1237 wxSize
wxTextCtrl::DoGetBestSize() const
1243 switch( m_windowVariant
)
1245 case wxWINDOW_VARIANT_NORMAL
:
1248 case wxWINDOW_VARIANT_SMALL
:
1251 case wxWINDOW_VARIANT_MINI
:
1259 if ( m_windowStyle
& wxTE_MULTILINE
)
1264 return wxSize(wText
, hText
);
1267 // ----------------------------------------------------------------------------
1269 // ----------------------------------------------------------------------------
1271 void wxTextCtrl::Undo()
1275 TXNUndo((TXNObject
)m_macTXN
);
1279 void wxTextCtrl::Redo()
1283 TXNRedo((TXNObject
)m_macTXN
);
1287 bool wxTextCtrl::CanUndo() const
1289 if ( !IsEditable() )
1293 return TXNCanUndo((TXNObject
)m_macTXN
,NULL
);
1296 bool wxTextCtrl::CanRedo() const
1298 if ( !IsEditable() )
1302 return TXNCanRedo((TXNObject
)m_macTXN
,NULL
);
1305 // Makes modifie or unmodified
1306 void wxTextCtrl::MarkDirty()
1311 void wxTextCtrl::DiscardEdits()
1316 int wxTextCtrl::GetNumberOfLines() const
1319 TXNGetLineCount((TXNObject
)m_macTXN
, &lines
) ;
1323 long wxTextCtrl::XYToPosition(long x
, long y
) const
1329 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
1334 void wxTextCtrl::ShowPosition(long pos
)
1336 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1340 TXNOffset selstart
, selend
;
1341 TXNGetSelection( (TXNObject
) m_macTXN
, &selstart
, &selend
) ;
1342 TXNOffsetToPoint( (TXNObject
) m_macTXN
, selstart
, ¤t
);
1343 TXNOffsetToPoint( (TXNObject
) m_macTXN
, pos
, &desired
);
1344 //TODO use HIPoints for 10.3 and above
1345 if ( (UInt32
) TXNScroll
!= (UInt32
) kUnresolvedCFragSymbolAddress
)
1347 OSErr theErr
= noErr
;
1348 SInt32 dv
= desired
.v
- current
.v
;
1349 SInt32 dh
= desired
.h
- current
.h
;
1350 TXNShowSelection( (TXNObject
) m_macTXN
, true ) ;
1351 theErr
= TXNScroll( (TXNObject
) m_macTXN
, kTXNScrollUnitsInPixels
, kTXNScrollUnitsInPixels
, &dv
, &dh
);
1352 wxASSERT_MSG( theErr
== noErr
, _T("TXNScroll returned an error!") );
1358 int wxTextCtrl::GetLineLength(long lineNo
) const
1360 // TODO change this if possible to reflect real lines
1361 wxString content
= GetValue() ;
1365 for (size_t i
= 0; i
< content
.Length() ; i
++)
1367 if (count
== lineNo
)
1369 // Count chars in line then
1371 for (size_t j
= i
; j
< content
.Length(); j
++)
1374 if (content
[j
] == '\n') return count
;
1379 if (content
[i
] == '\n') count
++;
1384 wxString
wxTextCtrl::GetLineText(long lineNo
) const
1386 // TODO change this if possible to reflect real lines
1387 wxString content
= GetValue() ;
1391 for (size_t i
= 0; i
< content
.Length() ; i
++)
1393 if (count
== lineNo
)
1395 // Add chars in line then
1398 for (size_t j
= i
; j
< content
.Length(); j
++)
1400 if (content
[j
] == '\n')
1408 if (content
[i
] == '\n') count
++;
1410 return wxEmptyString
;
1417 void wxTextCtrl::Command(wxCommandEvent
& event
)
1419 SetValue (event
.GetString());
1420 ProcessCommand (event
);
1423 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
1425 // By default, load the first file into the text window.
1426 if (event
.GetNumberOfFiles() > 0)
1428 LoadFile(event
.GetFiles()[0]);
1432 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
1434 int key
= event
.GetKeyCode() ;
1435 bool eat_key
= false ;
1437 if ( key
== 'c' && event
.MetaDown() )
1444 if ( !IsEditable() && key
!= WXK_LEFT
&& key
!= WXK_RIGHT
&& key
!= WXK_DOWN
&& key
!= WXK_UP
&& key
!= WXK_TAB
&&
1445 !( key
== WXK_RETURN
&& ( (m_windowStyle
& wxPROCESS_ENTER
) || (m_windowStyle
& wxTE_MULTILINE
) ) )
1446 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1453 // assume that any key not processed yet is going to modify the control
1456 if ( key
== 'v' && event
.MetaDown() )
1462 if ( key
== 'x' && event
.MetaDown() )
1471 if (m_windowStyle
& wxPROCESS_ENTER
)
1473 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1474 event
.SetEventObject( this );
1475 event
.SetString( GetValue() );
1476 if ( GetEventHandler()->ProcessEvent(event
) )
1479 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1481 wxWindow
*parent
= GetParent();
1482 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
1483 parent
= parent
->GetParent() ;
1485 if ( parent
&& parent
->GetDefaultItem() )
1487 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
1489 if ( def
&& def
->IsEnabled() )
1491 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
1492 event
.SetEventObject(def
);
1493 def
->Command(event
);
1498 // this will make wxWindows eat the ENTER key so that
1499 // we actually prevent line wrapping in a single line
1507 // always produce navigation event - even if we process TAB
1508 // ourselves the fact that we got here means that the user code
1509 // decided to skip processing of this TAB - probably to let it
1510 // do its default job.
1512 wxNavigationKeyEvent eventNav
;
1513 eventNav
.SetDirection(!event
.ShiftDown());
1514 eventNav
.SetWindowChange(event
.ControlDown());
1515 eventNav
.SetEventObject(this);
1517 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
1528 // perform keystroke handling
1529 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
1530 CallNextEventHandler((EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() , (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
1534 if ( wxMacConvertEventToRecord( (EventRef
) wxTheApp
->MacGetCurrentEvent() , &rec
) )
1536 EventRecord
*ev
= &rec
;
1539 keychar
= short(ev
->message
& charCodeMask
);
1540 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
1542 ::HandleControlKey( (ControlRef
) m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
1546 if ( ( key
>= 0x20 && key
< WXK_START
) ||
1547 key
== WXK_RETURN
||
1548 key
== WXK_DELETE
||
1551 wxCommandEvent
event1(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
1552 event1
.SetString( GetValue() ) ;
1553 event1
.SetEventObject( this );
1554 wxPostEvent(GetEventHandler(),event1
);
1558 // ----------------------------------------------------------------------------
1559 // standard handlers for standard edit menu events
1560 // ----------------------------------------------------------------------------
1562 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
1567 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1572 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1577 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
1582 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
1587 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
1589 event
.Enable( CanCut() );
1592 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
1594 event
.Enable( CanCopy() );
1597 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
1599 event
.Enable( CanPaste() );
1602 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
1604 event
.Enable( CanUndo() );
1607 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
1609 event
.Enable( CanRedo() );
1612 bool wxTextCtrl::MacSetupCursor( const wxPoint
& pt
)
1617 // user pane implementation
1619 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part
)
1623 wxInt16
wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
1625 return kControlNoPart
;
1628 wxInt16
wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
1630 return kControlNoPart
;
1633 void wxTextCtrl::MacControlUserPaneIdleProc()
1637 wxInt16
wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
1639 return kControlNoPart
;
1642 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating
)
1646 wxInt16
wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action
)
1648 return kControlNoPart
;
1651 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info
)