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