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