]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/textctrl.cpp
Updated the embedded sample program to reflect latest class functions. Added a gener...
[wxWidgets.git] / src / mac / carbon / textctrl.cpp
... / ...
CommitLineData
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 0
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
79TXNFrameOptions 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
104void 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
177typedef 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. */
210OSStatus 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. */
218ControlUserPaneDrawUPP gTPDrawProc = NULL;
219ControlUserPaneHitTestUPP gTPHitProc = NULL;
220ControlUserPaneTrackingUPP gTPTrackProc = NULL;
221ControlUserPaneIdleUPP gTPIdleProc = NULL;
222ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
223ControlUserPaneActivateUPP gTPActivateProc = NULL;
224ControlUserPaneFocusUPP gTPFocusProc = NULL;
225
226// one place for calculating all
227static 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
245OSStatus 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
268static 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
301static 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
314static 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
325static 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
335static 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. */
360static 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. */
386static 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. */
438static 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. */
485static 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. */
512static 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. */
539static 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. */
603OSStatus 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
674struct STPTextPaneVars
675{
676} ;
677
678#endif
679
680static 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
707IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
708
709BEGIN_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)
723END_EVENT_TABLE()
724#endif
725
726// Text item
727void 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
738wxTextCtrl::~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
752bool 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 HIViewRef scrollView = NULL ;
788 TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( style ) ;
789
790 if ( frameOptions & (kTXNWantVScrollBarMask|kTXNWantHScrollBarMask) )
791 {
792 HIScrollViewCreate(( frameOptions & kTXNWantHScrollBarMask ? kHIScrollViewOptionsHorizScroll : 0) |
793 ( frameOptions & kTXNWantVScrollBarMask ? kHIScrollViewOptionsVertScroll: 0 ) , &scrollView ) ;
794
795 HIViewSetFrame( scrollView, &hr );
796 HIViewSetVisible( scrollView, true );
797 }
798 HIViewRef textView ;
799 HITextViewCreate( NULL , 0, frameOptions , (ControlRef*) &textView ) ;
800 m_macTXN = HITextViewGetTXNObject( textView) ;
801 AdjustAttributesFromWXStyle( (TXNObject) m_macTXN , style , true ) ;
802 HIViewSetVisible( (ControlRef) textView , true ) ;
803 if ( scrollView )
804 {
805 HIViewAddSubview( scrollView , textView ) ;
806 m_macControl = (WXWidget) scrollView ;
807 }
808 else
809 {
810 m_macControl = (WXWidget) textView ;
811 }
812#else
813 short featurSet;
814
815 featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
816 | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground
817 | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
818 /* create the control */
819 verify_noerr( CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, featurSet , (ControlRef*) &m_macControl) ) ;
820
821 wxMacWindowClipper c(this) ;
822 STPTextPaneVars *varsp ;
823 mUPOpenControl( varsp, (ControlRef) m_macControl, m_windowStyle );
824 m_macTXNvars = varsp ;
825 m_macTXN = varsp->fTXNRec ;
826#endif
827
828 if ( style & wxTE_PASSWORD )
829 {
830 UniChar c = 0xA5 ;
831 verify_noerr(TXNEchoMode( (TXNObject) m_macTXN , c , 0 , true )) ;
832 }
833 }
834 MacPostControlCreate(pos,size) ;
835
836#if !wxMAC_USE_MLTE_HIVIEW
837 if ( MacIsReallyShown() )
838 MLTESetObjectVisibility( (STPTextPaneVars*) m_macTXNvars, true , GetWindowStyle() ) ;
839#endif
840
841 {
842 wxMacWindowClipper clipper( this ) ;
843#if !wxMAC_USE_MLTE_HIVIEW
844 TPUpdateVisibility( (ControlRef) m_macControl ) ;
845#endif
846 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ;
847
848 TXNSetSelection( (TXNObject) m_macTXN, 0, 0);
849 TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
850 }
851
852 // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front :
853 // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ;
854
855 SetBackgroundColour( *wxWHITE ) ;
856
857 TXNBackground tback;
858 tback.bgType = kTXNBackgroundTypeRGB;
859 tback.bg.color = MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
860 TXNSetBackground( (TXNObject) m_macTXN , &tback);
861
862 if ( m_windowStyle & wxTE_READONLY)
863 {
864 SetEditable( false ) ;
865 }
866#else
867 wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
868 CreateEditUnicodeTextControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds , cf , style & wxTE_PASSWORD , NULL , (ControlRef*) &m_macControl ) ;
869 MacPostControlCreate(pos,size) ;
870#endif
871
872
873 return TRUE;
874}
875
876void wxTextCtrl::MacVisibilityChanged()
877{
878#if wxMAC_USE_MLTE && !wxMAC_USE_MLTE_HIVIEW
879 MLTESetObjectVisibility((STPTextPaneVars*) m_macTXNvars , MacIsReallyShown() , GetWindowStyle() ) ;
880 if ( !MacIsReallyShown() )
881 InvalWindowRect( GetControlOwner( (ControlHandle) m_macControl ) , &((STPTextPaneVars *)m_macTXNvars)->fRBounds ) ;
882#endif
883}
884
885void wxTextCtrl::MacEnabledStateChanged()
886{
887}
888
889
890wxString wxTextCtrl::GetValue() const
891{
892 wxString result ;
893#if wxMAC_USE_MLTE
894 OSStatus err ;
895 Size actualSize = 0;
896 {
897#if wxUSE_UNICODE
898 Handle theText ;
899 err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNUnicodeTextData );
900 // all done
901 if ( err )
902 {
903 actualSize = 0 ;
904 }
905 else
906 {
907 actualSize = GetHandleSize( theText ) / sizeof( UniChar) ;
908 if ( actualSize > 0 )
909 {
910 wxChar *ptr = NULL ;
911#if SIZEOF_WCHAR_T == 2
912 ptr = new wxChar[actualSize + 1 ] ;
913 wxStrncpy( ptr , (wxChar*) *theText , actualSize ) ;
914
915#else
916 SetHandleSize( theText , ( actualSize + 1 ) * sizeof( UniChar ) ) ;
917 HLock( theText ) ;
918 (((UniChar*)*theText)[actualSize]) = 0 ;
919 wxMBConvUTF16BE converter ;
920 size_t noChars = converter.MB2WC( NULL , (const char*)*theText , 0 ) ;
921 ptr = new wxChar[noChars + 1] ;
922
923 noChars = converter.MB2WC( ptr , (const char*)*theText , noChars ) ;
924 ptr[noChars] = 0 ;
925 HUnlock( theText ) ;
926#endif
927 ptr[actualSize] = 0 ;
928 result = wxString( ptr ) ;
929 delete[] ptr ;
930 }
931 DisposeHandle( theText ) ;
932 }
933#else
934 Handle theText ;
935 err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
936 // all done
937 if ( err )
938 {
939 actualSize = 0 ;
940 }
941 else
942 {
943 actualSize = GetHandleSize( theText ) ;
944 if ( actualSize > 0 )
945 {
946 HLock( theText ) ;
947 result = wxString( *theText , wxConvLocal , actualSize ) ;
948 HUnlock( theText ) ;
949 }
950 DisposeHandle( theText ) ;
951 }
952#endif
953 }
954#else
955 CFStringRef value = NULL ;
956 Size actualSize = 0 ;
957
958 verify_noerr( GetControlData( (ControlRef) m_macControl , 0, GetWindowStyle() & wxTE_PASSWORD ?
959 kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag,
960 sizeof(CFStringRef), &value, &actualSize ) );
961 if ( value )
962 {
963 wxMacCFStringHolder cf(value) ;
964 result = cf.AsString() ;
965 }
966#endif
967 wxMacConvertNewlines10To13( &result ) ;
968 return result ;
969}
970
971void wxTextCtrl::GetSelection(long* from, long* to) const
972{
973#if wxMAC_USE_MLTE
974 TXNGetSelection( (TXNObject) m_macTXN , (TXNOffset*) from , (TXNOffset*) to ) ;
975#else
976 ControlEditTextSelectionRec sel ;
977 Size actualSize ;
978 verify_noerr( GetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag,
979 sizeof(ControlEditTextSelectionRec), &sel, &actualSize ) );
980 if ( from ) *from = sel.selStart ;
981 if ( to ) *to = sel.selEnd ;
982#endif
983}
984
985void wxTextCtrl::SetValue(const wxString& str)
986{
987 // optimize redraws
988 if ( GetValue() == str )
989 return ;
990
991 wxString st = str ;
992 wxMacConvertNewlines13To10( &st ) ;
993#if wxMAC_USE_MLTE
994 {
995 wxMacWindowClipper c( this ) ;
996 bool formerEditable = m_editable ;
997 if ( !formerEditable )
998 SetEditable(true) ;
999
1000#if !wxMAC_USE_MLTE_HIVIEW
1001 // otherwise scrolling might have problems ?
1002 TPUpdateVisibility( ( (STPTextPaneVars *)m_macTXNvars)->fUserPaneRec ) ;
1003#endif
1004 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ;
1005 TXNSetSelection( (TXNObject) m_macTXN, 0, 0);
1006 TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
1007 if ( !formerEditable )
1008 SetEditable(formerEditable) ;
1009 }
1010#else
1011 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
1012 CFStringRef value = cf ;
1013 verify_noerr( SetControlData( (ControlRef) m_macControl , 0, GetWindowStyle() & wxTE_PASSWORD ?
1014 kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag,
1015 sizeof(CFStringRef), &value ) );
1016#endif
1017}
1018
1019void wxTextCtrl::SetMaxLength(unsigned long len)
1020{
1021 m_maxLength = len ;
1022}
1023
1024bool wxTextCtrl::SetFont( const wxFont& font )
1025{
1026 if ( !wxTextCtrlBase::SetFont( font ) )
1027 return FALSE ;
1028
1029#if wxMAC_USE_MLTE
1030 wxMacWindowClipper c( this ) ;
1031 bool formerEditable = m_editable ;
1032 if ( !formerEditable )
1033 SetEditable(true) ;
1034
1035 TXNTypeAttributes typeAttr[4] ;
1036 Str255 fontName = "\pMonaco" ;
1037 SInt16 fontSize = 12 ;
1038 Style fontStyle = normal ;
1039 int attrCounter = 0 ;
1040
1041 wxMacStringToPascal( font.GetFaceName() , fontName ) ;
1042 fontSize = font.MacGetFontSize() ;
1043 fontStyle = font.MacGetFontStyle() ;
1044
1045 typeAttr[attrCounter].tag = kTXNQDFontNameAttribute ;
1046 typeAttr[attrCounter].size = kTXNQDFontNameAttributeSize ;
1047 typeAttr[attrCounter].data.dataPtr = (void*) fontName ;
1048 typeAttr[attrCounter+1].tag = kTXNQDFontSizeAttribute ;
1049 typeAttr[attrCounter+1].size = kTXNFontSizeAttributeSize ;
1050 typeAttr[attrCounter+1].data.dataValue = (fontSize << 16) ;
1051 typeAttr[attrCounter+2].tag = kTXNQDFontStyleAttribute ;
1052 typeAttr[attrCounter+2].size = kTXNQDFontStyleAttributeSize ;
1053 typeAttr[attrCounter+2].data.dataValue = fontStyle ;
1054 attrCounter += 3 ;
1055 /*
1056 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1057 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1058 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1059 color = MAC_WXCOLORREF(GetForegroundColour().GetPixel()) ;
1060 attrCounter += 1 ;
1061 */
1062 verify_noerr( TXNSetTypeAttributes ((TXNObject)m_macTXN, attrCounter , typeAttr, kTXNStartOffset,kTXNEndOffset) );
1063
1064 if ( !formerEditable )
1065 SetEditable(formerEditable) ;
1066#endif
1067 return true ;
1068}
1069
1070bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
1071{
1072#if wxMAC_USE_MLTE
1073 bool formerEditable = m_editable ;
1074 if ( !formerEditable )
1075 SetEditable(true) ;
1076 TXNTypeAttributes typeAttr[4] ;
1077 Str255 fontName = "\pMonaco" ;
1078 SInt16 fontSize = 12 ;
1079 Style fontStyle = normal ;
1080 RGBColor color ;
1081 int attrCounter = 0 ;
1082 if ( style.HasFont() )
1083 {
1084 const wxFont &font = style.GetFont() ;
1085 wxMacStringToPascal( font.GetFaceName() , fontName ) ;
1086 fontSize = font.GetPointSize() ;
1087 if ( font.GetUnderlined() )
1088 fontStyle |= underline ;
1089 if ( font.GetWeight() == wxBOLD )
1090 fontStyle |= bold ;
1091 if ( font.GetStyle() == wxITALIC )
1092 fontStyle |= italic ;
1093
1094 typeAttr[attrCounter].tag = kTXNQDFontNameAttribute ;
1095 typeAttr[attrCounter].size = kTXNQDFontNameAttributeSize ;
1096 typeAttr[attrCounter].data.dataPtr = (void*) fontName ;
1097 typeAttr[attrCounter+1].tag = kTXNQDFontSizeAttribute ;
1098 typeAttr[attrCounter+1].size = kTXNFontSizeAttributeSize ;
1099 typeAttr[attrCounter+1].data.dataValue = (fontSize << 16) ;
1100 typeAttr[attrCounter+2].tag = kTXNQDFontStyleAttribute ;
1101 typeAttr[attrCounter+2].size = kTXNQDFontStyleAttributeSize ;
1102 typeAttr[attrCounter+2].data.dataValue = fontStyle ;
1103 attrCounter += 3 ;
1104
1105 }
1106 if ( style.HasTextColour() )
1107 {
1108 typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
1109 typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
1110 typeAttr[attrCounter].data.dataPtr = (void*) &color ;
1111 color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ;
1112 attrCounter += 1 ;
1113 }
1114
1115 if ( attrCounter > 0 )
1116 {
1117 verify_noerr( TXNSetTypeAttributes ((TXNObject)m_macTXN, attrCounter , typeAttr, start,end) );
1118 }
1119 if ( !formerEditable )
1120 SetEditable(formerEditable) ;
1121#endif
1122 return TRUE ;
1123}
1124
1125bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style)
1126{
1127 wxTextCtrlBase::SetDefaultStyle( style ) ;
1128 SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
1129 return TRUE ;
1130}
1131
1132// Clipboard operations
1133void wxTextCtrl::Copy()
1134{
1135 if (CanCopy())
1136 {
1137#if wxMAC_USE_MLTE
1138 ClearCurrentScrap();
1139 TXNCopy((TXNObject)m_macTXN);
1140 TXNConvertToPublicScrap();
1141#endif
1142 }
1143}
1144
1145void wxTextCtrl::Cut()
1146{
1147 if (CanCut())
1148 {
1149#if wxMAC_USE_MLTE
1150 ClearCurrentScrap();
1151 TXNCut((TXNObject)m_macTXN);
1152 TXNConvertToPublicScrap();
1153#endif
1154 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1155 event.SetString( GetValue() ) ;
1156 event.SetEventObject( this );
1157 GetEventHandler()->ProcessEvent(event);
1158 }
1159}
1160
1161void wxTextCtrl::Paste()
1162{
1163 if (CanPaste())
1164 {
1165#if wxMAC_USE_MLTE
1166 TXNConvertFromPublicScrap();
1167 TXNPaste((TXNObject)m_macTXN);
1168 SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
1169#endif
1170 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1171 event.SetString( GetValue() ) ;
1172 event.SetEventObject( this );
1173 GetEventHandler()->ProcessEvent(event);
1174 }
1175}
1176
1177bool wxTextCtrl::CanCopy() const
1178{
1179 // Can copy if there's a selection
1180 long from, to;
1181 GetSelection(& from, & to);
1182 return (from != to);
1183}
1184
1185bool wxTextCtrl::CanCut() const
1186{
1187 if ( !IsEditable() )
1188 {
1189 return false ;
1190 }
1191 // Can cut if there's a selection
1192 long from, to;
1193 GetSelection(& from, & to);
1194 return (from != to);
1195}
1196
1197bool wxTextCtrl::CanPaste() const
1198{
1199 if (!IsEditable())
1200 return FALSE;
1201
1202#if wxMAC_USE_MLTE
1203 return TXNIsScrapPastable() ;
1204#else
1205 return true ;
1206#endif
1207}
1208
1209void wxTextCtrl::SetEditable(bool editable)
1210{
1211 if ( editable != m_editable )
1212 {
1213 m_editable = editable ;
1214#if wxMAC_USE_MLTE
1215 TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
1216 TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ;
1217 TXNSetTXNObjectControls( (TXNObject) m_macTXN , false , sizeof(tag) / sizeof (TXNControlTag) , tag , data ) ;
1218#endif
1219 }
1220}
1221
1222void wxTextCtrl::SetInsertionPoint(long pos)
1223{
1224 SetSelection( pos , pos ) ;
1225}
1226
1227void wxTextCtrl::SetInsertionPointEnd()
1228{
1229 long pos = GetLastPosition();
1230 SetInsertionPoint(pos);
1231}
1232
1233long wxTextCtrl::GetInsertionPoint() const
1234{
1235 long begin,end ;
1236 GetSelection( &begin , &end ) ;
1237 return begin ;
1238}
1239
1240long wxTextCtrl::GetLastPosition() const
1241{
1242 long actualsize = 0 ;
1243#if wxMAC_USE_MLTE
1244 Handle theText ;
1245 OSErr err = TXNGetDataEncoded( (TXNObject) m_macTXN, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
1246 /* all done */
1247 if ( err )
1248 {
1249 actualsize = 0 ;
1250 }
1251 else
1252 {
1253 actualsize = GetHandleSize( theText ) ;
1254 DisposeHandle( theText ) ;
1255 }
1256#endif
1257 return actualsize ;
1258}
1259
1260void wxTextCtrl::Replace(long from, long to, const wxString& str)
1261{
1262#if wxMAC_USE_MLTE
1263 wxString value = str ;
1264 wxMacConvertNewlines13To10( &value ) ;
1265
1266 bool formerEditable = m_editable ;
1267 if ( !formerEditable )
1268 SetEditable(true) ;
1269 TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
1270 TXNClear( ((TXNObject) m_macTXN) ) ;
1271 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , str , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
1272 if ( !formerEditable )
1273 SetEditable( formerEditable ) ;
1274
1275 Refresh() ;
1276#endif
1277}
1278
1279void wxTextCtrl::Remove(long from, long to)
1280{
1281#if wxMAC_USE_MLTE
1282 bool formerEditable = m_editable ;
1283 if ( !formerEditable )
1284 SetEditable(true) ;
1285 TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
1286 TXNClear( ((TXNObject) m_macTXN) ) ;
1287 if ( !formerEditable )
1288 SetEditable( formerEditable ) ;
1289
1290 Refresh() ;
1291#endif
1292}
1293
1294void wxTextCtrl::SetSelection(long from, long to)
1295{
1296#if wxMAC_USE_MLTE
1297 /* change the selection */
1298 if ((from == -1) && (to == -1))
1299 TXNSelectAll((TXNObject) m_macTXN);
1300 else
1301 TXNSetSelection( (TXNObject) m_macTXN, from, to);
1302 TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
1303#else
1304 ControlEditTextSelectionRec sel ;
1305 sel.selStart = from ;
1306 sel.selEnd = to ;
1307 verify_noerr( SetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag,
1308 sizeof(ControlEditTextSelectionRec), &sel ) );
1309
1310#endif
1311}
1312
1313bool wxTextCtrl::LoadFile(const wxString& file)
1314{
1315 if ( wxTextCtrlBase::LoadFile(file) )
1316 {
1317 return TRUE;
1318 }
1319
1320 return FALSE;
1321}
1322
1323class wxMacFunctor
1324{
1325public :
1326 wxMacFunctor(){}
1327 virtual ~wxMacFunctor() {}
1328 virtual void* operator()() = 0 ;
1329 static void* CallBackProc(void *param)
1330 {
1331 wxMacFunctor* f = (wxMacFunctor*) param ;
1332 void *result = (*f)() ;
1333 return result ;
1334 }
1335} ;
1336
1337template<typename classtype,typename param1type>
1338class wxMacObjectFunctor1 : public wxMacFunctor
1339{
1340 typedef void (classtype::*function)( param1type p1 ) ;
1341 typedef void (classtype::*ref_function)( const param1type& p1 ) ;
1342public :
1343 wxMacObjectFunctor1( classtype *obj , function f , param1type p1 ) :
1344 wxMacFunctor( )
1345 {
1346 m_object = obj ;
1347 m_function = f ;
1348 m_param1 = p1 ;
1349 }
1350
1351 wxMacObjectFunctor1( classtype *obj , ref_function f , param1type p1 ) :
1352 wxMacFunctor( )
1353 {
1354 m_object = obj ;
1355 m_refFunction = f ;
1356 m_param1 = p1 ;
1357 }
1358
1359 ~wxMacObjectFunctor1() {}
1360
1361 virtual void* operator()()
1362 {
1363 (m_object->*m_function)(m_param1) ;
1364 return NULL ;
1365 }
1366private :
1367 classtype* m_object ;
1368 param1type m_param1 ;
1369 union
1370 {
1371 function m_function ;
1372 ref_function m_refFunction ;
1373 } ;
1374} ;
1375
1376template<typename classtype, typename param1type>
1377void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
1378{
1379 wxMacObjectFunctor1<classtype,param1type> params(object,function,p1) ;
1380 void *result =
1381 MPRemoteCall( wxMacFunctor::CallBackProc , &params , kMPOwningProcessRemoteContext ) ;
1382 return result ;
1383}
1384
1385template<typename classtype, typename param1type>
1386void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
1387{
1388 wxMacObjectFunctor1<classtype,param1type> params(object,function,p1) ;
1389 void *result =
1390 MPRemoteCall( wxMacFunctor::CallBackProc , &params , kMPOwningProcessRemoteContext ) ;
1391 return result ;
1392}
1393
1394template<typename classtype, typename param1type>
1395void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
1396{
1397 wxMutexGuiLeave() ;
1398 void *result = wxMacMPRemoteCall( object , function , p1 ) ;
1399 wxMutexGuiEnter() ;
1400 return result ;
1401}
1402
1403template<typename classtype, typename param1type>
1404void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
1405{
1406 wxMutexGuiLeave() ;
1407 void *result = wxMacMPRemoteCall( object , function , p1 ) ;
1408 wxMutexGuiEnter() ;
1409 return result ;
1410}
1411
1412void wxTextCtrl::WriteText(const wxString& str)
1413{
1414 if ( !wxIsMainThread() )
1415 {
1416 wxMacMPRemoteGUICall( this , &wxTextCtrl::WriteText , str ) ;
1417 return ;
1418 }
1419 else
1420 {
1421 wxString st = str ;
1422 wxMacConvertNewlines13To10( &st ) ;
1423 #if wxMAC_USE_MLTE
1424 bool formerEditable = m_editable ;
1425 if ( !formerEditable )
1426 SetEditable(true) ;
1427 {
1428 wxMacWindowStateSaver s( this ) ;
1429 long start , end , dummy ;
1430 GetSelection( &start , &dummy ) ;
1431 SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
1432 GetSelection( &dummy , &end ) ;
1433 SetStyle( start , end , GetDefaultStyle() ) ;
1434 }
1435 if ( !formerEditable )
1436 SetEditable( formerEditable ) ;
1437
1438 MacRedrawControl() ;
1439 #else
1440 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1441 wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
1442 CFStringRef value = cf ;
1443 SetControlData( (ControlRef) m_macControl , 0, kControlEditTextInsertCFStringRefTag,
1444 sizeof(CFStringRef), &value );
1445 #else
1446 wxString val = GetValue() ;
1447 long start , end ;
1448 GetSelection( &start , &end ) ;
1449 val.Remove( start , end - start ) ;
1450 val.insert( start , str ) ;
1451 SetValue( val ) ;
1452 #endif
1453 #endif
1454 }
1455}
1456
1457void wxTextCtrl::AppendText(const wxString& text)
1458{
1459 SetInsertionPointEnd();
1460 WriteText(text);
1461}
1462
1463void wxTextCtrl::Clear()
1464{
1465#if wxMAC_USE_MLTE
1466 bool formerEditable = m_editable ;
1467 if ( !formerEditable )
1468 SetEditable(true) ;
1469 TXNSetSelection( (TXNObject)m_macTXN , kTXNStartOffset , kTXNEndOffset ) ;
1470 TXNClear((TXNObject)m_macTXN);
1471
1472 if ( !formerEditable )
1473 SetEditable( formerEditable ) ;
1474
1475 Refresh() ;
1476#else
1477 SetValue(wxEmptyString) ;
1478#endif
1479}
1480
1481bool wxTextCtrl::IsModified() const
1482{
1483 return m_dirty;
1484}
1485
1486bool wxTextCtrl::IsEditable() const
1487{
1488 return IsEnabled() && m_editable ;
1489}
1490
1491bool wxTextCtrl::AcceptsFocus() const
1492{
1493 // we don't want focus if we can't be edited
1494 return /*IsEditable() && */ wxControl::AcceptsFocus();
1495}
1496
1497wxSize wxTextCtrl::DoGetBestSize() const
1498{
1499 int wText = 100 ;
1500
1501 int hText;
1502
1503 switch( m_windowVariant )
1504 {
1505 case wxWINDOW_VARIANT_NORMAL :
1506 hText = 22 ;
1507 break ;
1508 case wxWINDOW_VARIANT_SMALL :
1509 hText = 19 ;
1510 break ;
1511 case wxWINDOW_VARIANT_MINI :
1512 hText= 15 ;
1513 break ;
1514 default :
1515 hText = 22 ;
1516 break ;
1517 }
1518
1519 if ( m_windowStyle & wxTE_MULTILINE )
1520 {
1521 hText *= 5 ;
1522 }
1523
1524 return wxSize(wText, hText);
1525}
1526
1527// ----------------------------------------------------------------------------
1528// Undo/redo
1529// ----------------------------------------------------------------------------
1530
1531void wxTextCtrl::Undo()
1532{
1533 if (CanUndo())
1534 {
1535#if wxMAC_USE_MLTE
1536 TXNUndo((TXNObject)m_macTXN);
1537#endif
1538 }
1539}
1540
1541void wxTextCtrl::Redo()
1542{
1543 if (CanRedo())
1544 {
1545#if wxMAC_USE_MLTE
1546 TXNRedo((TXNObject)m_macTXN);
1547#endif
1548 }
1549}
1550
1551bool wxTextCtrl::CanUndo() const
1552{
1553 if ( !IsEditable() )
1554 {
1555 return false ;
1556 }
1557#if wxMAC_USE_MLTE
1558 return TXNCanUndo((TXNObject)m_macTXN,NULL);
1559#else
1560 return false ;
1561#endif
1562}
1563
1564bool wxTextCtrl::CanRedo() const
1565{
1566 if ( !IsEditable() )
1567 {
1568 return false ;
1569 }
1570#if wxMAC_USE_MLTE
1571 return TXNCanRedo((TXNObject)m_macTXN,NULL);
1572#else
1573 return false ;
1574#endif
1575}
1576
1577// Makes modifie or unmodified
1578void wxTextCtrl::MarkDirty()
1579{
1580 m_dirty = true;
1581}
1582
1583void wxTextCtrl::DiscardEdits()
1584{
1585 m_dirty = false;
1586}
1587
1588int wxTextCtrl::GetNumberOfLines() const
1589{
1590 ItemCount lines = 0 ;
1591#if wxMAC_USE_MLTE
1592 TXNGetLineCount((TXNObject)m_macTXN, &lines ) ;
1593#endif
1594 return lines ;
1595}
1596
1597long wxTextCtrl::XYToPosition(long x, long y) const
1598{
1599#if wxMAC_USE_MLTE
1600 Point curpt ;
1601
1602 long lastpos = GetLastPosition() ;
1603
1604 // TODO find a better implementation : while we can get the
1605 // line metrics of a certain line, we don't get its starting
1606 // position, so it would probably be rather a binary search
1607 // for the start position
1608 long xpos = 0 ;
1609 long ypos = 0 ;
1610 int lastHeight = 0 ;
1611
1612 ItemCount n ;
1613 for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
1614 {
1615 if ( y == ypos && x == xpos )
1616 return n ;
1617
1618 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1619
1620 if ( curpt.v > lastHeight )
1621 {
1622 xpos = 0 ;
1623 if ( n > 0 )
1624 ++ypos ;
1625 lastHeight = curpt.v ;
1626 }
1627 else
1628 ++xpos ;
1629 }
1630#endif
1631 return 0;
1632}
1633
1634bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
1635{
1636#if wxMAC_USE_MLTE
1637 Point curpt ;
1638
1639 long lastpos = GetLastPosition() ;
1640
1641 if ( y ) *y = 0 ;
1642 if ( x ) *x = 0 ;
1643
1644 if ( pos <= lastpos )
1645 {
1646 // TODO find a better implementation : while we can get the
1647 // line metrics of a certain line, we don't get its starting
1648 // position, so it would probably be rather a binary search
1649 // for the start position
1650 long xpos = 0 ;
1651 long ypos = 0 ;
1652 int lastHeight = 0 ;
1653
1654 ItemCount n ;
1655 for ( n = 0 ; n <= (ItemCount) pos ; ++n )
1656 {
1657 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1658
1659 if ( curpt.v > lastHeight )
1660 {
1661 xpos = 0 ;
1662 if ( n > 0 )
1663 ++ypos ;
1664 lastHeight = curpt.v ;
1665 }
1666 else
1667 ++xpos ;
1668 }
1669 if ( y ) *y = ypos ;
1670 if ( x ) *x = xpos ;
1671 }
1672#else
1673 if ( y ) *y = 0 ;
1674 if ( x ) *x = 0 ;
1675#endif
1676 return FALSE ;
1677}
1678
1679void wxTextCtrl::ShowPosition(long pos)
1680{
1681#if wxMAC_USE_MLTE
1682#if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
1683 {
1684 Point current ;
1685 Point desired ;
1686 TXNOffset selstart , selend ;
1687 TXNGetSelection( (TXNObject) m_macTXN , &selstart , &selend) ;
1688 TXNOffsetToPoint( (TXNObject) m_macTXN, selstart , &current);
1689 TXNOffsetToPoint( (TXNObject) m_macTXN, pos , &desired);
1690 //TODO use HIPoints for 10.3 and above
1691 if ( (UInt32) TXNScroll != (UInt32) kUnresolvedCFragSymbolAddress )
1692 {
1693 OSErr theErr = noErr;
1694 SInt32 dv = desired.v - current.v ;
1695 SInt32 dh = desired.h - current.h ;
1696 TXNShowSelection( (TXNObject) m_macTXN , true ) ;
1697 theErr = TXNScroll( (TXNObject) m_macTXN, kTXNScrollUnitsInPixels , kTXNScrollUnitsInPixels , &dv , &dh );
1698 wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") );
1699 }
1700 }
1701#endif
1702#endif
1703}
1704
1705int wxTextCtrl::GetLineLength(long lineNo) const
1706{
1707#if wxMAC_USE_MLTE
1708 Point curpt ;
1709 if ( lineNo < GetNumberOfLines() )
1710 {
1711 // TODO find a better implementation : while we can get the
1712 // line metrics of a certain line, we don't get its starting
1713 // position, so it would probably be rather a binary search
1714 // for the start position
1715 long xpos = 0 ;
1716 long ypos = 0 ;
1717 int lastHeight = 0 ;
1718 long lastpos = GetLastPosition() ;
1719
1720 ItemCount n ;
1721 for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
1722 {
1723 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1724
1725 if ( curpt.v > lastHeight )
1726 {
1727 if ( ypos == lineNo )
1728 return xpos ;
1729
1730 xpos = 0 ;
1731 if ( n > 0 )
1732 ++ypos ;
1733 lastHeight = curpt.v ;
1734 }
1735 else
1736 ++xpos ;
1737 }
1738 }
1739#endif
1740 return 0;
1741}
1742
1743wxString wxTextCtrl::GetLineText(long lineNo) const
1744{
1745 wxString line ;
1746#if wxMAC_USE_MLTE
1747 Point curpt ;
1748 wxString content = GetValue() ;
1749
1750 if ( lineNo < GetNumberOfLines() )
1751 {
1752 // TODO find a better implementation : while we can get the
1753 // line metrics of a certain line, we don't get its starting
1754 // position, so it would probably be rather a binary search
1755 // for the start position
1756 long xpos = 0 ;
1757 long ypos = 0 ;
1758 int lastHeight = 0 ;
1759 long lastpos = GetLastPosition() ;
1760
1761 ItemCount n ;
1762 for ( n = 0 ; n <= (ItemCount)lastpos ; ++n )
1763 {
1764 TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt);
1765
1766 if ( curpt.v > lastHeight )
1767 {
1768 if ( ypos == lineNo )
1769 return line ;
1770
1771 xpos = 0 ;
1772 if ( n > 0 )
1773 ++ypos ;
1774 lastHeight = curpt.v ;
1775 }
1776 else
1777 {
1778 if ( ypos == lineNo )
1779 line += content[n] ;
1780 ++xpos ;
1781 }
1782 }
1783 }
1784#endif
1785 return line ;
1786}
1787
1788/*
1789 * Text item
1790 */
1791
1792void wxTextCtrl::Command(wxCommandEvent & event)
1793{
1794 SetValue (event.GetString());
1795 ProcessCommand (event);
1796}
1797
1798void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
1799{
1800 // By default, load the first file into the text window.
1801 if (event.GetNumberOfFiles() > 0)
1802 {
1803 LoadFile(event.GetFiles()[0]);
1804 }
1805}
1806
1807void wxTextCtrl::OnChar(wxKeyEvent& event)
1808{
1809 int key = event.GetKeyCode() ;
1810 bool eat_key = false ;
1811
1812 if ( key == 'c' && event.MetaDown() )
1813 {
1814 if ( CanCopy() )
1815 Copy() ;
1816 return ;
1817 }
1818
1819 if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
1820 !( key == WXK_RETURN && ( (m_windowStyle & wxPROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
1821/* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1822 )
1823 {
1824 // eat it
1825 return ;
1826 }
1827
1828 // assume that any key not processed yet is going to modify the control
1829 m_dirty = true;
1830
1831 if ( key == 'v' && event.MetaDown() )
1832 {
1833 if ( CanPaste() )
1834 Paste() ;
1835 return ;
1836 }
1837 if ( key == 'x' && event.MetaDown() )
1838 {
1839 if ( CanCut() )
1840 Cut() ;
1841 return ;
1842 }
1843 switch ( key )
1844 {
1845 case WXK_RETURN:
1846 if (m_windowStyle & wxPROCESS_ENTER)
1847 {
1848 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
1849 event.SetEventObject( this );
1850 event.SetString( GetValue() );
1851 if ( GetEventHandler()->ProcessEvent(event) )
1852 return;
1853 }
1854 if ( !(m_windowStyle & wxTE_MULTILINE) )
1855 {
1856 wxWindow *parent = GetParent();
1857 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
1858 parent = parent->GetParent() ;
1859 }
1860 if ( parent && parent->GetDefaultItem() )
1861 {
1862 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
1863 wxButton);
1864 if ( def && def->IsEnabled() )
1865 {
1866 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
1867 event.SetEventObject(def);
1868 def->Command(event);
1869 return ;
1870 }
1871 }
1872
1873 // this will make wxWindows eat the ENTER key so that
1874 // we actually prevent line wrapping in a single line
1875 // text control
1876 eat_key = TRUE;
1877 }
1878
1879 break;
1880
1881 case WXK_TAB:
1882 // always produce navigation event - even if we process TAB
1883 // ourselves the fact that we got here means that the user code
1884 // decided to skip processing of this TAB - probably to let it
1885 // do its default job.
1886 {
1887 wxNavigationKeyEvent eventNav;
1888 eventNav.SetDirection(!event.ShiftDown());
1889 eventNav.SetWindowChange(event.ControlDown());
1890 eventNav.SetEventObject(this);
1891
1892 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
1893 return;
1894
1895 event.Skip() ;
1896 return;
1897 }
1898 break;
1899 }
1900
1901 if (!eat_key)
1902 {
1903 // perform keystroke handling
1904 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
1905 CallNextEventHandler((EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
1906 else
1907 {
1908 EventRecord rec ;
1909 if ( wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) )
1910 {
1911 EventRecord *ev = &rec ;
1912 short keycode ;
1913 short keychar ;
1914 keychar = short(ev->message & charCodeMask);
1915 keycode = short(ev->message & keyCodeMask) >> 8 ;
1916
1917 ::HandleControlKey( (ControlRef) m_macControl , keycode , keychar , ev->modifiers ) ;
1918 }
1919 }
1920 }
1921 if ( ( key >= 0x20 && key < WXK_START ) ||
1922 key == WXK_RETURN ||
1923 key == WXK_DELETE ||
1924 key == WXK_BACK)
1925 {
1926 wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1927 event1.SetString( GetValue() ) ;
1928 event1.SetEventObject( this );
1929 wxPostEvent(GetEventHandler(),event1);
1930 }
1931}
1932
1933// ----------------------------------------------------------------------------
1934// standard handlers for standard edit menu events
1935// ----------------------------------------------------------------------------
1936
1937void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
1938{
1939 Cut();
1940}
1941
1942void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
1943{
1944 Copy();
1945}
1946
1947void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
1948{
1949 Paste();
1950}
1951
1952void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
1953{
1954 Undo();
1955}
1956
1957void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
1958{
1959 Redo();
1960}
1961
1962void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
1963{
1964 event.Enable( CanCut() );
1965}
1966
1967void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
1968{
1969 event.Enable( CanCopy() );
1970}
1971
1972void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
1973{
1974 event.Enable( CanPaste() );
1975}
1976
1977void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
1978{
1979 event.Enable( CanUndo() );
1980}
1981
1982void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
1983{
1984 event.Enable( CanRedo() );
1985}
1986
1987bool wxTextCtrl::MacSetupCursor( const wxPoint& pt )
1988{
1989 return true ;
1990}
1991
1992// user pane implementation
1993
1994void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part)
1995{
1996}
1997
1998wxInt16 wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
1999{
2000 return kControlNoPart ;
2001}
2002
2003wxInt16 wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
2004{
2005 return kControlNoPart ;
2006}
2007
2008void wxTextCtrl::MacControlUserPaneIdleProc()
2009{
2010}
2011
2012wxInt16 wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
2013{
2014 return kControlNoPart ;
2015}
2016
2017void wxTextCtrl::MacControlUserPaneActivateProc(bool activating)
2018{
2019}
2020
2021wxInt16 wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action)
2022{
2023 return kControlNoPart ;
2024}
2025
2026void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info)
2027{
2028}
2029
2030#endif
2031 // wxUSE_TEXTCTRL