]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/textctrl.cpp
initial value set
[wxWidgets.git] / src / mac / carbon / textctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: textctrl.cpp
3 // Purpose: wxTextCtrl
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
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 #include <fstream.h>
27
28 #include "wx/app.h"
29 #include "wx/dc.h"
30 #include "wx/button.h"
31 #include "wx/toplevel.h"
32 #include "wx/textctrl.h"
33 #include "wx/notebook.h"
34 #include "wx/tabctrl.h"
35 #include "wx/settings.h"
36 #include "wx/filefn.h"
37 #include "wx/utils.h"
38
39 #if defined(__BORLANDC__) && !defined(__WIN32__)
40 #include <alloc.h>
41 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
42 #include <malloc.h>
43 #endif
44
45 #ifndef __DARWIN__
46 #include <Scrap.h>
47 #endif
48 #include <MacTextEditor.h>
49 #include "ATSUnicode.h"
50 #include "TextCommon.h"
51 #include "TextEncodingConverter.h"
52 #include "wx/mac/uma.h"
53
54 extern wxApp *wxTheApp ;
55
56 // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
57 // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
58 // moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
59 // an alternate path for carbon key events that routes automatically into the same wx flow of events
60
61 #include "MacTextEditor.h"
62
63 /* part codes */
64
65 /* kmUPTextPart is the part code we return to indicate the user has clicked
66 in the text area of our control */
67 #define kmUPTextPart 1
68
69 /* kmUPScrollPart is the part code we return to indicate the user has clicked
70 in the scroll bar part of the control. */
71 #define kmUPScrollPart 2
72
73
74 /* routines for using existing user pane controls.
75 These routines are useful for cases where you would like to use an
76 existing user pane control in, say, a dialog window as a scrolling
77 text edit field.*/
78
79 /* mUPOpenControl initializes a user pane control so it will be drawn
80 and will behave as a scrolling text edit field inside of a window.
81 This routine performs all of the initialization steps necessary,
82 except it does not create the user pane control itself. theControl
83 should refer to a user pane control that you have either created
84 yourself or extracted from a dialog's control heirarchy using
85 the GetDialogItemAsControl routine. */
86 OSStatus mUPOpenControl(ControlHandle theControl, bool multiline);
87
88 /* Utility Routines */
89
90 enum {
91 kShiftKeyCode = 56
92 };
93
94 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
95 routine. In our focus switching routine this part code is understood
96 as meaning 'the user has clicked in the control and we need to switch
97 the current focus to ourselves before we can continue'. */
98 #define kUserClickedToFocusPart 100
99
100
101 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
102 slow the speed of 'auto scrolling' inside of our clickloop routine.
103 This value prevents the text from wizzzzzing by while the mouse
104 is being held down inside of the text area. */
105 #define kmUPClickScrollDelayTicks 3
106
107
108 /* STPTextPaneVars is a structure used for storing the the mUP Control's
109 internal variables and state information. A handle to this record is
110 stored in the pane control's reference value field using the
111 SetControlReference routine. */
112
113 typedef struct {
114 /* OS records referenced */
115 TXNObject fTXNRec; /* the txn record */
116 TXNFrameID fTXNFrame; /* the txn frame ID */
117 ControlHandle fUserPaneRec; /* handle to the user pane control */
118 WindowPtr fOwner; /* window containing control */
119 GrafPtr fDrawingEnvironment; /* grafport where control is drawn */
120 /* flags */
121 Boolean fInFocus; /* true while the focus rect is drawn around the control */
122 Boolean fIsActive; /* true while the control is drawn in the active state */
123 Boolean fTEActive; /* reflects the activation state of the text edit record */
124 Boolean fInDialogWindow; /* true if displayed in a dialog window */
125 /* calculated locations */
126 Rect fRTextArea; /* area where the text is drawn */
127 Rect fRFocusOutline; /* rectangle used to draw the focus box */
128 Rect fRTextOutline; /* rectangle used to draw the border */
129 RgnHandle fTextBackgroundRgn; /* background region for the text, erased before calling TEUpdate */
130 /* our focus advance override routine */
131 EventHandlerUPP handlerUPP;
132 EventHandlerRef handlerRef;
133 bool fMultiline ;
134 } STPTextPaneVars;
135
136
137
138
139 /* Univerals Procedure Pointer variables used by the
140 mUP Control. These variables are set up
141 the first time that mUPOpenControl is called. */
142 ControlUserPaneDrawUPP gTPDrawProc = NULL;
143 ControlUserPaneHitTestUPP gTPHitProc = NULL;
144 ControlUserPaneTrackingUPP gTPTrackProc = NULL;
145 ControlUserPaneIdleUPP gTPIdleProc = NULL;
146 ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
147 ControlUserPaneActivateUPP gTPActivateProc = NULL;
148 ControlUserPaneFocusUPP gTPFocusProc = NULL;
149
150 /* TPActivatePaneText activates or deactivates the text edit record
151 according to the value of setActive. The primary purpose of this
152 routine is to ensure each call is only made once. */
153 static void TPActivatePaneText(STPTextPaneVars **tpvars, Boolean setActive) {
154 STPTextPaneVars *varsp;
155 varsp = *tpvars;
156 if (varsp->fTEActive != setActive) {
157
158 varsp->fTEActive = setActive;
159
160 TXNActivate(varsp->fTXNRec, varsp->fTXNFrame, varsp->fTEActive);
161
162 if (varsp->fInFocus)
163 TXNFocus( varsp->fTXNRec, varsp->fTEActive);
164 }
165 }
166
167
168 /* TPFocusPaneText set the focus state for the text record. */
169 static void TPFocusPaneText(STPTextPaneVars **tpvars, Boolean setFocus) {
170 STPTextPaneVars *varsp;
171 varsp = *tpvars;
172 if (varsp->fInFocus != setFocus) {
173 varsp->fInFocus = setFocus;
174 TXNFocus( varsp->fTXNRec, varsp->fInFocus);
175 }
176 }
177
178
179 /* TPPaneDrawProc is called to redraw the control and for update events
180 referring to the control. This routine erases the text area's background,
181 and redraws the text. This routine assumes the scroll bar has been
182 redrawn by a call to DrawControls. */
183 static pascal void TPPaneDrawProc(ControlRef theControl, ControlPartCode thePart) {
184 STPTextPaneVars **tpvars, *varsp;
185 char state;
186 Rect bounds;
187 /* set up our globals */
188 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
189 if (tpvars != NULL) {
190 state = HGetState((Handle) tpvars);
191 HLock((Handle) tpvars);
192 varsp = *tpvars;
193
194 /* save the drawing state */
195 SetPort((**tpvars).fDrawingEnvironment);
196 /* verify our boundary */
197 GetControlBounds(theControl, &bounds);
198 if ( ! EqualRect(&bounds, &varsp->fRFocusOutline) ) {
199 // scrollbar is on the border, we add one
200 Rect oldbounds = varsp->fRFocusOutline ;
201 InsetRect( &oldbounds , -1 , -1 ) ;
202
203 InvalWindowRect( GetControlOwner( theControl ) , &oldbounds ) ;
204 SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
205 SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
206 SetRect(&varsp->fRTextArea, bounds.left + 2 , bounds.top + (varsp->fMultiline ? 0 : 2) ,
207 bounds.right - (varsp->fMultiline ? 0 : 2), bounds.bottom - (varsp->fMultiline ? 0 : 2));
208 RectRgn(varsp->fTextBackgroundRgn, &varsp->fRTextOutline);
209 TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left,
210 varsp->fRTextArea.bottom, varsp->fRTextArea.right, varsp->fTXNFrame);
211 }
212
213 /* update the text region */
214 RGBColor white = { 65535 , 65535 , 65535 } ;
215 RGBBackColor( &white ) ;
216 EraseRgn(varsp->fTextBackgroundRgn);
217 TXNDraw(varsp->fTXNRec, NULL);
218 /* restore the drawing environment */
219 /* draw the text frame and focus frame (if necessary) */
220 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
221 if ((**tpvars).fIsActive && varsp->fInFocus) DrawThemeFocusRect(&varsp->fRFocusOutline, true);
222 /* release our globals */
223 HSetState((Handle) tpvars, state);
224 }
225 }
226
227
228 /* TPPaneHitTestProc is called when the control manager would
229 like to determine what part of the control the mouse resides over.
230 We also call this routine from our tracking proc to determine how
231 to handle mouse clicks. */
232 static pascal ControlPartCode TPPaneHitTestProc(ControlHandle theControl, Point where) {
233 STPTextPaneVars **tpvars;
234 ControlPartCode result;
235 char state;
236 /* set up our locals and lock down our globals*/
237 result = 0;
238 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
239 if (tpvars != NULL) {
240 state = HGetState((Handle) tpvars);
241 HLock((Handle) tpvars);
242 /* find the region where we clicked */
243 if (PtInRect(where, &(**tpvars).fRTextArea)) {
244 result = kmUPTextPart;
245 } else result = 0;
246 /* release oure globals */
247 HSetState((Handle) tpvars, state);
248 }
249 return result;
250 }
251
252
253
254
255
256 /* TPPaneTrackingProc is called when the mouse is being held down
257 over our control. This routine handles clicks in the text area
258 and in the scroll bar. */
259 static pascal ControlPartCode TPPaneTrackingProc(ControlHandle theControl, Point startPt, ControlActionUPP actionProc) {
260 STPTextPaneVars **tpvars, *varsp;
261 char state;
262 ControlPartCode partCodeResult;
263 /* make sure we have some variables... */
264 partCodeResult = 0;
265 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
266 if (tpvars != NULL) {
267 /* lock 'em down */
268 state = HGetState((Handle) tpvars);
269 HLock((Handle) tpvars);
270 varsp = *tpvars;
271 /* we don't do any of these functions unless we're in focus */
272 if ( ! varsp->fInFocus) {
273 WindowPtr owner;
274 owner = GetControlOwner(theControl);
275 ClearKeyboardFocus(owner);
276 SetKeyboardFocus(owner, theControl, kUserClickedToFocusPart);
277 }
278 /* find the location for the click */
279 switch (TPPaneHitTestProc(theControl, startPt)) {
280
281 /* handle clicks in the text part */
282 case kmUPTextPart:
283 { SetPort((**tpvars).fDrawingEnvironment);
284 TXNClick( varsp->fTXNRec, (const EventRecord*) wxTheApp->MacGetCurrentEvent());
285 }
286 break;
287
288 }
289
290 HSetState((Handle) tpvars, state);
291 }
292 return partCodeResult;
293 }
294
295
296 /* TPPaneIdleProc is our user pane idle routine. When our text field
297 is active and in focus, we use this routine to set the cursor. */
298 static pascal void TPPaneIdleProc(ControlHandle theControl) {
299 STPTextPaneVars **tpvars, *varsp;
300 /* set up locals */
301 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
302 if (tpvars != NULL) {
303 /* if we're not active, then we have nothing to say about the cursor */
304 if ((**tpvars).fIsActive) {
305 char state;
306 Rect bounds;
307 Point mousep;
308 /* lock down the globals */
309 state = HGetState((Handle) tpvars);
310 HLock((Handle) tpvars);
311 varsp = *tpvars;
312 /* get the current mouse coordinates (in our window) */
313 SetPortWindowPort(GetControlOwner(theControl));
314 GetMouse(&mousep);
315 /* there's a 'focus thing' and an 'unfocused thing' */
316 if (varsp->fInFocus) {
317 /* flash the cursor */
318 SetPort((**tpvars).fDrawingEnvironment);
319 TXNIdle(varsp->fTXNRec);
320 /* set the cursor */
321 if (PtInRect(mousep, &varsp->fRTextArea)) {
322 RgnHandle theRgn;
323 RectRgn((theRgn = NewRgn()), &varsp->fRTextArea);
324 TXNAdjustCursor(varsp->fTXNRec, theRgn);
325 DisposeRgn(theRgn);
326 } else SetThemeCursor(kThemeArrowCursor);
327 } else {
328 /* if it's in our bounds, set the cursor */
329 GetControlBounds(theControl, &bounds);
330 if (PtInRect(mousep, &bounds))
331 SetThemeCursor(kThemeArrowCursor);
332 }
333
334 HSetState((Handle) tpvars, state);
335 }
336 }
337 }
338
339
340 /* TPPaneKeyDownProc is called whenever a keydown event is directed
341 at our control. Here, we direct the keydown event to the text
342 edit record and redraw the scroll bar and text field as appropriate. */
343 static pascal ControlPartCode TPPaneKeyDownProc(ControlHandle theControl,
344 SInt16 keyCode, SInt16 charCode, SInt16 modifiers) {
345 STPTextPaneVars **tpvars;
346 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
347 if (tpvars != NULL) {
348 if ((**tpvars).fInFocus) {
349 /* turn autoscrolling on and send the key event to text edit */
350 SetPort((**tpvars).fDrawingEnvironment);
351 EventRecord ev ;
352 memset( &ev , 0 , sizeof( ev ) ) ;
353 ev.what = keyDown ;
354 ev.modifiers = modifiers ;
355 ev.message = (( keyCode & keyCodeMask ) << 8 ) + ( charCode & charCodeMask ) ;
356 TXNKeyDown( (**tpvars).fTXNRec, &ev);
357 }
358 }
359 return kControlEntireControl;
360 }
361
362
363 /* TPPaneActivateProc is called when the window containing
364 the user pane control receives activate events. Here, we redraw
365 the control and it's text as necessary for the activation state. */
366 static pascal void TPPaneActivateProc(ControlHandle theControl, Boolean activating) {
367 Rect bounds;
368 STPTextPaneVars **tpvars, *varsp;
369 char state;
370 /* set up locals */
371 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
372 if (tpvars != NULL) {
373 state = HGetState((Handle) tpvars);
374 HLock((Handle) tpvars);
375 varsp = *tpvars;
376 /* de/activate the text edit record */
377 SetPort((**tpvars).fDrawingEnvironment);
378 GetControlBounds(theControl, &bounds);
379 varsp->fIsActive = activating;
380 TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
381 /* redraw the frame */
382 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
383 if (varsp->fInFocus) DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive);
384 HSetState((Handle) tpvars, state);
385 }
386 }
387
388
389 /* TPPaneFocusProc is called when every the focus changes to or
390 from our control. Herein, switch the focus appropriately
391 according to the parameters and redraw the control as
392 necessary. */
393 static pascal ControlPartCode TPPaneFocusProc(ControlHandle theControl, ControlFocusPart action) {
394 ControlPartCode focusResult;
395 STPTextPaneVars **tpvars, *varsp;
396 char state;
397 /* set up locals */
398 focusResult = kControlFocusNoPart;
399 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
400 if (tpvars != NULL) {
401 state = HGetState((Handle) tpvars);
402 HLock((Handle) tpvars);
403 varsp = *tpvars;
404 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
405 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
406 and kControlFocusNextPart will be received. When the user clicks in our field
407 and it is not the current focus, then the constant kUserClickedToFocusPart will
408 be received. The constant kControlFocusNoPart will be received when our control
409 is the current focus and the user clicks in another control. In your focus routine,
410 you should respond to these codes as follows:
411
412 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
413 the control and the focus rectangle as necessary.
414
415 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
416 depending on its current state. redraw the control and the focus rectangle
417 as appropriate for the new focus state. If the focus state is 'off', return the constant
418 kControlFocusNoPart, otherwise return a non-zero part code.
419 kUserClickedToFocusPart - is a constant defined for this example. You should
420 define your own value for handling click-to-focus type events. */
421 /* save the drawing state */
422 SetPort((**tpvars).fDrawingEnvironment);
423 /* calculate the next highlight state */
424 switch (action) {
425 default:
426 case kControlFocusNoPart:
427 TPFocusPaneText(tpvars, false);
428 focusResult = kControlFocusNoPart;
429 break;
430 case kUserClickedToFocusPart:
431 TPFocusPaneText(tpvars, true);
432 focusResult = 1;
433 break;
434 case kControlFocusPrevPart:
435 case kControlFocusNextPart:
436 TPFocusPaneText(tpvars, ( ! varsp->fInFocus));
437 focusResult = varsp->fInFocus ? 1 : kControlFocusNoPart;
438 break;
439 }
440 TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
441 /* redraw the text fram and focus rectangle to indicate the
442 new focus state */
443 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
444 DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive && varsp->fInFocus);
445 /* done */
446 HSetState((Handle) tpvars, state);
447 }
448 return focusResult;
449 }
450
451
452 /* mUPOpenControl initializes a user pane control so it will be drawn
453 and will behave as a scrolling text edit field inside of a window.
454 This routine performs all of the initialization steps necessary,
455 except it does not create the user pane control itself. theControl
456 should refer to a user pane control that you have either created
457 yourself or extracted from a dialog's control heirarchy using
458 the GetDialogItemAsControl routine. */
459 OSStatus mUPOpenControl(ControlHandle theControl, bool multiline)
460 {
461 Rect bounds;
462 WindowRef theWindow;
463 STPTextPaneVars **tpvars, *varsp;
464 OSStatus err;
465 RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF};
466 TXNBackground tback;
467
468 /* set up our globals */
469 if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(TPPaneDrawProc);
470 if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(TPPaneHitTestProc);
471 if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(TPPaneTrackingProc);
472 if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(TPPaneIdleProc);
473 if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc);
474 if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(TPPaneActivateProc);
475 if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(TPPaneFocusProc);
476
477 /* allocate our private storage */
478 tpvars = (STPTextPaneVars **) NewHandleClear(sizeof(STPTextPaneVars));
479 SetControlReference(theControl, (long) tpvars);
480 HLock((Handle) tpvars);
481 varsp = *tpvars;
482 /* set the initial settings for our private data */
483 varsp->fMultiline = multiline ;
484 varsp->fInFocus = false;
485 varsp->fIsActive = true;
486 varsp->fTEActive = true; // in order to get a deactivate
487 varsp->fUserPaneRec = theControl;
488 theWindow = varsp->fOwner = GetControlOwner(theControl);
489
490 varsp->fDrawingEnvironment = (GrafPtr) GetWindowPort(theWindow);
491
492 varsp->fInDialogWindow = ( GetWindowKind(varsp->fOwner) == kDialogWindowKind );
493 /* set up the user pane procedures */
494 SetControlData(theControl, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
495 SetControlData(theControl, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
496 SetControlData(theControl, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
497 SetControlData(theControl, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
498 SetControlData(theControl, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
499 SetControlData(theControl, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
500 SetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
501 /* calculate the rectangles used by the control */
502 GetControlBounds(theControl, &bounds);
503 SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
504 SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
505 SetRect(&varsp->fRTextArea, bounds.left + 2 , bounds.top + (varsp->fMultiline ? 0 : 2) ,
506 bounds.right - (varsp->fMultiline ? 0 : 2), bounds.bottom - (varsp->fMultiline ? 0 : 2));
507 /* calculate the background region for the text. In this case, it's kindof
508 and irregular region because we're setting the scroll bar a little ways inside
509 of the text area. */
510 RectRgn((varsp->fTextBackgroundRgn = NewRgn()), &varsp->fRTextOutline);
511
512 /* set up the drawing environment */
513 SetPort(varsp->fDrawingEnvironment);
514
515 /* create the new edit field */
516 TXNNewObject(NULL, varsp->fOwner, &varsp->fRTextArea,
517 ( multiline ? kTXNWantVScrollBarMask : 0 ) |
518 kTXNDontDrawCaretWhenInactiveMask |
519 kTXNDontDrawSelectionWhenInactiveMask |
520 kTXNAlwaysWrapAtViewEdgeMask,
521 kTXNTextEditStyleFrameType,
522 kTXNTextensionFile,
523 kTXNSystemDefaultEncoding,
524 &varsp->fTXNRec, &varsp->fTXNFrame, (TXNObjectRefcon) tpvars);
525
526 Str255 fontName ;
527 SInt16 fontSize ;
528 Style fontStyle ;
529
530 GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
531
532 TXNTypeAttributes typeAttr[] =
533 {
534 { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } ,
535 { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } ,
536 { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } ,
537 } ;
538
539 OSStatus status = TXNSetTypeAttributes (varsp->fTXNRec, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr,
540 kTXNStartOffset,
541 kTXNEndOffset);
542 /* set the field's background */
543 tback.bgType = kTXNBackgroundTypeRGB;
544 tback.bg.color = rgbWhite;
545 TXNSetBackground( varsp->fTXNRec, &tback);
546
547 /* unlock our storage */
548 HUnlock((Handle) tpvars);
549 /* perform final activations and setup for our text field. Here,
550 we assume that the window is going to be the 'active' window. */
551 TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
552 /* all done */
553 return noErr;
554 }
555
556
557
558
559 #if !USE_SHARED_LIBRARY
560 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
561
562 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
563 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
564 EVT_CHAR(wxTextCtrl::OnChar)
565 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
566 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
567 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
568 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
569 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
570
571 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
572 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
573 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
574 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
575 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
576 END_EVENT_TABLE()
577 #endif
578
579 // Text item
580 wxTextCtrl::wxTextCtrl()
581 {
582 m_macTE = NULL ;
583 m_macTXN = NULL ;
584 m_macTXNvars = NULL ;
585 m_macUsesTXN = false ;
586 m_editable = true ;
587 }
588
589 wxTextCtrl::~wxTextCtrl()
590 {
591 if ( m_macUsesTXN )
592 {
593 SetControlReference((ControlHandle)m_macControl, 0) ;
594 TXNDeleteObject((TXNObject)m_macTXN);
595 /* delete our private storage */
596 DisposeHandle((Handle) m_macTXNvars);
597 /* zero the control reference */
598 }
599 }
600
601 const short kVerticalMargin = 2 ;
602 const short kHorizontalMargin = 2 ;
603
604 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
605 const wxString& st,
606 const wxPoint& pos,
607 const wxSize& size, long style,
608 const wxValidator& validator,
609 const wxString& name)
610 {
611 m_macTE = NULL ;
612 m_macTXN = NULL ;
613 m_macTXNvars = NULL ;
614 m_macUsesTXN = false ;
615 m_editable = true ;
616
617 m_macUsesTXN = ! (style & wxTE_PASSWORD ) ;
618
619 m_macUsesTXN &= (TXNInitTextension != (void*) kUnresolvedCFragSymbolAddress) ;
620
621 // base initialization
622 if ( !CreateBase(parent, id, pos, size, style, validator, name) )
623 return FALSE;
624
625 wxSize mySize = size ;
626 if ( m_macUsesTXN )
627 {
628 m_macHorizontalBorder = 5 ; // additional pixels around the real control
629 m_macVerticalBorder = 3 ;
630 }
631 else
632 {
633 m_macHorizontalBorder = 5 ; // additional pixels around the real control
634 m_macVerticalBorder = 5 ;
635 }
636
637
638 Rect bounds ;
639 Str255 title ;
640 /*
641 if ( mySize.y == -1 )
642 {
643 mySize.y = 13 ;
644 if ( m_windowStyle & wxTE_MULTILINE )
645 mySize.y *= 5 ;
646
647 mySize.y += 2 * m_macVerticalBorder ;
648 }
649 */
650 MacPreControlCreate( parent , id , "" , pos , mySize ,style, validator , name , &bounds , title ) ;
651
652 if ( m_windowStyle & wxTE_MULTILINE )
653 {
654 wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
655 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
656
657 m_windowStyle |= wxTE_PROCESS_ENTER;
658 }
659
660
661 if ( !m_macUsesTXN )
662 {
663 m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , "\p" , true , 0 , 0 , 1,
664 (style & wxTE_PASSWORD) ? kControlEditTextPasswordProc : kControlEditTextProc , (long) this ) ;
665 long size ;
666 ::GetControlData((ControlHandle) m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &((TEHandle) m_macTE) , &size ) ;
667
668 }
669 else
670 {
671 short featurSet;
672
673 featurSet = kControlSupportsEmbedding | kControlSupportsFocus // | kControlWantsIdle
674 | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground
675 | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
676 /* create the control */
677 m_macControl = NewControl(MAC_WXHWND(parent->MacGetRootWindow()), &bounds, "\p", true, featurSet, 0, featurSet, kControlUserPaneProc, 0);
678 /* set up the mUP specific features and data */
679 mUPOpenControl((ControlHandle) m_macControl, m_windowStyle & wxTE_MULTILINE );
680 if ( parent )
681 {
682 parent->MacGetTopLevelWindow()->MacInstallEventHandler() ;
683 }
684 }
685 MacPostControlCreate() ;
686
687 wxString value ;
688
689 if( wxApp::s_macDefaultEncodingIsPC )
690 value = wxMacMakeMacStringFromPC( st ) ;
691 else
692 value = st ;
693
694 if ( !m_macUsesTXN )
695 {
696 ::SetControlData( (ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
697 }
698 else
699 {
700 STPTextPaneVars **tpvars;
701 /* set up locals */
702 tpvars = (STPTextPaneVars **) GetControlReference((ControlHandle) m_macControl);
703 /* set the text in the record */
704 TXNSetData( (**tpvars).fTXNRec, kTXNTextData, (void*)value.c_str(), value.Length(),
705 kTXNStartOffset, kTXNEndOffset);
706 m_macTXN = (**tpvars).fTXNRec ;
707 m_macTXNvars = tpvars ;
708 m_macUsesTXN = true ;
709 }
710
711 return TRUE;
712 }
713
714 wxString wxTextCtrl::GetValue() const
715 {
716 Size actualsize;
717 if ( !m_macUsesTXN )
718 {
719 ::GetControlData( (ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
720 }
721 else
722 {
723 Handle theText ;
724 OSStatus err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
725 /* all done */
726 if ( err )
727 {
728 actualsize = 0 ;
729 }
730 else
731 {
732 actualsize = GetHandleSize( theText ) ;
733 if (actualsize != 0)
734 strncpy( wxBuffer , *theText , actualsize ) ;
735 DisposeHandle( theText ) ;
736 }
737 }
738 wxBuffer[actualsize] = 0 ;
739 if( wxApp::s_macDefaultEncodingIsPC )
740 return wxMacMakePCStringFromMac( wxBuffer ) ;
741 else
742 return wxString(wxBuffer);
743 }
744
745 void wxTextCtrl::GetSelection(long* from, long* to) const
746 {
747 if ( !m_macUsesTXN )
748 {
749 *from = (**((TEHandle) m_macTE)).selStart;
750 *to = (**((TEHandle) m_macTE)).selEnd;
751 }
752 else
753 {
754 TXNGetSelection( ((TXNObject) m_macTXN) , (TXNOffset*) from , (TXNOffset*) to ) ;
755 }
756 }
757
758 void wxTextCtrl::SetValue(const wxString& st)
759 {
760 wxString value ;
761
762 if( wxApp::s_macDefaultEncodingIsPC )
763 value = wxMacMakeMacStringFromPC( st ) ;
764 else
765 value = st ;
766 if ( !m_macUsesTXN )
767 {
768 ::SetControlData((ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
769 }
770 else
771 {
772 TXNSetData( ((TXNObject) m_macTXN), kTXNTextData, (void*)value.c_str(), value.Length(),
773 kTXNStartOffset, kTXNEndOffset);
774 }
775 MacRedrawControl() ;
776 }
777
778 // Clipboard operations
779 void wxTextCtrl::Copy()
780 {
781 if (CanCopy())
782 {
783 if ( !m_macUsesTXN )
784 {
785 TECopy( ((TEHandle) m_macTE) ) ;
786 ClearCurrentScrap();
787 TEToScrap() ;
788 MacRedrawControl() ;
789 }
790 else
791 {
792 ClearCurrentScrap();
793 TXNCopy((TXNObject)m_macTXN);
794 TXNConvertToPublicScrap();
795 }
796 }
797 }
798
799 void wxTextCtrl::Cut()
800 {
801 if (CanCut())
802 {
803 if ( !m_macUsesTXN )
804 {
805 TECut( ((TEHandle) m_macTE) ) ;
806 ClearCurrentScrap();
807 TEToScrap() ;
808 MacRedrawControl() ;
809 }
810 else
811 {
812 ClearCurrentScrap();
813 TXNCut((TXNObject)m_macTXN);
814 TXNConvertToPublicScrap();
815 }
816 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
817 event.SetString( GetValue() ) ;
818 event.SetEventObject( this );
819 GetEventHandler()->ProcessEvent(event);
820 }
821 }
822
823 void wxTextCtrl::Paste()
824 {
825 if (CanPaste())
826 {
827 if ( !m_macUsesTXN )
828 {
829 TEFromScrap() ;
830 TEPaste( (TEHandle) m_macTE ) ;
831 MacRedrawControl() ;
832 }
833 else
834 {
835 TXNConvertFromPublicScrap();
836 TXNPaste((TXNObject)m_macTXN);
837 }
838 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
839 event.SetString( GetValue() ) ;
840 event.SetEventObject( this );
841 GetEventHandler()->ProcessEvent(event);
842 }
843 }
844
845 bool wxTextCtrl::CanCopy() const
846 {
847 // Can copy if there's a selection
848 long from, to;
849 GetSelection(& from, & to);
850 return (from != to);
851 }
852
853 bool wxTextCtrl::CanCut() const
854 {
855 if ( !IsEditable() )
856 {
857 return false ;
858 }
859 // Can cut if there's a selection
860 long from, to;
861 GetSelection(& from, & to);
862 return (from != to);
863 }
864
865 bool wxTextCtrl::CanPaste() const
866 {
867 if (!IsEditable())
868 return FALSE;
869
870 long offset ;
871 #if TARGET_CARBON
872 OSStatus err = noErr;
873 ScrapRef scrapRef;
874
875 err = GetCurrentScrap( &scrapRef );
876 if ( err != noTypeErr && err != memFullErr )
877 {
878 ScrapFlavorFlags flavorFlags;
879 Size byteCount;
880
881 if (( err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags )) == noErr)
882 {
883 if (( err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount )) == noErr)
884 {
885 return TRUE ;
886 }
887 }
888 }
889 return FALSE;
890
891 #else
892 if ( GetScrap( NULL , 'TEXT' , &offset ) > 0 )
893 {
894 return TRUE ;
895 }
896 #endif
897 return FALSE ;
898 }
899
900 void wxTextCtrl::SetEditable(bool editable)
901 {
902 if ( editable != m_editable )
903 {
904 m_editable = editable ;
905 if ( editable )
906 UMAActivateControl( (ControlHandle) m_macControl ) ;
907 else
908 UMADeactivateControl((ControlHandle) m_macControl ) ;
909 }
910 }
911
912 void wxTextCtrl::SetInsertionPoint(long pos)
913 {
914 SetSelection( pos , pos ) ;
915 }
916
917 void wxTextCtrl::SetInsertionPointEnd()
918 {
919 long pos = GetLastPosition();
920 SetInsertionPoint(pos);
921 }
922
923 long wxTextCtrl::GetInsertionPoint() const
924 {
925 long begin,end ;
926 GetSelection( &begin , &end ) ;
927 return begin ;
928 }
929
930 long wxTextCtrl::GetLastPosition() const
931 {
932 if ( !m_macUsesTXN )
933 {
934 return (**((TEHandle) m_macTE)).teLength ;
935 }
936 else
937 {
938 Handle theText ;
939 long actualsize ;
940 OSErr err = TXNGetDataEncoded( (TXNObject) m_macTXN, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
941 /* all done */
942 if ( err )
943 {
944 actualsize = 0 ;
945 }
946 else
947 {
948 actualsize = GetHandleSize( theText ) ;
949 DisposeHandle( theText ) ;
950 }
951 return actualsize ;
952 }
953 }
954
955 void wxTextCtrl::Replace(long from, long to, const wxString& value)
956 {
957 if ( !m_macUsesTXN )
958 {
959 ControlEditTextSelectionRec selection ;
960
961 selection.selStart = from ;
962 selection.selEnd = to ;
963 ::SetControlData((ControlHandle) m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
964 TESetSelect( from , to , ((TEHandle) m_macTE) ) ;
965 TEDelete( ((TEHandle) m_macTE) ) ;
966 TEInsert( value , value.Length() , ((TEHandle) m_macTE) ) ;
967 }
968 else
969 {
970 TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
971 TXNClear( ((TXNObject) m_macTXN) ) ;
972 TXNSetData( ((TXNObject) m_macTXN), kTXNTextData, (void*)value.c_str(), value.Length(),
973 kTXNUseCurrentSelection, kTXNUseCurrentSelection);
974 }
975 Refresh() ;
976 }
977
978 void wxTextCtrl::Remove(long from, long to)
979 {
980 if ( !m_macUsesTXN )
981 {
982 ControlEditTextSelectionRec selection ;
983
984 selection.selStart = from ;
985 selection.selEnd = to ;
986 ::SetControlData( (ControlHandle) m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
987 TEDelete( ((TEHandle) m_macTE) ) ;
988 }
989 else
990 {
991 TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
992 TXNClear( ((TXNObject) m_macTXN) ) ;
993 }
994 Refresh() ;
995 }
996
997 void wxTextCtrl::SetSelection(long from, long to)
998 {
999
1000 if ( !m_macUsesTXN )
1001 {
1002 ControlEditTextSelectionRec selection ;
1003 selection.selStart = from ;
1004 selection.selEnd = to ;
1005
1006 TESetSelect( selection.selStart , selection.selEnd , ((TEHandle) m_macTE) ) ;
1007 ::SetControlData((ControlHandle) m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
1008 }
1009 else
1010 {
1011 STPTextPaneVars **tpvars;
1012 /* set up our locals */
1013 tpvars = (STPTextPaneVars **) GetControlReference((ControlHandle) m_macControl);
1014 /* and our drawing environment as the operation
1015 may force a redraw in the text area. */
1016 SetPort((**tpvars).fDrawingEnvironment);
1017 /* change the selection */
1018 TXNSetSelection( (**tpvars).fTXNRec, from, to);
1019 }
1020 }
1021
1022 bool wxTextCtrl::LoadFile(const wxString& file)
1023 {
1024 if ( wxTextCtrlBase::LoadFile(file) )
1025 {
1026 return TRUE;
1027 }
1028
1029 return FALSE;
1030 }
1031
1032 void wxTextCtrl::WriteText(const wxString& text)
1033 {
1034 wxString value ;
1035 if( wxApp::s_macDefaultEncodingIsPC )
1036 value = wxMacMakeMacStringFromPC( text ) ;
1037 else
1038 value = text ;
1039 if ( !m_macUsesTXN )
1040 {
1041 TEInsert( value , value.Length() , ((TEHandle) m_macTE) ) ;
1042 }
1043 else
1044 {
1045 TXNSetData( ((TXNObject) m_macTXN), kTXNTextData, (void*) (const char*)value, value.Length(),
1046 kTXNUseCurrentSelection, kTXNUseCurrentSelection);
1047 }
1048 MacRedrawControl() ;
1049 }
1050
1051 void wxTextCtrl::AppendText(const wxString& text)
1052 {
1053 SetInsertionPointEnd();
1054 WriteText(text);
1055 }
1056
1057 void wxTextCtrl::Clear()
1058 {
1059 if ( !IsEditable() )
1060 {
1061 return ;
1062 }
1063 if ( !m_macUsesTXN )
1064 {
1065 ::SetControlData((ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 0 , (char*) ((const char*)NULL) ) ;
1066 }
1067 else
1068 {
1069 ClearCurrentScrap();
1070 TXNClear((TXNObject)m_macTXN);
1071 }
1072 Refresh() ;
1073 }
1074
1075 bool wxTextCtrl::IsModified() const
1076 {
1077 return TRUE;
1078 }
1079
1080 bool wxTextCtrl::IsEditable() const
1081 {
1082 return IsEnabled() && m_editable ;
1083 }
1084
1085 bool wxTextCtrl::AcceptsFocus() const
1086 {
1087 // we don't want focus if we can't be edited
1088 return /*IsEditable() && */ wxControl::AcceptsFocus();
1089 }
1090
1091 wxSize wxTextCtrl::DoGetBestSize() const
1092 {
1093 int wText = 100 ;
1094
1095 int hText;
1096 if ( m_macUsesTXN )
1097 {
1098 hText = 17 ;
1099 }
1100 else
1101 {
1102 hText = 13 ;
1103 }
1104 /*
1105 int cx, cy;
1106 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
1107
1108 int wText = DEFAULT_ITEM_WIDTH;
1109
1110 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
1111
1112 return wxSize(wText, hText);
1113 */
1114 if ( m_windowStyle & wxTE_MULTILINE )
1115 {
1116 hText *= 5 ;
1117 }
1118 hText += 2 * m_macVerticalBorder ;
1119 wText += 2 * m_macHorizontalBorder ;
1120 //else: for single line control everything is ok
1121 return wxSize(wText, hText);
1122 }
1123
1124 // ----------------------------------------------------------------------------
1125 // Undo/redo
1126 // ----------------------------------------------------------------------------
1127
1128 void wxTextCtrl::Undo()
1129 {
1130 if (CanUndo())
1131 {
1132 }
1133 }
1134
1135 void wxTextCtrl::Redo()
1136 {
1137 if (CanRedo())
1138 {
1139 }
1140 }
1141
1142 bool wxTextCtrl::CanUndo() const
1143 {
1144 return FALSE ;
1145 }
1146
1147 bool wxTextCtrl::CanRedo() const
1148 {
1149 return FALSE ;
1150 }
1151
1152 // Makes 'unmodified'
1153 void wxTextCtrl::DiscardEdits()
1154 {
1155 // TODO
1156 }
1157
1158 int wxTextCtrl::GetNumberOfLines() const
1159 {
1160 // TODO change this if possible to reflect real lines
1161 wxString content = GetValue() ;
1162
1163 int count = 1;
1164 for (int i = 0; i < content.Length() ; i++)
1165 {
1166 if (content[i] == '\r') count++;
1167 }
1168
1169 return count;
1170 }
1171
1172 long wxTextCtrl::XYToPosition(long x, long y) const
1173 {
1174 // TODO
1175 return 0;
1176 }
1177
1178 bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
1179 {
1180 return FALSE ;
1181 }
1182
1183 void wxTextCtrl::ShowPosition(long pos)
1184 {
1185 // TODO
1186 }
1187
1188 int wxTextCtrl::GetLineLength(long lineNo) const
1189 {
1190 // TODO change this if possible to reflect real lines
1191 wxString content = GetValue() ;
1192
1193 // Find line first
1194 int count = 0;
1195 for (int i = 0; i < content.Length() ; i++)
1196 {
1197 if (count == lineNo)
1198 {
1199 // Count chars in line then
1200 count = 0;
1201 for (int j = i; j < content.Length(); j++)
1202 {
1203 count++;
1204 if (content[j] == '\r') return count;
1205 }
1206
1207 return count;
1208 }
1209 if (content[i] == '\r') count++;
1210 }
1211 return 0;
1212 }
1213
1214 wxString wxTextCtrl::GetLineText(long lineNo) const
1215 {
1216 // TODO change this if possible to reflect real lines
1217 wxString content = GetValue() ;
1218
1219 // Find line first
1220 int count = 0;
1221 for (int i = 0; i < content.Length() ; i++)
1222 {
1223 if (count == lineNo)
1224 {
1225 // Add chars in line then
1226 wxString tmp("");
1227
1228 for (int j = i; j < content.Length(); j++)
1229 {
1230 if (content[j] == '\r')
1231 return tmp;
1232
1233 tmp += content[j];
1234 }
1235
1236 return tmp;
1237 }
1238 if (content[i] == '\r') count++;
1239 }
1240 return "" ;
1241 }
1242
1243 /*
1244 * Text item
1245 */
1246
1247 void wxTextCtrl::Command(wxCommandEvent & event)
1248 {
1249 SetValue (event.GetString());
1250 ProcessCommand (event);
1251 }
1252
1253 void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
1254 {
1255 // By default, load the first file into the text window.
1256 if (event.GetNumberOfFiles() > 0)
1257 {
1258 LoadFile(event.GetFiles()[0]);
1259 }
1260 }
1261
1262 void wxTextCtrl::OnChar(wxKeyEvent& event)
1263 {
1264 int key = event.GetKeyCode() ;
1265 bool eat_key = false ;
1266
1267 if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
1268 !( key == WXK_RETURN && ( (m_windowStyle & wxPROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
1269 /* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
1270 )
1271 {
1272 // eat it
1273 return ;
1274 }
1275 switch ( key )
1276 {
1277 case WXK_RETURN:
1278 if (m_windowStyle & wxPROCESS_ENTER)
1279 {
1280 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
1281 event.SetEventObject( this );
1282 event.SetString( GetValue() );
1283 if ( GetEventHandler()->ProcessEvent(event) )
1284 return;
1285 }
1286 if ( !(m_windowStyle & wxTE_MULTILINE) )
1287 {
1288 wxWindow *parent = GetParent();
1289 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
1290 parent = parent->GetParent() ;
1291 }
1292 if ( parent && parent->GetDefaultItem() )
1293 {
1294 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
1295 wxButton);
1296 if ( def && def->IsEnabled() )
1297 {
1298 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
1299 event.SetEventObject(def);
1300 def->Command(event);
1301 return ;
1302 }
1303 }
1304
1305 // this will make wxWindows eat the ENTER key so that
1306 // we actually prevent line wrapping in a single line
1307 // text control
1308 eat_key = TRUE;
1309 }
1310
1311 break;
1312
1313 case WXK_TAB:
1314 // always produce navigation event - even if we process TAB
1315 // ourselves the fact that we got here means that the user code
1316 // decided to skip processing of this TAB - probably to let it
1317 // do its default job.
1318 {
1319 wxNavigationKeyEvent eventNav;
1320 eventNav.SetDirection(!event.ShiftDown());
1321 eventNav.SetWindowChange(event.ControlDown());
1322 eventNav.SetEventObject(this);
1323
1324 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
1325 return;
1326
1327 event.Skip() ;
1328 return;
1329 }
1330 break;
1331 }
1332
1333 EventRecord *ev = (EventRecord*) wxTheApp->MacGetCurrentEvent();
1334 short keychar = short(ev->message & charCodeMask);
1335 if (!eat_key)
1336 {
1337 short keycode = short(ev->message & keyCodeMask) >> 8 ;
1338 ::HandleControlKey( (ControlHandle) m_macControl , keycode , keychar , ev->modifiers );
1339 }
1340 if ( keychar >= 0x20 ||
1341 event.KeyCode() == WXK_RETURN ||
1342 event.KeyCode() == WXK_DELETE ||
1343 event.KeyCode() == WXK_BACK)
1344 {
1345 wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
1346 event1.SetString( GetValue() ) ;
1347 event1.SetEventObject( this );
1348 GetEventHandler()->ProcessEvent(event1);
1349 }
1350 }
1351
1352 // ----------------------------------------------------------------------------
1353 // standard handlers for standard edit menu events
1354 // ----------------------------------------------------------------------------
1355
1356 void wxTextCtrl::OnCut(wxCommandEvent& event)
1357 {
1358 Cut();
1359 }
1360
1361 void wxTextCtrl::OnCopy(wxCommandEvent& event)
1362 {
1363 Copy();
1364 }
1365
1366 void wxTextCtrl::OnPaste(wxCommandEvent& event)
1367 {
1368 Paste();
1369 }
1370
1371 void wxTextCtrl::OnUndo(wxCommandEvent& event)
1372 {
1373 Undo();
1374 }
1375
1376 void wxTextCtrl::OnRedo(wxCommandEvent& event)
1377 {
1378 Redo();
1379 }
1380
1381 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
1382 {
1383 event.Enable( CanCut() );
1384 }
1385
1386 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
1387 {
1388 event.Enable( CanCopy() );
1389 }
1390
1391 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
1392 {
1393 event.Enable( CanPaste() );
1394 }
1395
1396 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
1397 {
1398 event.Enable( CanUndo() );
1399 }
1400
1401 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
1402 {
1403 event.Enable( CanRedo() );
1404 }
1405
1406
1407
1408 #endif
1409 // wxUSE_TEXTCTRL