]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/textctrl.cpp
e99c566bdd7bfc23007513682e591bc0029ef2af
[wxWidgets.git] / src / mac / carbon / textctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: textctrl.cpp
3 // Purpose: wxTextCtrl
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "textctrl.h"
14 #endif
15
16 #include "wx/defs.h"
17
18 #if wxUSE_TEXTCTRL
19
20 #ifdef __DARWIN__
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #else
24 #include <stat.h>
25 #endif
26
27 #include "wx/msgdlg.h"
28
29 #if wxUSE_STD_IOSTREAM
30 #if wxUSE_IOSTREAMH
31 #include <fstream.h>
32 #else
33 #include <fstream>
34 #endif
35 #endif
36
37 #include "wx/app.h"
38 #include "wx/dc.h"
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"
46 #include "wx/utils.h"
47
48 #if defined(__BORLANDC__) && !defined(__WIN32__)
49 #include <alloc.h>
50 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
51 #include <malloc.h>
52 #endif
53
54 #ifndef __DARWIN__
55 #include <Scrap.h>
56 #endif
57 #include <MacTextEditor.h>
58 #include <ATSUnicode.h>
59 #include <TextCommon.h>
60 #include <TextEncodingConverter.h>
61 #include "wx/mac/uma.h"
62
63 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
64 #if TARGET_API_MAC_OSX
65 #define wxMAC_USE_MLTE 1
66 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
67 #define wxMAC_USE_MLTE_HIVIEW 1
68 #else
69 #define wxMAC_USE_MLTE_HIVIEW 0
70 #endif
71 #else
72 // there is no unicodetextctrl on classic, and hopefully MLTE works better there
73 #define wxMAC_USE_MLTE 1
74 #define wxMAC_USE_MLTE_HIVIEW 0
75 #endif
76
77 #if wxMAC_USE_MLTE
78
79 TXNFrameOptions FrameOptionsFromWXStyle( long wxStyle )
80 {
81 TXNFrameOptions frameOptions =
82 kTXNDontDrawCaretWhenInactiveMask ;
83 if ( ! ( wxStyle & wxTE_NOHIDESEL ) )
84 frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ;
85
86 if ( wxStyle & wxTE_MULTILINE )
87 {
88 if ( ! ( wxStyle & wxTE_DONTWRAP ) )
89 frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
90 else
91 {
92 frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
93 frameOptions |= kTXNWantHScrollBarMask ;
94 }
95
96 if ( !(wxStyle & wxTE_NO_VSCROLL ) )
97 frameOptions |= kTXNWantVScrollBarMask ;
98 }
99 else
100 frameOptions |= kTXNSingleLineOnlyMask ;
101 return frameOptions ;
102 }
103
104 void AdjustAttributesFromWXStyle( TXNObject txn , long wxStyle , bool visible )
105 {
106 TXNControlTag iControlTags[3] = { kTXNDoFontSubstitution, kTXNWordWrapStateTag };
107 TXNControlData iControlData[3] = { {false}, {kTXNNoAutoWrap} };
108 int toptag = 2 ;
109 #if TARGET_API_MAC_OSX
110 iControlTags[2] = kTXNVisibilityTag ;
111 iControlData[2].uValue = visible ;
112 toptag++ ;
113 #endif
114
115 if ( wxStyle & wxTE_MULTILINE )
116 {
117 if (wxStyle & wxTE_DONTWRAP)
118 iControlData[1].uValue = kTXNNoAutoWrap ;
119 else
120 iControlData[1].uValue = kTXNAutoWrap ;
121
122 }
123 verify_noerr( TXNSetTXNObjectControls( txn, false, toptag,
124 iControlTags, iControlData )) ;
125
126 Str255 fontName ;
127 SInt16 fontSize ;
128 Style fontStyle ;
129
130 GetThemeFont(kThemeSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
131
132 TXNTypeAttributes typeAttr[] =
133 {
134 { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } ,
135 { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } ,
136 { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } ,
137 } ;
138
139 verify_noerr( TXNSetTypeAttributes (txn, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr,
140 kTXNStartOffset,
141 kTXNEndOffset) );
142
143 }
144
145 #if !wxMAC_USE_MLTE_HIVIEW
146
147 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
148 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
149 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
150 // an alternate path for carbon key events that routes automatically into the same wx flow of events
151
152 /* part codes */
153
154 /* kmUPTextPart is the part code we return to indicate the user has clicked
155 in the text area of our control */
156 #define kmUPTextPart 1
157
158
159 /* routines for using existing user pane controls.
160 These routines are useful for cases where you would like to use an
161 existing user pane control in, say, a dialog window as a scrolling
162 text edit field.*/
163
164 /* Utility Routines */
165
166 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
167 routine. In our focus switching routine this part code is understood
168 as meaning 'the user has clicked in the control and we need to switch
169 the current focus to ourselves before we can continue'. */
170 #define kUserClickedToFocusPart 100
171
172 /* STPTextPaneVars is a structure used for storing the the mUP Control's
173 internal variables and state information. A handle to this record is
174 stored in the pane control's reference value field using the
175 SetControlReference routine. */
176
177 typedef struct {
178 /* OS records referenced */
179 TXNObject fTXNRec; /* the txn record */
180 TXNFrameID fTXNFrame; /* the txn frame ID */
181 ControlRef fUserPaneRec; /* handle to the user pane control */
182 WindowPtr fOwner; /* window containing control */
183 GrafPtr fDrawingEnvironment; /* grafport where control is drawn */
184 /* flags */
185 Boolean fInFocus; /* true while the focus rect is drawn around the control */
186 Boolean fIsActive; /* true while the control is drawn in the active state */
187 Boolean fTXNObjectActive; /* reflects the activation state of the text edit record */
188 Boolean fFocusDrawState; /* true if focus is drawn (default: true) */
189 /* calculated locations */
190 Rect fRBounds; /* control bounds */
191 Rect fRTextArea; /* area where the text is drawn */
192 Rect fRFocusOutline; /* rectangle used to draw the focus box */
193 Rect fRTextOutline; /* rectangle used to draw the border */
194 RgnHandle fRTextOutlineRegion; /* background region for the text, erased before calling TEUpdate */
195 /* our focus advance override routine */
196 EventHandlerUPP handlerUPP;
197 EventHandlerRef handlerRef;
198 bool fNoBorders ;
199 bool fMultiline ;
200 bool fVisible ;
201 } STPTextPaneVars;
202
203 /* mUPOpenControl initializes a user pane control so it will be drawn
204 and will behave as a scrolling text edit field inside of a window.
205 This routine performs all of the initialization steps necessary,
206 except it does not create the user pane control itself. theControl
207 should refer to a user pane control that you have either created
208 yourself or extracted from a dialog's control heirarchy using
209 the GetDialogItemAsControl routine. */
210 OSStatus mUPOpenControl(STPTextPaneVars* &handle, ControlRef theControl, long wxStyle);
211
212
213
214
215 /* Univerals Procedure Pointer variables used by the
216 mUP Control. These variables are set up
217 the first time that mUPOpenControl is called. */
218 ControlUserPaneDrawUPP gTPDrawProc = NULL;
219 ControlUserPaneHitTestUPP gTPHitProc = NULL;
220 ControlUserPaneTrackingUPP gTPTrackProc = NULL;
221 ControlUserPaneIdleUPP gTPIdleProc = NULL;
222 ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
223 ControlUserPaneActivateUPP gTPActivateProc = NULL;
224 ControlUserPaneFocusUPP gTPFocusProc = NULL;
225
226 // one place for calculating all
227 static void TPCalculateBounds(STPTextPaneVars *varsp, const Rect& bounds)
228 {
229 SetRect(&varsp->fRBounds, bounds.left, bounds.top, bounds.right, bounds.bottom);
230 SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
231 // eventually make TextOutline inset 1,1
232 SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
233 if ( !varsp->fNoBorders )
234 {
235 SetRect(&varsp->fRTextArea, bounds.left + 2 , bounds.top + (varsp->fMultiline ? 0 : 2) ,
236 bounds.right - (varsp->fMultiline ? 0 : 2), bounds.bottom - (varsp->fMultiline ? 0 : 2));
237 }
238 else
239 {
240 SetRect(&varsp->fRTextArea, bounds.left , bounds.top ,
241 bounds.right, bounds.bottom);
242 }
243 }
244
245 OSStatus MLTESetObjectVisibility( STPTextPaneVars *varsp, Boolean vis , long wxStyle)
246 {
247 OSStatus err = noErr ;
248 #if TARGET_API_MAC_OSX
249 TXNControlTag iControlTags[1] = { kTXNVisibilityTag };
250 TXNControlData iControlData[1] = {{ vis }};
251 err = ::TXNSetTXNObjectControls( varsp->fTXNRec, false, 1, iControlTags, iControlData );
252 #endif
253 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(varsp->fUserPaneRec);
254 if ( vis && textctrl )
255 {
256 Rect bounds ;
257 UMAGetControlBoundsInWindowCoords( varsp->fUserPaneRec, &bounds);
258 TPCalculateBounds( varsp , bounds ) ;
259 wxMacWindowClipper cl(textctrl) ;
260 TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left,
261 varsp->fRTextArea.bottom, varsp->fRTextArea.right, varsp->fTXNFrame);
262 TXNShowSelection( varsp->fTXNRec, kTXNShowStart);
263 }
264 return err ;
265 }
266
267 // make sure we don't miss changes as carbon events are not available for these under classic
268 static void TPUpdateVisibility(ControlRef theControl) {
269 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
270 if ( textctrl == NULL )
271 return ;
272
273 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
274
275 Rect bounds ;
276 UMAGetControlBoundsInWindowCoords(theControl, &bounds);
277 if ( textctrl->MacIsReallyShown() != varsp->fVisible )
278 {
279 // invalidate old position
280 // InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
281 varsp->fVisible = textctrl->MacIsReallyShown() ;
282 }
283 if ( !EqualRect( &bounds , &varsp->fRBounds ) )
284 {
285 // old position
286 Rect oldBounds = varsp->fRBounds ;
287 TPCalculateBounds( varsp , bounds ) ;
288 // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places
289 if ( varsp->fVisible )
290 {
291 wxMacWindowClipper cl(textctrl) ;
292 TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left,
293 varsp->fRTextArea.bottom, varsp->fRTextArea.right, varsp->fTXNFrame);
294 }
295 InvalWindowRect( GetControlOwner( theControl ) , &oldBounds ) ;
296 InvalWindowRect( GetControlOwner( theControl ) , &varsp->fRBounds ) ;
297 }
298 }
299
300 // make correct activations
301 static void TPActivatePaneText(STPTextPaneVars *varsp, Boolean setActive) {
302
303 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(varsp->fUserPaneRec);
304 if (varsp->fTXNObjectActive != setActive && textctrl->MacIsReallyShown() )
305 {
306 varsp->fTXNObjectActive = setActive;
307 TXNActivate(varsp->fTXNRec, varsp->fTXNFrame, varsp->fTXNObjectActive);
308 if (varsp->fInFocus)
309 TXNFocus( varsp->fTXNRec, varsp->fTXNObjectActive);
310 }
311 }
312
313 // update focus outlines
314 static void TPRedrawFocusOutline(STPTextPaneVars *varsp) {
315
316 /* state changed */
317 if (varsp->fFocusDrawState != (varsp->fIsActive && varsp->fInFocus))
318 {
319 varsp->fFocusDrawState = (varsp->fIsActive && varsp->fInFocus);
320 DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fFocusDrawState);
321 }
322 }
323
324 // update TXN focus state
325 static void TPFocusPaneText(STPTextPaneVars *varsp, Boolean setFocus) {
326 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(varsp->fUserPaneRec);
327
328 if (varsp->fInFocus != setFocus && textctrl->MacIsReallyShown()) {
329 varsp->fInFocus = setFocus;
330 TXNFocus( varsp->fTXNRec, varsp->fInFocus);
331 }
332 }
333
334 // draw the control
335 static pascal void TPPaneDrawProc(ControlRef theControl, ControlPartCode thePart) {
336 /* set up our globals */
337
338 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
339 if ( textctrl == NULL )
340 return ;
341 TPUpdateVisibility( theControl ) ;
342
343 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
344 if ( textctrl->MacIsReallyShown() )
345 {
346 wxMacWindowClipper clipper( textctrl ) ;
347 TXNDraw(varsp->fTXNRec, NULL);
348 if ( !varsp->fNoBorders )
349 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
350 TPRedrawFocusOutline( varsp ) ;
351 }
352
353 }
354
355
356 /* TPPaneHitTestProc is called when the control manager would
357 like to determine what part of the control the mouse resides over.
358 We also call this routine from our tracking proc to determine how
359 to handle mouse clicks. */
360 static pascal ControlPartCode TPPaneHitTestProc(ControlRef theControl, Point where) {
361 ControlPartCode result;
362 /* set up our locals and lock down our globals*/
363 result = 0;
364 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
365 if ( textctrl == NULL )
366 return 0 ;
367 TPUpdateVisibility( theControl ) ;
368 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
369 if (textctrl->MacIsReallyShown() )
370 {
371 if (PtInRect(where, &varsp->fRBounds))
372 result = kmUPTextPart;
373 else
374 result = 0;
375 }
376 return result;
377 }
378
379
380
381
382
383 /* TPPaneTrackingProc is called when the mouse is being held down
384 over our control. This routine handles clicks in the text area
385 and in the scroll bar. */
386 static pascal ControlPartCode TPPaneTrackingProc(ControlRef theControl, Point startPt, ControlActionUPP actionProc) {
387
388 ControlPartCode partCodeResult;
389 /* make sure we have some variables... */
390 partCodeResult = 0;
391 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
392 if ( textctrl == NULL )
393 return 0;
394 TPUpdateVisibility( theControl ) ;
395 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
396 if (textctrl->MacIsReallyShown() )
397 {
398 /* we don't do any of these functions unless we're in focus */
399 if ( ! varsp->fInFocus) {
400 WindowPtr owner;
401 owner = GetControlOwner(theControl);
402 ClearKeyboardFocus(owner);
403 SetKeyboardFocus(owner, theControl, kUserClickedToFocusPart);
404 }
405 /* find the location for the click */
406 // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
407 if ( textctrl->MacGetTopLevelWindow()->MacUsesCompositing() )
408 {
409 int x = 0 , y = 0 ;
410 textctrl->MacClientToRootWindow( &x , &y ) ;
411 startPt.h += x ;
412 startPt.v += y ;
413 }
414
415 switch (TPPaneHitTestProc(theControl, startPt))
416 {
417
418 /* handle clicks in the text part */
419 case kmUPTextPart:
420 {
421 wxMacWindowClipper clipper( textctrl ) ;
422
423 EventRecord rec ;
424 ConvertEventRefToEventRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
425 TXNClick( varsp->fTXNRec, &rec );
426
427 }
428 break;
429
430 }
431 }
432 return partCodeResult;
433 }
434
435
436 /* TPPaneIdleProc is our user pane idle routine. When our text field
437 is active and in focus, we use this routine to set the cursor. */
438 static pascal void TPPaneIdleProc(ControlRef theControl) {
439 /* set up locals */
440 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
441 if ( textctrl == NULL )
442 return ;
443 TPUpdateVisibility( theControl ) ;
444 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
445 if (textctrl->MacIsReallyShown()) {
446 /* if we're not active, then we have nothing to say about the cursor */
447 if (varsp->fIsActive) {
448 Rect bounds;
449 Point mousep;
450
451 wxMacWindowClipper clipper( textctrl ) ;
452 GetMouse(&mousep);
453 /* there's a 'focus thing' and an 'unfocused thing' */
454 if (varsp->fInFocus) {
455 /* flash the cursor */
456 SetPort(varsp->fDrawingEnvironment);
457 TXNIdle(varsp->fTXNRec);
458 /* set the cursor */
459 if (PtInRect(mousep, &varsp->fRTextArea)) {
460 RgnHandle theRgn;
461 RectRgn((theRgn = NewRgn()), &varsp->fRTextArea);
462 TXNAdjustCursor(varsp->fTXNRec, theRgn);
463 DisposeRgn(theRgn);
464 }
465 else
466 {
467 // SetThemeCursor(kThemeArrowCursor);
468 }
469 } else {
470 /* if it's in our bounds, set the cursor */
471 UMAGetControlBoundsInWindowCoords(theControl, &bounds);
472 if (PtInRect(mousep, &bounds))
473 {
474 // SetThemeCursor(kThemeArrowCursor);
475 }
476 }
477 }
478 }
479 }
480
481
482 /* TPPaneKeyDownProc is called whenever a keydown event is directed
483 at our control. Here, we direct the keydown event to the text
484 edit record and redraw the scroll bar and text field as appropriate. */
485 static pascal ControlPartCode TPPaneKeyDownProc(ControlRef theControl,
486 SInt16 keyCode, SInt16 charCode, SInt16 modifiers) {
487
488 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
489 if ( textctrl == NULL )
490 return 0;
491 TPUpdateVisibility( theControl ) ;
492
493 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
494 if (varsp->fInFocus)
495 {
496 /* turn autoscrolling on and send the key event to text edit */
497 wxMacWindowClipper clipper( textctrl ) ;
498 EventRecord ev ;
499 memset( &ev , 0 , sizeof( ev ) ) ;
500 ev.what = keyDown ;
501 ev.modifiers = modifiers ;
502 ev.message = (( keyCode << 8 ) & keyCodeMask ) + ( charCode & charCodeMask ) ;
503 TXNKeyDown( varsp->fTXNRec, &ev);
504 }
505 return kControlEntireControl;
506 }
507
508
509 /* TPPaneActivateProc is called when the window containing
510 the user pane control receives activate events. Here, we redraw
511 the control and it's text as necessary for the activation state. */
512 static pascal void TPPaneActivateProc(ControlRef theControl, Boolean activating) {
513 /* set up locals */
514 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
515
516 if ( textctrl == NULL )
517 return ;
518 TPUpdateVisibility( theControl ) ;
519
520 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
521
522 varsp->fIsActive = activating;
523 wxMacWindowClipper clipper( textctrl ) ;
524 TPActivatePaneText(varsp, varsp->fIsActive && varsp->fInFocus);
525 /* redraw the frame */
526 if ( textctrl->MacIsReallyShown() )
527 {
528 if ( !varsp->fNoBorders )
529 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
530 TPRedrawFocusOutline( varsp ) ;
531 }
532 }
533
534
535 /* TPPaneFocusProc is called when every the focus changes to or
536 from our control. Herein, switch the focus appropriately
537 according to the parameters and redraw the control as
538 necessary. */
539 static pascal ControlPartCode TPPaneFocusProc(ControlRef theControl, ControlFocusPart action) {
540 ControlPartCode focusResult;
541
542 focusResult = kControlFocusNoPart;
543 wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(theControl);
544 if ( textctrl == NULL )
545 return 0;
546 TPUpdateVisibility( theControl ) ;
547 STPTextPaneVars *varsp = (STPTextPaneVars *) textctrl->m_macTXNvars ;
548 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
549 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
550 and kControlFocusNextPart will be received. When the user clicks in our field
551 and it is not the current focus, then the constant kUserClickedToFocusPart will
552 be received. The constant kControlFocusNoPart will be received when our control
553 is the current focus and the user clicks in another control. In your focus routine,
554 you should respond to these codes as follows:
555
556 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
557 the control and the focus rectangle as necessary.
558
559 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
560 depending on its current state. redraw the control and the focus rectangle
561 as appropriate for the new focus state. If the focus state is 'off', return the constant
562 kControlFocusNoPart, otherwise return a non-zero part code.
563 kUserClickedToFocusPart - is a constant defined for this example. You should
564 define your own value for handling click-to-focus type events. */
565 /* calculate the next highlight state */
566 switch (action) {
567 default:
568 case kControlFocusNoPart:
569 TPFocusPaneText(varsp, false);
570 focusResult = kControlFocusNoPart;
571 break;
572 case kUserClickedToFocusPart:
573 TPFocusPaneText(varsp, true);
574 focusResult = 1;
575 break;
576 case kControlFocusPrevPart:
577 case kControlFocusNextPart:
578 TPFocusPaneText(varsp, ( ! varsp->fInFocus));
579 focusResult = varsp->fInFocus ? 1 : kControlFocusNoPart;
580 break;
581 }
582 TPActivatePaneText(varsp, varsp->fIsActive && varsp->fInFocus);
583 /* redraw the text fram and focus rectangle to indicate the
584 new focus state */
585 if ( textctrl->MacIsReallyShown() )
586 {
587 wxMacWindowClipper c( textctrl ) ;
588 if ( !varsp->fNoBorders )
589 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
590 TPRedrawFocusOutline( varsp ) ;
591 }
592 return focusResult;
593 }
594
595
596 /* mUPOpenControl initializes a user pane control so it will be drawn
597 and will behave as a scrolling text edit field inside of a window.
598 This routine performs all of the initialization steps necessary,
599 except it does not create the user pane control itself. theControl
600 should refer to a user pane control that you have either created
601 yourself or extracted from a dialog's control heirarchy using
602 the GetDialogItemAsControl routine. */
603 OSStatus mUPOpenControl(STPTextPaneVars* &handle, ControlRef theControl, long wxStyle )
604 {
605 Rect bounds;
606 WindowRef theWindow;
607 STPTextPaneVars *varsp;
608 OSStatus err = noErr ;
609
610 /* set up our globals */
611 if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(TPPaneDrawProc);
612 if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(TPPaneHitTestProc);
613 if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(TPPaneTrackingProc);
614 if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(TPPaneIdleProc);
615 if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc);
616 if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(TPPaneActivateProc);
617 if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(TPPaneFocusProc);
618
619 /* allocate our private storage */
620 varsp = (STPTextPaneVars *) malloc(sizeof(STPTextPaneVars));
621 handle = varsp ;
622
623 /* set the initial settings for our private data */
624 varsp->fMultiline = wxStyle & wxTE_MULTILINE ;
625 varsp->fNoBorders = wxStyle & wxNO_BORDER ;
626 varsp->fInFocus = false;
627 varsp->fIsActive = true;
628 varsp->fTXNObjectActive = false;
629 varsp->fFocusDrawState = false ;
630 varsp->fUserPaneRec = theControl;
631 varsp->fVisible = true ;
632
633 theWindow = varsp->fOwner = GetControlOwner(theControl);
634
635 varsp->fDrawingEnvironment = (GrafPtr) GetWindowPort(theWindow);
636
637 /* set up the user pane procedures */
638 SetControlData(theControl, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
639 SetControlData(theControl, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
640 SetControlData(theControl, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
641 SetControlData(theControl, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
642 SetControlData(theControl, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
643 SetControlData(theControl, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
644 SetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
645
646 /* calculate the rectangles used by the control */
647 UMAGetControlBoundsInWindowCoords(theControl, &bounds);
648 varsp->fRTextOutlineRegion = NewRgn() ;
649 TPCalculateBounds( varsp , bounds ) ;
650
651 /* set up the drawing environment */
652 SetPort(varsp->fDrawingEnvironment);
653
654 /* create the new edit field */
655
656 TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( wxStyle ) ;
657
658 verify_noerr(TXNNewObject(NULL, varsp->fOwner, &varsp->fRTextArea,
659 frameOptions ,
660 kTXNTextEditStyleFrameType,
661 kTXNTextensionFile,
662 kTXNSystemDefaultEncoding,
663 &varsp->fTXNRec, &varsp->fTXNFrame, (TXNObjectRefcon) varsp));
664
665 AdjustAttributesFromWXStyle( varsp->fTXNRec , wxStyle , varsp->fVisible ) ;
666 /* perform final activations and setup for our text field. Here,
667 we assume that the window is going to be the 'active' window. */
668 TPActivatePaneText(varsp, varsp->fIsActive && varsp->fInFocus);
669 /* all done */
670 return err;
671 }
672
673 #else
674 struct STPTextPaneVars
675 {
676 } ;
677
678 #endif
679
680 static void SetTXNData( STPTextPaneVars *varsp, TXNObject txn , const wxString& st , TXNOffset start , TXNOffset end )
681 {
682 #if wxUSE_UNICODE
683 #if SIZEOF_WCHAR_T == 2
684 size_t len = st.Len() ;
685 TXNSetData( txn , kTXNUnicodeTextData, (void*)st.wc_str(), len * 2,
686 start, end);
687 #else
688 wxMBConvUTF16BE converter ;
689 ByteCount byteBufferLen = converter.WC2MB( NULL , st.wc_str() , 0 ) ;
690 UniChar *unibuf = (UniChar*) malloc(byteBufferLen) ;
691 converter.WC2MB( (char*) unibuf , st.wc_str() , byteBufferLen ) ;
692 TXNSetData( txn , kTXNUnicodeTextData, (void*)unibuf, byteBufferLen ,
693 start, end);
694 free( unibuf ) ;
695 #endif
696 #else
697 wxCharBuffer text = st.mb_str(wxConvLocal) ;
698 TXNSetData( txn , kTXNTextData, (void*)text.data(), strlen( text ) ,
699 start, end);
700 #endif
701 }
702
703
704 #endif
705
706 #if !USE_SHARED_LIBRARY
707 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
708
709 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
710 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
711 EVT_CHAR(wxTextCtrl::OnChar)
712 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
713 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
714 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
715 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
716 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
717
718 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
719 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
720 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
721 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
722 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
723 END_EVENT_TABLE()
724 #endif
725
726 // Text item
727 void wxTextCtrl::Init()
728 {
729 m_macTXN = NULL ;
730 m_macTXNvars = NULL ;
731
732 m_editable = true ;
733 m_dirty = false;
734
735 m_maxLength = TE_UNLIMITED_LENGTH ;
736 }
737
738 wxTextCtrl::~wxTextCtrl()
739 {
740 #if wxMAC_USE_MLTE
741 SetControlReference((ControlRef)m_macControl, 0) ;
742 #if !wxMAC_USE_MLTE_HIVIEW
743 TXNDeleteObject((TXNObject)m_macTXN);
744 #endif
745 /* delete our private storage */
746 free(m_macTXNvars);
747 /* zero the control reference */
748 #endif
749 }
750
751
752 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
753 const wxString& str,
754 const wxPoint& pos,
755 const wxSize& size, long style,
756 const wxValidator& validator,
757 const wxString& name)
758 {
759 m_macIsUserPane = FALSE ;
760
761 m_macTXN = NULL ;
762 m_macTXNvars = NULL ;
763 m_editable = true ;
764
765 // base initialization
766 if ( !wxTextCtrlBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
767 return FALSE;
768
769 wxSize mySize = size ;
770
771 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
772
773 if ( m_windowStyle & wxTE_MULTILINE )
774 {
775 wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
776 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
777
778 m_windowStyle |= wxTE_PROCESS_ENTER;
779 }
780
781 wxString st = str ;
782 wxMacConvertNewlines13To10( &st ) ;
783 #if wxMAC_USE_MLTE
784 {
785 #if wxMAC_USE_MLTE_HIVIEW
786 HIRect hr = { bounds.left , bounds.top , bounds.right - bounds.left , bounds.bottom- bounds.top } ;
787 HITextViewCreate( &hr , 0, FrameOptionsFromWXStyle( m_windowStyle ) , (ControlRef*) &m_macControl ) ;
788 m_macTXN = HITextViewGetTXNObject((ControlRef) m_macControl) ;
789 AdjustAttributesFromWXStyle( (TXNObject) m_macTXN , m_windowStyle , true ) ;
790 HIViewSetVisible( (ControlRef) m_macControl , true ) ;
791 #else
792 short featurSet;
793
794 featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
795 | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground
796 | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
797 /* create the control */
798 m_macControl = (WXWidget) ::NewControl(MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, "\p", true , featurSet, 0, featurSet, kControlUserPaneProc, (long) this );
799 /* set up the mUP specific features and data */
800 wxMacWindowClipper c(this) ;
801 STPTextPaneVars *varsp ;
802 mUPOpenControl( varsp, (ControlRef) m_macControl, m_windowStyle );
803 m_macTXNvars = varsp ;
804 m_macTXN = varsp->fTXNRec ;
805 #endif
806
807 if ( style & wxTE_PASSWORD )
808 {
809 UniChar c = 0xA5 ;
810 verify_noerr(TXNEchoMode( (TXNObject) m_macTXN , c , 0 , true )) ;
811 }
812 }
813 MacPostControlCreate(pos,size) ;
814
815 #if !wxMAC_USE_MLTE_HIVIEW
816 if ( MacIsReallyShown() )
817 MLTESetObjectVisibility( (STPTextPaneVars*) m_macTXNvars, true , GetWindowStyle() ) ;
818 #endif
819
820 {
821 wxMacWindowClipper clipper( this ) ;
822 #if !wxMAC_USE_MLTE_HIVIEW
823 TPUpdateVisibility( (ControlRef) m_macControl ) ;
824 #endif
825 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ;
826
827 TXNSetSelection( (TXNObject) m_macTXN, 0, 0);
828 TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
829 }
830
831 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
832 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
833
834 SetBackgroundColour( *wxWHITE ) ;
835
836 TXNBackground tback;
837 tback.bgType = kTXNBackgroundTypeRGB;
838 tback.bg.color = MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
839 TXNSetBackground( (TXNObject) m_macTXN , &tback);
840
841 if ( m_windowStyle & wxTE_READONLY)
842 {
843 SetEditable( false ) ;
844 }
845 #else
846 wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
847 CreateEditUnicodeTextControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds , cf , style & wxTE_PASSWORD , NULL , (ControlRef*) &m_macControl ) ;
848 MacPostControlCreate(pos,size) ;
849 #endif
850
851
852 return TRUE;
853 }
854
855 void wxTextCtrl::MacVisibilityChanged()
856 {
857 #if wxMAC_USE_MLTE && !wxMAC_USE_MLTE_HIVIEW
858 MLTESetObjectVisibility((STPTextPaneVars*) m_macTXNvars , MacIsReallyShown() , GetWindowStyle() ) ;
859 if ( !MacIsReallyShown() )
860 InvalWindowRect( GetControlOwner( (ControlHandle) m_macControl ) , &((STPTextPaneVars *)m_macTXNvars)->fRBounds ) ;
861 #endif
862 }
863
864 void wxTextCtrl::MacEnabledStateChanged()
865 {
866 }
867
868
869 wxString wxTextCtrl::GetValue() const
870 {
871 wxString result ;
872 #if wxMAC_USE_MLTE
873 OSStatus err ;
874 Size actualSize = 0;
875 {
876 #if wxUSE_UNICODE
877 Handle theText ;
878 err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNUnicodeTextData );
879 // all done
880 if ( err )
881 {
882 actualSize = 0 ;
883 }
884 else
885 {
886 actualSize = GetHandleSize( theText ) / sizeof( UniChar) ;
887 if ( actualSize > 0 )
888 {
889 wxChar *ptr = NULL ;
890 #if SIZEOF_WCHAR_T == 2
891 ptr = new wxChar[actualSize + 1 ] ;
892 wxStrncpy( ptr , (wxChar*) *theText , actualSize ) ;
893
894 #else
895 SetHandleSize( theText , ( actualSize + 1 ) * sizeof( UniChar ) ) ;
896 HLock( theText ) ;
897 (((UniChar*)*theText)[actualSize]) = 0 ;
898 wxMBConvUTF16BE converter ;
899 size_t noChars = converter.MB2WC( NULL , (const char*)*theText , 0 ) ;
900 ptr = new wxChar[noChars + 1] ;
901
902 noChars = converter.MB2WC( ptr , (const char*)*theText , noChars ) ;
903 ptr[noChars] = 0 ;
904 HUnlock( theText ) ;
905 #endif
906 ptr[actualSize] = 0 ;
907 result = wxString( ptr ) ;
908 delete[] ptr ;
909 }
910 DisposeHandle( theText ) ;
911 }
912 #else
913 Handle theText ;
914 err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
915 // all done
916 if ( err )
917 {
918 actualSize = 0 ;
919 }
920 else
921 {
922 actualSize = GetHandleSize( theText ) ;
923 if ( actualSize > 0 )
924 {
925 HLock( theText ) ;
926 result = wxString( *theText , wxConvLocal , actualSize ) ;
927 HUnlock( theText ) ;
928 }
929 DisposeHandle( theText ) ;
930 }
931 #endif
932 }
933 #else
934 CFStringRef value = NULL ;
935 Size actualSize = 0 ;
936
937 verify_noerr( GetControlData( (ControlRef) m_macControl , 0, GetWindowStyle() & wxTE_PASSWORD ?
938 kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag,
939 sizeof(CFStringRef), &value, &actualSize ) );
940 if ( value )
941 {
942 wxMacCFStringHolder cf(value) ;
943 result = cf.AsString() ;
944 }
945 #endif
946 wxMacConvertNewlines10To13( &result ) ;
947 return result ;
948 }
949
950 void wxTextCtrl::GetSelection(long* from, long* to) const
951 {
952 #if wxMAC_USE_MLTE
953 TXNGetSelection( (TXNObject) m_macTXN , (TXNOffset*) from , (TXNOffset*) to ) ;
954 #else
955 ControlEditTextSelectionRec sel ;
956 Size actualSize ;
957 verify_noerr( GetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag,
958 sizeof(ControlEditTextSelectionRec), &sel, &actualSize ) );
959 if ( from ) *from = sel.selStart ;
960 if ( to ) *to = sel.selEnd ;
961 #endif
962 }
963
964 void wxTextCtrl::SetValue(const wxString& str)
965 {
966 // optimize redraws
967 if ( GetValue() == str )
968 return ;
969
970 wxString st = str ;
971 wxMacConvertNewlines13To10( &st ) ;
972 #if wxMAC_USE_MLTE
973 {
974 wxMacWindowClipper c( this ) ;
975 bool formerEditable = m_editable ;
976 if ( !formerEditable )
977 SetEditable(true) ;
978
979 #if !wxMAC_USE_MLTE_HIVIEW
980 // otherwise scrolling might have problems ?
981 TPUpdateVisibility( ( (STPTextPaneVars *)m_macTXNvars)->fUserPaneRec ) ;
982 #endif
983 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ;
984 TXNSetSelection( (TXNObject) m_macTXN, 0, 0);
985 TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
986 if ( !formerEditable )
987 SetEditable(formerEditable) ;
988 }
989 #else
990 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
991 CFStringRef value = cf ;
992 verify_noerr( SetControlData( (ControlRef) m_macControl , 0, GetWindowStyle() & wxTE_PASSWORD ?
993 kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag,
994 sizeof(CFStringRef), &value ) );
995 #endif
996 }
997
998 void wxTextCtrl::SetMaxLength(unsigned long len)
999 {
1000 m_maxLength = len ;
1001 }
1002
1003 bool wxTextCtrl::SetFont( const wxFont& font )
1004 {
1005 if ( !wxTextCtrlBase::SetFont( font ) )
1006 return FALSE ;
1007
1008 #if wxMAC_USE_MLTE
1009 wxMacWindowClipper c( this ) ;
1010 bool formerEditable = m_editable ;
1011 if ( !formerEditable )
1012 SetEditable(true) ;
1013
1014 TXNTypeAttributes typeAttr[4] ;
1015 Str255 fontName = "\pMonaco" ;
1016 SInt16 fontSize = 12 ;
1017 Style fontStyle = normal ;
1018 int attrCounter = 0 ;
1019
1020 wxMacStringToPascal( font.GetFaceName() , fontName ) ;
1021 fontSize = font.MacGetFontSize() ;
1022 fontStyle = font.MacGetFontStyle() ;
1023
1024 typeAttr[attrCounter].tag = kTXNQDFontNameAttribute ;
1025 typeAttr[attrCounter].size = kTXNQDFontNameAttributeSize ;
1026 typeAttr[attrCounter].data.dataPtr = (void*) fontName ;
1027 typeAttr[attrCounter+1].tag = kTXNQDFontSizeAttribute ;
1028 typeAttr[attrCounter+1].size = kTXNFontSizeAttributeSize ;
1029 typeAttr[attrCounter+1].data.dataValue = (fontSize << 16) ;
1030 typeAttr[attrCounter+2].tag = kTXNQDFontStyleAttribute ;
1031 typeAttr[attrCounter+2].size = kTXNQDFontStyleAttributeSize ;
1032 typeAttr[attrCounter+2].data.dataValue = fontStyle ;
1033 attrCounter += 3 ;
1034 /*
1035 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1036 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1037 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1038 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
1039 attrCounter += 1 ;
1040 */
1041 verify_noerr( TXNSetTypeAttributes ((TXNObject)m_macTXN, attrCounter , typeAttr, kTXNStartOffset,kTXNEndOffset) );
1042
1043 if ( !formerEditable )
1044 SetEditable(formerEditable) ;
1045 #endif
1046 return true ;
1047 }
1048
1049 bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
1050 {
1051 #if wxMAC_USE_MLTE
1052 bool formerEditable = m_editable ;
1053 if ( !formerEditable )
1054 SetEditable(true) ;
1055 TXNTypeAttributes typeAttr[4] ;
1056 Str255 fontName = "\pMonaco" ;
1057 SInt16 fontSize = 12 ;
1058 Style fontStyle = normal ;
1059 RGBColor color ;
1060 int attrCounter = 0 ;
1061 if ( style.HasFont() )
1062 {
1063 const wxFont &font = style.GetFont() ;
1064 wxMacStringToPascal( font.GetFaceName() , fontName ) ;
1065 fontSize = font.GetPointSize() ;
1066 if ( font.GetUnderlined() )
1067 fontStyle |= underline ;
1068 if ( font.GetWeight() == wxBOLD )
1069 fontStyle |= bold ;
1070 if ( font.GetStyle() == wxITALIC )
1071 fontStyle |= italic ;
1072
1073 typeAttr[attrCounter].tag = kTXNQDFontNameAttribute ;
1074 typeAttr[attrCounter].size = kTXNQDFontNameAttributeSize ;
1075 typeAttr[attrCounter].data.dataPtr = (void*) fontName ;
1076 typeAttr[attrCounter+1].tag = kTXNQDFontSizeAttribute ;
1077 typeAttr[attrCounter+1].size = kTXNFontSizeAttributeSize ;
1078 typeAttr[attrCounter+1].data.dataValue = (fontSize << 16) ;
1079 typeAttr[attrCounter+2].tag = kTXNQDFontStyleAttribute ;
1080 typeAttr[attrCounter+2].size = kTXNQDFontStyleAttributeSize ;
1081 typeAttr[attrCounter+2].data.dataValue = fontStyle ;
1082 attrCounter += 3 ;
1083
1084 }
1085 if ( style.HasTextColour() )
1086 {
1087 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1088 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1089 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1090 color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ;
1091 attrCounter += 1 ;
1092 }
1093
1094 if ( attrCounter > 0 )
1095 {
1096 verify_noerr( TXNSetTypeAttributes ((TXNObject)m_macTXN, attrCounter , typeAttr, start,end) );
1097 }
1098 if ( !formerEditable )
1099 SetEditable(formerEditable) ;
1100 #endif
1101 return TRUE ;
1102 }
1103
1104 bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style)
1105 {
1106 wxTextCtrlBase::SetDefaultStyle( style ) ;
1107 SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
1108 return TRUE ;
1109 }
1110
1111 // Clipboard operations
1112 void wxTextCtrl::Copy()
1113 {
1114 if (CanCopy())
1115 {
1116 #if wxMAC_USE_MLTE
1117 ClearCurrentScrap();
1118 TXNCopy((TXNObject)m_macTXN);
1119 TXNConvertToPublicScrap();
1120 #endif
1121 }
1122 }
1123
1124 void wxTextCtrl::Cut()
1125 {
1126 if (CanCut())
1127 {
1128 #if wxMAC_USE_MLTE
1129 ClearCurrentScrap();
1130 TXNCut((TXNObject)m_macTXN);
1131 TXNConvertToPublicScrap();
1132 #endif
1133 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1134 event.SetString( GetValue() ) ;
1135 event.SetEventObject( this );
1136 GetEventHandler()->ProcessEvent(event);
1137 }
1138 }
1139
1140 void wxTextCtrl::Paste()
1141 {
1142 if (CanPaste())
1143 {
1144 #if wxMAC_USE_MLTE
1145 TXNConvertFromPublicScrap();
1146 TXNPaste((TXNObject)m_macTXN);
1147 SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
1148 #endif
1149 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1150 event.SetString( GetValue() ) ;
1151 event.SetEventObject( this );
1152 GetEventHandler()->ProcessEvent(event);
1153 }
1154 }
1155
1156 bool wxTextCtrl::CanCopy() const
1157 {
1158 // Can copy if there's a selection
1159 long from, to;
1160 GetSelection(& from, & to);
1161 return (from != to);
1162 }
1163
1164 bool wxTextCtrl::CanCut() const
1165 {
1166 if ( !IsEditable() )
1167 {
1168 return false ;
1169 }
1170 // Can cut if there's a selection
1171 long from, to;
1172 GetSelection(& from, & to);
1173 return (from != to);
1174 }
1175
1176 bool wxTextCtrl::CanPaste() const
1177 {
1178 if (!IsEditable())
1179 return FALSE;
1180
1181 #if wxMAC_USE_MLTE
1182 return TXNIsScrapPastable() ;
1183 #else
1184 return true ;
1185 #endif
1186 }
1187
1188 void wxTextCtrl::SetEditable(bool editable)
1189 {
1190 if ( editable != m_editable )
1191 {
1192 m_editable = editable ;
1193 #if wxMAC_USE_MLTE
1194 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1195 TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ;
1196 TXNSetTXNObjectControls( (TXNObject) m_macTXN , false , sizeof(tag) / sizeof (TXNControlTag) , tag , data ) ;
1197 #endif
1198 }
1199 }
1200
1201 void wxTextCtrl::SetInsertionPoint(long pos)
1202 {
1203 SetSelection( pos , pos ) ;
1204 }
1205
1206 void wxTextCtrl::SetInsertionPointEnd()
1207 {
1208 long pos = GetLastPosition();
1209 SetInsertionPoint(pos);
1210 }
1211
1212 long wxTextCtrl::GetInsertionPoint() const
1213 {
1214 long begin,end ;
1215 GetSelection( &begin , &end ) ;
1216 return begin ;
1217 }
1218
1219 long wxTextCtrl::GetLastPosition() const
1220 {
1221 Handle theText ;
1222 long actualsize = 0 ;
1223 #if wxMAC_USE_MLTE
1224 OSErr err = TXNGetDataEncoded( (TXNObject) m_macTXN, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
1225 /* all done */
1226 if ( err )
1227 {
1228 actualsize = 0 ;
1229 }
1230 else
1231 {
1232 actualsize = GetHandleSize( theText ) ;
1233 DisposeHandle( theText ) ;
1234 }
1235 #endif
1236 return actualsize ;
1237 }
1238
1239 void wxTextCtrl::Replace(long from, long to, const wxString& str)
1240 {
1241 #if wxMAC_USE_MLTE
1242 wxString value = str ;
1243 wxMacConvertNewlines13To10( &value ) ;
1244
1245 bool formerEditable = m_editable ;
1246 if ( !formerEditable )
1247 SetEditable(true) ;
1248 TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
1249 TXNClear( ((TXNObject) m_macTXN) ) ;
1250 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , str , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
1251 if ( !formerEditable )
1252 SetEditable( formerEditable ) ;
1253
1254 Refresh() ;
1255 #endif
1256 }
1257
1258 void wxTextCtrl::Remove(long from, long to)
1259 {
1260 #if wxMAC_USE_MLTE
1261 bool formerEditable = m_editable ;
1262 if ( !formerEditable )
1263 SetEditable(true) ;
1264 TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
1265 TXNClear( ((TXNObject) m_macTXN) ) ;
1266 if ( !formerEditable )
1267 SetEditable( formerEditable ) ;
1268
1269 Refresh() ;
1270 #endif
1271 }
1272
1273 void wxTextCtrl::SetSelection(long from, long to)
1274 {
1275 #if wxMAC_USE_MLTE
1276 /* change the selection */
1277 if ((from == -1) && (to == -1))
1278 TXNSelectAll((TXNObject) m_macTXN);
1279 else
1280 TXNSetSelection( (TXNObject) m_macTXN, from, to);
1281 TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
1282 #else
1283 ControlEditTextSelectionRec sel ;
1284 sel.selStart = from ;
1285 sel.selEnd = to ;
1286 verify_noerr( SetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag,
1287 sizeof(ControlEditTextSelectionRec), &sel ) );
1288
1289 #endif
1290 }
1291
1292 bool wxTextCtrl::LoadFile(const wxString& file)
1293 {
1294 if ( wxTextCtrlBase::LoadFile(file) )
1295 {
1296 return TRUE;
1297 }
1298
1299 return FALSE;
1300 }
1301
1302 void wxTextCtrl::WriteText(const wxString& str)
1303 {
1304 wxString st = str ;
1305 wxMacConvertNewlines13To10( &st ) ;
1306 #if wxMAC_USE_MLTE
1307 bool formerEditable = m_editable ;
1308 if ( !formerEditable )
1309 SetEditable(true) ;
1310 {
1311 wxMacWindowStateSaver( this ) ;
1312 long start , end , dummy ;
1313 GetSelection( &start , &dummy ) ;
1314 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
1315 GetSelection( &dummy , &end ) ;
1316 SetStyle( start , end , GetDefaultStyle() ) ;
1317 }
1318 if ( !formerEditable )
1319 SetEditable( formerEditable ) ;
1320
1321 MacRedrawControl() ;
1322 #else
1323 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
1324 CFStringRef value = cf ;
1325 SetControlData( (ControlRef) m_macControl , 0, kControlEditTextInsertCFStringRefTag,
1326 sizeof(CFStringRef), &value );
1327 #endif
1328 }
1329
1330 void wxTextCtrl::AppendText(const wxString& text)
1331 {
1332 SetInsertionPointEnd();
1333 WriteText(text);
1334 }
1335
1336 void wxTextCtrl::Clear()
1337 {
1338 #if wxMAC_USE_MLTE
1339 bool formerEditable = m_editable ;
1340 if ( !formerEditable )
1341 SetEditable(true) ;
1342 TXNSetSelection( (TXNObject)m_macTXN , kTXNStartOffset , kTXNEndOffset ) ;
1343 TXNClear((TXNObject)m_macTXN);
1344
1345 if ( !formerEditable )
1346 SetEditable( formerEditable ) ;
1347
1348 Refresh() ;
1349 #else
1350 SetValue(wxEmptyString) ;
1351 #endif
1352 }
1353
1354 bool wxTextCtrl::IsModified() const
1355 {
1356 return m_dirty;
1357 }
1358
1359 bool wxTextCtrl::IsEditable() const
1360 {
1361 return IsEnabled() && m_editable ;
1362 }
1363
1364 bool wxTextCtrl::AcceptsFocus() const
1365 {
1366 // we don't want focus if we can't be edited
1367 return /*IsEditable() && */ wxControl::AcceptsFocus();
1368 }
1369
1370 wxSize wxTextCtrl::DoGetBestSize() const
1371 {
1372 int wText = 100 ;
1373
1374 int hText;
1375
1376 switch( m_windowVariant )
1377 {
1378 case wxWINDOW_VARIANT_NORMAL :
1379 hText = 22 ;
1380 break ;
1381 case wxWINDOW_VARIANT_SMALL :
1382 hText = 19 ;
1383 break ;
1384 case wxWINDOW_VARIANT_MINI :
1385 hText= 15 ;
1386 break ;
1387 default :
1388 hText = 22 ;
1389 break ;
1390 }
1391
1392 if ( m_windowStyle & wxTE_MULTILINE )
1393 {
1394 hText *= 5 ;
1395 }
1396
1397 return wxSize(wText, hText);
1398 }
1399
1400 // ----------------------------------------------------------------------------
1401 // Undo/redo
1402 // ----------------------------------------------------------------------------
1403
1404 void wxTextCtrl::Undo()
1405 {
1406 if (CanUndo())
1407 {
1408 #if wxMAC_USE_MLTE
1409 TXNUndo((TXNObject)m_macTXN);
1410 #endif
1411 }
1412 }
1413
1414 void wxTextCtrl::Redo()
1415 {
1416 if (CanRedo())
1417 {
1418 #if wxMAC_USE_MLTE
1419 TXNRedo((TXNObject)m_macTXN);
1420 #endif
1421 }
1422 }
1423
1424 bool wxTextCtrl::CanUndo() const
1425 {
1426 if ( !IsEditable() )
1427 {
1428 return false ;
1429 }
1430 #if wxMAC_USE_MLTE
1431 return TXNCanUndo((TXNObject)m_macTXN,NULL);
1432 #else
1433 return false ;
1434 #endif
1435 }
1436
1437 bool wxTextCtrl::CanRedo() const
1438 {
1439 if ( !IsEditable() )
1440 {
1441 return false ;
1442 }
1443 #if wxMAC_USE_MLTE
1444 return TXNCanRedo((TXNObject)m_macTXN,NULL);
1445 #else
1446 return false ;
1447 #endif
1448 }
1449
1450 // Makes modifie or unmodified
1451 void wxTextCtrl::MarkDirty()
1452 {
1453 m_dirty = true;
1454 }
1455
1456 void wxTextCtrl::DiscardEdits()
1457 {
1458 m_dirty = false;
1459 }
1460
1461 int wxTextCtrl::GetNumberOfLines() const
1462 {
1463 ItemCount lines = 0 ;
1464 #if wxMAC_USE_MLTE
1465 TXNGetLineCount((TXNObject)m_macTXN, &lines ) ;
1466 #endif
1467 return lines ;
1468 }
1469
1470 long wxTextCtrl::XYToPosition(long x, long y) const
1471 {
1472 #if wxMAC_USE_MLTE
1473 Point curpt ;
1474
1475 long lastpos = GetLastPosition() ;
1476
1477 // TODO find a better implementation : while we can get the
1478 // line metrics of a certain line, we don't get its starting
1479 // position, so it would probably be rather a binary search
1480 // for the start position
1481 long xpos = 0 ;
1482 long ypos = 0 ;
1483 int lastHeight = 0 ;
1484
1485 ItemCount n ;
1486 for ( n = 0 ; n <= lastpos ; ++n )
1487 {
1488 if ( y == ypos && x == xpos )
1489 return n ;
1490
1491 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1492
1493 if ( curpt.v > lastHeight )
1494 {
1495 xpos = 0 ;
1496 if ( n > 0 )
1497 ++ypos ;
1498 lastHeight = curpt.v ;
1499 }
1500 else
1501 ++xpos ;
1502 }
1503 #endif
1504 return 0;
1505 }
1506
1507 bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
1508 {
1509 #if wxMAC_USE_MLTE
1510 Point curpt ;
1511
1512 long lastpos = GetLastPosition() ;
1513
1514 if ( y ) *y = 0 ;
1515 if ( x ) *x = 0 ;
1516
1517 if ( pos <= lastpos )
1518 {
1519 // TODO find a better implementation : while we can get the
1520 // line metrics of a certain line, we don't get its starting
1521 // position, so it would probably be rather a binary search
1522 // for the start position
1523 long xpos = 0 ;
1524 long ypos = 0 ;
1525 int lastHeight = 0 ;
1526
1527 ItemCount n ;
1528 for ( n = 0 ; n <= pos ; ++n )
1529 {
1530 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1531
1532 if ( curpt.v > lastHeight )
1533 {
1534 xpos = 0 ;
1535 if ( n > 0 )
1536 ++ypos ;
1537 lastHeight = curpt.v ;
1538 }
1539 else
1540 ++xpos ;
1541 }
1542 if ( y ) *y = ypos ;
1543 if ( x ) *x = xpos ;
1544 }
1545 #else
1546 if ( y ) *y = 0 ;
1547 if ( x ) *x = 0 ;
1548 #endif
1549 return FALSE ;
1550 }
1551
1552 void wxTextCtrl::ShowPosition(long pos)
1553 {
1554 #if wxMAC_USE_MLTE
1555 #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1556 {
1557 Point current ;
1558 Point desired ;
1559 TXNOffset selstart , selend ;
1560 TXNGetSelection( (TXNObject) m_macTXN , &selstart , &selend) ;
1561 TXNOffsetToPoint( (TXNObject) m_macTXN, selstart , &current);
1562 TXNOffsetToPoint( (TXNObject) m_macTXN, pos , &desired);
1563 //TODO use HIPoints for 10.3 and above
1564 if ( (UInt32) TXNScroll != (UInt32) kUnresolvedCFragSymbolAddress )
1565 {
1566 OSErr theErr = noErr;
1567 SInt32 dv = desired.v - current.v ;
1568 SInt32 dh = desired.h - current.h ;
1569 TXNShowSelection( (TXNObject) m_macTXN , true ) ;
1570 theErr = TXNScroll( (TXNObject) m_macTXN, kTXNScrollUnitsInPixels , kTXNScrollUnitsInPixels , &dv , &dh );
1571 wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") );
1572 }
1573 }
1574 #endif
1575 #endif
1576 }
1577
1578 int wxTextCtrl::GetLineLength(long lineNo) const
1579 {
1580 #if wxMAC_USE_MLTE
1581 Point curpt ;
1582 if ( lineNo < GetNumberOfLines() )
1583 {
1584 // TODO find a better implementation : while we can get the
1585 // line metrics of a certain line, we don't get its starting
1586 // position, so it would probably be rather a binary search
1587 // for the start position
1588 long xpos = 0 ;
1589 long ypos = 0 ;
1590 int lastHeight = 0 ;
1591 long lastpos = GetLastPosition() ;
1592
1593 ItemCount n ;
1594 for ( n = 0 ; n <= lastpos ; ++n )
1595 {
1596 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1597
1598 if ( curpt.v > lastHeight )
1599 {
1600 if ( ypos == lineNo )
1601 return xpos ;
1602
1603 xpos = 0 ;
1604 if ( n > 0 )
1605 ++ypos ;
1606 lastHeight = curpt.v ;
1607 }
1608 else
1609 ++xpos ;
1610 }
1611 }
1612 #endif
1613 return 0;
1614 }
1615
1616 wxString wxTextCtrl::GetLineText(long lineNo) const
1617 {
1618 Point curpt ;
1619 wxString line ;
1620 #if wxMAC_USE_MLTE
1621 wxString content = GetValue() ;
1622
1623 if ( lineNo < GetNumberOfLines() )
1624 {
1625 // TODO find a better implementation : while we can get the
1626 // line metrics of a certain line, we don't get its starting
1627 // position, so it would probably be rather a binary search
1628 // for the start position
1629 long xpos = 0 ;
1630 long ypos = 0 ;
1631 int lastHeight = 0 ;
1632 long lastpos = GetLastPosition() ;
1633
1634 ItemCount n ;
1635 for ( n = 0 ; n <= lastpos ; ++n )
1636 {
1637 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1638
1639 if ( curpt.v > lastHeight )
1640 {
1641 if ( ypos == lineNo )
1642 return line ;
1643
1644 xpos = 0 ;
1645 if ( n > 0 )
1646 ++ypos ;
1647 lastHeight = curpt.v ;
1648 }
1649 else
1650 {
1651 if ( ypos == lineNo )
1652 line += content[n] ;
1653 ++xpos ;
1654 }
1655 }
1656 }
1657 #endif
1658 return line ;
1659 }
1660
1661 /*
1662 * Text item
1663 */
1664
1665 void wxTextCtrl::Command(wxCommandEvent & event)
1666 {
1667 SetValue (event.GetString());
1668 ProcessCommand (event);
1669 }
1670
1671 void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
1672 {
1673 // By default, load the first file into the text window.
1674 if (event.GetNumberOfFiles() > 0)
1675 {
1676 LoadFile(event.GetFiles()[0]);
1677 }
1678 }
1679
1680 void wxTextCtrl::OnChar(wxKeyEvent& event)
1681 {
1682 int key = event.GetKeyCode() ;
1683 bool eat_key = false ;
1684
1685 if ( key == 'c' && event.MetaDown() )
1686 {
1687 if ( CanCopy() )
1688 Copy() ;
1689 return ;
1690 }
1691
1692 if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
1693 !( key == WXK_RETURN && ( (m_windowStyle & wxPROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
1694 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1695 )
1696 {
1697 // eat it
1698 return ;
1699 }
1700
1701 // assume that any key not processed yet is going to modify the control
1702 m_dirty = true;
1703
1704 if ( key == 'v' && event.MetaDown() )
1705 {
1706 if ( CanPaste() )
1707 Paste() ;
1708 return ;
1709 }
1710 if ( key == 'x' && event.MetaDown() )
1711 {
1712 if ( CanCut() )
1713 Cut() ;
1714 return ;
1715 }
1716 switch ( key )
1717 {
1718 case WXK_RETURN:
1719 if (m_windowStyle & wxPROCESS_ENTER)
1720 {
1721 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
1722 event.SetEventObject( this );
1723 event.SetString( GetValue() );
1724 if ( GetEventHandler()->ProcessEvent(event) )
1725 return;
1726 }
1727 if ( !(m_windowStyle & wxTE_MULTILINE) )
1728 {
1729 wxWindow *parent = GetParent();
1730 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
1731 parent = parent->GetParent() ;
1732 }
1733 if ( parent && parent->GetDefaultItem() )
1734 {
1735 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
1736 wxButton);
1737 if ( def && def->IsEnabled() )
1738 {
1739 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
1740 event.SetEventObject(def);
1741 def->Command(event);
1742 return ;
1743 }
1744 }
1745
1746 // this will make wxWindows eat the ENTER key so that
1747 // we actually prevent line wrapping in a single line
1748 // text control
1749 eat_key = TRUE;
1750 }
1751
1752 break;
1753
1754 case WXK_TAB:
1755 // always produce navigation event - even if we process TAB
1756 // ourselves the fact that we got here means that the user code
1757 // decided to skip processing of this TAB - probably to let it
1758 // do its default job.
1759 {
1760 wxNavigationKeyEvent eventNav;
1761 eventNav.SetDirection(!event.ShiftDown());
1762 eventNav.SetWindowChange(event.ControlDown());
1763 eventNav.SetEventObject(this);
1764
1765 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
1766 return;
1767
1768 event.Skip() ;
1769 return;
1770 }
1771 break;
1772 }
1773
1774 if (!eat_key)
1775 {
1776 // perform keystroke handling
1777 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
1778 CallNextEventHandler((EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
1779 else
1780 {
1781 EventRecord rec ;
1782 if ( wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) )
1783 {
1784 EventRecord *ev = &rec ;
1785 short keycode ;
1786 short keychar ;
1787 keychar = short(ev->message & charCodeMask);
1788 keycode = short(ev->message & keyCodeMask) >> 8 ;
1789
1790 ::HandleControlKey( (ControlRef) m_macControl , keycode , keychar , ev->modifiers ) ;
1791 }
1792 }
1793 }
1794 if ( ( key >= 0x20 && key < WXK_START ) ||
1795 key == WXK_RETURN ||
1796 key == WXK_DELETE ||
1797 key == WXK_BACK)
1798 {
1799 wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1800 event1.SetString( GetValue() ) ;
1801 event1.SetEventObject( this );
1802 wxPostEvent(GetEventHandler(),event1);
1803 }
1804 }
1805
1806 // ----------------------------------------------------------------------------
1807 // standard handlers for standard edit menu events
1808 // ----------------------------------------------------------------------------
1809
1810 void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
1811 {
1812 Cut();
1813 }
1814
1815 void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
1816 {
1817 Copy();
1818 }
1819
1820 void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
1821 {
1822 Paste();
1823 }
1824
1825 void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
1826 {
1827 Undo();
1828 }
1829
1830 void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
1831 {
1832 Redo();
1833 }
1834
1835 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
1836 {
1837 event.Enable( CanCut() );
1838 }
1839
1840 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
1841 {
1842 event.Enable( CanCopy() );
1843 }
1844
1845 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
1846 {
1847 event.Enable( CanPaste() );
1848 }
1849
1850 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
1851 {
1852 event.Enable( CanUndo() );
1853 }
1854
1855 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
1856 {
1857 event.Enable( CanRedo() );
1858 }
1859
1860 bool wxTextCtrl::MacSetupCursor( const wxPoint& pt )
1861 {
1862 return true ;
1863 }
1864
1865 // user pane implementation
1866
1867 void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part)
1868 {
1869 }
1870
1871 wxInt16 wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
1872 {
1873 return kControlNoPart ;
1874 }
1875
1876 wxInt16 wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
1877 {
1878 return kControlNoPart ;
1879 }
1880
1881 void wxTextCtrl::MacControlUserPaneIdleProc()
1882 {
1883 }
1884
1885 wxInt16 wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
1886 {
1887 return kControlNoPart ;
1888 }
1889
1890 void wxTextCtrl::MacControlUserPaneActivateProc(bool activating)
1891 {
1892 }
1893
1894 wxInt16 wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action)
1895 {
1896 return kControlNoPart ;
1897 }
1898
1899 void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info)
1900 {
1901 }
1902
1903 #endif
1904 // wxUSE_TEXTCTRL