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