]> git.saurik.com Git - wxWidgets.git/blob - src/mac/textctrl.cpp
corrections for theme brush alignments under X (no more SetOrigin calls)
[wxWidgets.git] / src / mac / textctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: textctrl.cpp
3 // Purpose: wxTextCtrl
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "textctrl.h"
14 #endif
15
16 #include "wx/defs.h"
17
18 #if wxUSE_TEXTCTRL
19
20 #ifdef __DARWIN__
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #else
24 #include <stat.h>
25 #endif
26 #include <fstream.h>
27
28 #include "wx/app.h"
29 #include "wx/dc.h"
30 #include "wx/button.h"
31 #include "wx/toplevel.h"
32 #include "wx/textctrl.h"
33 #include "wx/notebook.h"
34 #include "wx/tabctrl.h"
35 #include "wx/settings.h"
36 #include "wx/filefn.h"
37 #include "wx/utils.h"
38
39 #if defined(__BORLANDC__) && !defined(__WIN32__)
40 #include <alloc.h>
41 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
42 #include <malloc.h>
43 #endif
44
45 #include "wx/mac/uma.h"
46
47 #define wxUSE_MLTE 0
48
49 #if wxUSE_MLTE == 0 // old textctrl implementation
50
51 #if !USE_SHARED_LIBRARY
52 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
53
54 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
55 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
56 EVT_CHAR(wxTextCtrl::OnChar)
57 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
58 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
59 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
60 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
61 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
62
63 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
64 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
65 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
66 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
67 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
68 END_EVENT_TABLE()
69 #endif
70
71 // Text item
72 wxTextCtrl::wxTextCtrl()
73 {
74 }
75
76 const short kVerticalMargin = 2 ;
77 const short kHorizontalMargin = 2 ;
78
79 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
80 const wxString& st,
81 const wxPoint& pos,
82 const wxSize& size, long style,
83 const wxValidator& validator,
84 const wxString& name)
85 {
86 // base initialization
87 if ( !CreateBase(parent, id, pos, size, style, validator, name) )
88 return FALSE;
89
90 wxSize mySize = size ;
91 if ( UMAHasAppearance() )
92 {
93 m_macHorizontalBorder = 5 ; // additional pixels around the real control
94 m_macVerticalBorder = 5 ;
95 }
96 else
97 {
98 m_macHorizontalBorder = 0 ; // additional pixels around the real control
99 m_macVerticalBorder = 0 ;
100 }
101
102
103 Rect bounds ;
104 Str255 title ;
105
106 if ( mySize.y == -1 )
107 {
108 if ( UMAHasAppearance() )
109 mySize.y = 13 ;
110 else
111 mySize.y = 24 ;
112
113 mySize.y += 2 * m_macVerticalBorder ;
114 }
115
116 MacPreControlCreate( parent , id , "" , pos , mySize ,style, validator , name , &bounds , title ) ;
117
118 if ( m_windowStyle & wxTE_MULTILINE )
119 {
120 wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
121 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
122
123 m_windowStyle |= wxTE_PROCESS_ENTER;
124 }
125
126
127 m_macControl = ::NewControl( parent->MacGetRootWindow() , &bounds , "\p" , true , 0 , 0 , 1,
128 ( style & wxTE_PASSWORD ) ? kControlEditTextPasswordProc : kControlEditTextProc , (long) this ) ;
129 MacPostControlCreate() ;
130
131 wxString value ;
132
133 {
134 TEHandle teH ;
135 long size ;
136
137 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
138 (*teH)->lineHeight = -1 ;
139 }
140
141 if( wxApp::s_macDefaultEncodingIsPC )
142 value = wxMacMakeMacStringFromPC( st ) ;
143 else
144 value = st ;
145 ::SetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
146
147 return TRUE;
148 }
149
150 wxString wxTextCtrl::GetValue() const
151 {
152 Size actualsize;
153 ::GetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
154 wxBuffer[actualsize] = 0 ;
155 if( wxApp::s_macDefaultEncodingIsPC )
156 return wxMacMakePCStringFromMac( wxBuffer ) ;
157 else
158 return wxString(wxBuffer);
159 }
160
161 void wxTextCtrl::GetSelection(long* from, long* to) const
162 {
163 ControlEditTextSelectionRec selection ;
164 TEHandle teH ;
165 long size ;
166
167 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
168
169 *from = (**teH).selStart;
170 *to = (**teH).selEnd;
171 }
172
173 void wxTextCtrl::SetValue(const wxString& st)
174 {
175 wxString value ;
176
177 if( wxApp::s_macDefaultEncodingIsPC )
178 value = wxMacMakeMacStringFromPC( st ) ;
179 else
180 value = st ;
181 ::SetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
182 WindowRef window = MacGetRootWindow() ;
183 if ( window )
184 {
185 wxWindow* win = wxFindWinFromMacWindow( window ) ;
186 if ( win )
187 {
188 wxMacDrawingHelper help( win ) ;
189 // the mac control manager always assumes to have the origin at 0,0
190
191 bool hasTabBehind = false ;
192 wxWindow* parent = GetParent() ;
193 while ( parent )
194 {
195 if( parent->IsTopLevel() )
196 {
197 // ::SetThemeWindowBackground( win->MacGetRootWindow() , kThemeBrushDialogBackgroundActive , false ) ;
198 break ;
199 }
200
201 if( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
202 {
203 if ( ((wxControl*)parent)->GetMacControl() )
204 SetUpControlBackground( ((wxControl*)parent)->GetMacControl() , -1 , true ) ;
205 break ;
206 }
207
208 parent = parent->GetParent() ;
209 }
210
211 UMADrawControl( m_macControl ) ;
212 // ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
213 }
214 }
215 }
216
217 // Clipboard operations
218 void wxTextCtrl::Copy()
219 {
220 if (CanCopy())
221 {
222 TEHandle teH ;
223 long size ;
224
225 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
226 TECopy( teH ) ;
227 ClearCurrentScrap();
228 TEToScrap() ;
229 }
230 }
231
232 void wxTextCtrl::Cut()
233 {
234 if (CanCut())
235 {
236 TEHandle teH ;
237 long size ;
238
239 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
240 TECut( teH ) ;
241 ClearCurrentScrap();
242 TEToScrap() ;
243 // MacInvalidateControl() ;
244 }
245 }
246
247 void wxTextCtrl::Paste()
248 {
249 if (CanPaste())
250 {
251 TEHandle teH ;
252 long size ;
253
254 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
255 TEFromScrap() ;
256 TEPaste( teH ) ;
257 WindowRef window = MacGetRootWindow() ;
258 if ( window )
259 {
260 wxWindow* win = wxFindWinFromMacWindow( window ) ;
261 if ( win )
262 {
263 wxMacDrawingHelper help( win ) ;
264 // the mac control manager always assumes to have the origin at 0,0
265
266 bool hasTabBehind = false ;
267 wxWindow* parent = GetParent() ;
268 while ( parent )
269 {
270 if( parent->IsTopLevel() )
271 {
272 // ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , kThemeBrushDialogBackgroundActive , false ) ;
273 break ;
274 }
275
276 if( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
277 {
278 if ( ((wxControl*)parent)->GetMacControl() )
279 SetUpControlBackground( ((wxControl*)parent)->GetMacControl() , -1 , true ) ;
280 break ;
281 }
282
283 parent = parent->GetParent() ;
284 }
285
286 UMADrawControl( m_macControl ) ;
287 // ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
288 }
289 }
290 }
291 }
292
293 bool wxTextCtrl::CanCopy() const
294 {
295 // Can copy if there's a selection
296 long from, to;
297 GetSelection(& from, & to);
298 return (from != to);
299 }
300
301 bool wxTextCtrl::CanCut() const
302 {
303 // Can cut if there's a selection
304 long from, to;
305 GetSelection(& from, & to);
306 return (from != to);
307 }
308
309 bool wxTextCtrl::CanPaste() const
310 {
311 if (!IsEditable())
312 return FALSE;
313
314 long offset ;
315 #if TARGET_CARBON
316 OSStatus err = noErr;
317 ScrapRef scrapRef;
318
319 err = GetCurrentScrap( &scrapRef );
320 if ( err != noTypeErr && err != memFullErr )
321 {
322 ScrapFlavorFlags flavorFlags;
323 Size byteCount;
324
325 if (( err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags )) == noErr)
326 {
327 if (( err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount )) == noErr)
328 {
329 return TRUE ;
330 }
331 }
332 }
333 return FALSE;
334
335 #else
336 if ( GetScrap( NULL , 'TEXT' , &offset ) > 0 )
337 {
338 return TRUE ;
339 }
340 #endif
341 return FALSE ;
342 }
343
344 void wxTextCtrl::SetEditable(bool editable)
345 {
346 if ( editable )
347 UMAActivateControl( m_macControl ) ;
348 else
349 UMADeactivateControl( m_macControl ) ;
350 }
351
352 void wxTextCtrl::SetInsertionPoint(long pos)
353 {
354 SetSelection( pos , pos ) ;
355 }
356
357 void wxTextCtrl::SetInsertionPointEnd()
358 {
359 long pos = GetLastPosition();
360 SetInsertionPoint(pos);
361 }
362
363 long wxTextCtrl::GetInsertionPoint() const
364 {
365 ControlEditTextSelectionRec selection ;
366 TEHandle teH ;
367 long size ;
368
369 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
370 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
371 return (**teH).selStart ;
372 }
373
374 long wxTextCtrl::GetLastPosition() const
375 {
376 ControlEditTextSelectionRec selection ;
377 TEHandle teH ;
378 long size ;
379
380 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
381
382 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
383 return (**teH).teLength ;
384 }
385
386 void wxTextCtrl::Replace(long from, long to, const wxString& value)
387 {
388 TEHandle teH ;
389 long size ;
390
391 ControlEditTextSelectionRec selection ;
392
393 selection.selStart = from ;
394 selection.selEnd = to ;
395 ::SetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
396 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
397 TESetSelect( from , to , teH ) ;
398 TEDelete( teH ) ;
399 TEInsert( value , value.Length() , teH ) ;
400 Refresh() ;
401 }
402
403 void wxTextCtrl::Remove(long from, long to)
404 {
405 TEHandle teH ;
406 long size ;
407
408 ControlEditTextSelectionRec selection ;
409
410 selection.selStart = from ;
411 selection.selEnd = to ;
412 ::SetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
413 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
414 TEDelete( teH ) ;
415 Refresh() ;
416 }
417
418 void wxTextCtrl::SetSelection(long from, long to)
419 {
420 ControlEditTextSelectionRec selection ;
421 TEHandle teH ;
422 long size ;
423
424 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
425
426 selection.selStart = from ;
427 selection.selEnd = to ;
428
429 ::SetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
430 TESetSelect( selection.selStart , selection.selEnd , teH ) ;
431 }
432
433 bool wxTextCtrl::LoadFile(const wxString& file)
434 {
435 if ( wxTextCtrlBase::LoadFile(file) )
436 {
437 return TRUE;
438 }
439
440 return FALSE;
441 }
442
443 void wxTextCtrl::WriteText(const wxString& text)
444 {
445 TEHandle teH ;
446 long size ;
447
448 memcpy( wxBuffer, text , text.Length() ) ;
449 wxBuffer[text.Length() ] = 0 ;
450 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
451
452 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
453
454 TEInsert( wxBuffer , strlen( wxBuffer) , teH ) ;
455 Refresh() ;
456 }
457
458 void wxTextCtrl::AppendText(const wxString& text)
459 {
460 SetInsertionPointEnd();
461 WriteText(text);
462 }
463
464 void wxTextCtrl::Clear()
465 {
466 ::SetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 0 , (char*) ((const char*)NULL) ) ;
467 Refresh() ;
468 }
469
470 bool wxTextCtrl::IsModified() const
471 {
472 return TRUE;
473 }
474
475 bool wxTextCtrl::IsEditable() const
476 {
477 return IsEnabled();
478 }
479
480 bool wxTextCtrl::AcceptsFocus() const
481 {
482 // we don't want focus if we can't be edited
483 return IsEditable() && wxControl::AcceptsFocus();
484 }
485
486 wxSize wxTextCtrl::DoGetBestSize() const
487 {
488 int wText = 100 ;
489
490 int hText ;
491 if ( UMAHasAppearance() )
492 hText = 13 ;
493 else
494 hText = 24 ;
495 hText += 2 * m_macHorizontalBorder ;
496 /*
497 int cx, cy;
498 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
499
500 int wText = DEFAULT_ITEM_WIDTH;
501
502 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
503
504 return wxSize(wText, hText);
505 */
506 if ( m_windowStyle & wxTE_MULTILINE )
507 {
508 hText *= wxMin(GetNumberOfLines(), 5);
509 }
510 //else: for single line control everything is ok
511 return wxSize(wText, hText);
512 }
513
514 // ----------------------------------------------------------------------------
515 // Undo/redo
516 // ----------------------------------------------------------------------------
517
518 void wxTextCtrl::Undo()
519 {
520 if (CanUndo())
521 {
522 }
523 }
524
525 void wxTextCtrl::Redo()
526 {
527 if (CanRedo())
528 {
529 }
530 }
531
532 bool wxTextCtrl::CanUndo() const
533 {
534 return FALSE ;
535 }
536
537 bool wxTextCtrl::CanRedo() const
538 {
539 return FALSE ;
540 }
541
542 // Makes 'unmodified'
543 void wxTextCtrl::DiscardEdits()
544 {
545 // TODO
546 }
547
548 int wxTextCtrl::GetNumberOfLines() const
549 {
550 Size actualsize;
551 ::GetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
552
553 int count = 1;
554 for (int i = 0; i < actualsize; i++)
555 {
556 if (wxBuffer[i] == '\r') count++;
557 }
558
559 return count;
560 }
561
562 long wxTextCtrl::XYToPosition(long x, long y) const
563 {
564 // TODO
565 return 0;
566 }
567
568 bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
569 {
570 return FALSE ;
571 }
572
573 void wxTextCtrl::ShowPosition(long pos)
574 {
575 // TODO
576 }
577
578 int wxTextCtrl::GetLineLength(long lineNo) const
579 {
580 Size actualsize;
581 ::GetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
582
583 // Find line first
584 int count = 0;
585 for (int i = 0; i < actualsize; i++)
586 {
587 if (count == lineNo)
588 {
589 // Count chars in line then
590 count = 0;
591 for (int j = i; j < actualsize; j++)
592 {
593 count++;
594 if (wxBuffer[j] == '\r') return count;
595 }
596
597 return count;
598 }
599 if (wxBuffer[i] == '\r') count++;
600 }
601
602 return 0;
603 }
604
605 wxString wxTextCtrl::GetLineText(long lineNo) const
606 {
607 Size actualsize;
608 ::GetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
609
610 // Find line first
611 int count = 0;
612 for (int i = 0; i < actualsize; i++)
613 {
614 if (count == lineNo)
615 {
616 // Add chars in line then
617 wxString tmp("");
618
619 for (int j = i; j < actualsize; j++)
620 {
621 if (wxBuffer[j] == '\r')
622 return tmp;
623
624 tmp += wxBuffer[j];
625 }
626
627 return tmp;
628 }
629 if (wxBuffer[i] == '\r') count++;
630 }
631
632 return wxString("");
633 }
634
635 /*
636 * Text item
637 */
638
639 void wxTextCtrl::Command(wxCommandEvent & event)
640 {
641 SetValue (event.GetString());
642 ProcessCommand (event);
643 }
644
645 void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
646 {
647 // By default, load the first file into the text window.
648 if (event.GetNumberOfFiles() > 0)
649 {
650 LoadFile(event.GetFiles()[0]);
651 }
652 }
653
654 void wxTextCtrl::OnChar(wxKeyEvent& key_event)
655 {
656 bool eat_key = FALSE;
657
658 switch ( key_event.KeyCode() )
659 {
660 case WXK_RETURN:
661 if (m_windowStyle & wxPROCESS_ENTER)
662 {
663 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
664 event.SetEventObject( this );
665 event.SetString( GetValue() );
666 if ( GetEventHandler()->ProcessEvent(event) )
667 return;
668 }
669 if ( !(m_windowStyle & wxTE_MULTILINE) )
670 {
671 wxWindow *parent = GetParent();
672 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
673 parent = parent->GetParent() ;
674 }
675 if ( parent && parent->GetDefaultItem() )
676 {
677 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
678 wxButton);
679 if ( def && def->IsEnabled() )
680 {
681 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
682 event.SetEventObject(def);
683 def->Command(event);
684 return ;
685 }
686 }
687
688 // this will make wxWindows eat the ENTER key so that
689 // we actually prevent line wrapping in a single line
690 // text control
691 eat_key = TRUE;
692 }
693
694 break;
695
696 case WXK_TAB:
697 // always produce navigation event - even if we process TAB
698 // ourselves the fact that we got here means that the user code
699 // decided to skip processing of this TAB - probably to let it
700 // do its default job.
701 {
702 wxNavigationKeyEvent eventNav;
703 eventNav.SetDirection(!key_event.ShiftDown());
704 eventNav.SetWindowChange(key_event.ControlDown());
705 eventNav.SetEventObject(this);
706
707 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
708 return;
709
710 key_event.Skip() ;
711 return;
712 }
713 break;
714 }
715
716 EventRecord *ev = wxTheApp->MacGetCurrentEvent();
717 short keychar = short(ev->message & charCodeMask);
718 if (!eat_key)
719 {
720 short keycode = short(ev->message & keyCodeMask) >> 8 ;
721 ::HandleControlKey( m_macControl , keycode , keychar , ev->modifiers );
722 }
723 if ( keychar >= 0x20 ||
724 key_event.KeyCode() == WXK_RETURN ||
725 key_event.KeyCode() == WXK_DELETE ||
726 key_event.KeyCode() == WXK_BACK)
727 {
728 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
729 event.SetString( GetValue() ) ;
730 event.SetEventObject( this );
731 GetEventHandler()->ProcessEvent(event);
732 }
733 }
734
735 // ----------------------------------------------------------------------------
736 // standard handlers for standard edit menu events
737 // ----------------------------------------------------------------------------
738
739 void wxTextCtrl::OnCut(wxCommandEvent& event)
740 {
741 Cut();
742 }
743
744 void wxTextCtrl::OnCopy(wxCommandEvent& event)
745 {
746 Copy();
747 }
748
749 void wxTextCtrl::OnPaste(wxCommandEvent& event)
750 {
751 Paste();
752 }
753
754 void wxTextCtrl::OnUndo(wxCommandEvent& event)
755 {
756 Undo();
757 }
758
759 void wxTextCtrl::OnRedo(wxCommandEvent& event)
760 {
761 Redo();
762 }
763
764 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
765 {
766 event.Enable( CanCut() );
767 }
768
769 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
770 {
771 event.Enable( CanCopy() );
772 }
773
774 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
775 {
776 event.Enable( CanPaste() );
777 }
778
779 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
780 {
781 event.Enable( CanUndo() );
782 }
783
784 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
785 {
786 event.Enable( CanRedo() );
787 }
788
789 #else
790
791 extern wxApp *wxTheApp ;
792 // CS:We will replace the TextEdit by using the MultiLanguageTextEngine based on the following code written by apple
793
794 /*
795 File: mUPControl.c
796
797 Description:
798 mUPControl implementation.
799
800 Copyright:
801 © Copyright 2000 Apple Computer, Inc. All rights reserved.
802
803 Disclaimer:
804 IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
805 ("Apple") in consideration of your agreement to the following terms, and your
806 use, installation, modification or redistribution of this Apple software
807 constitutes acceptance of these terms. If you do not agree with these terms,
808 please do not use, install, modify or redistribute this Apple software.
809
810 In consideration of your agreement to abide by the following terms, and subject
811 to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
812 copyrights in this original Apple software (the "Apple Software"), to use,
813 reproduce, modify and redistribute the Apple Software, with or without
814 modifications, in source and/or binary forms; provided that if you redistribute
815 the Apple Software in its entirety and without modifications, you must retain
816 this notice and the following text and disclaimers in all such redistributions of
817 the Apple Software. Neither the name, trademarks, service marks or logos of
818 Apple Computer, Inc. may be used to endorse or promote products derived from the
819 Apple Software without specific prior written permission from Apple. Except as
820 expressly stated in this notice, no other rights or licenses, express or implied,
821 are granted by Apple herein, including but not limited to any patent rights that
822 may be infringed by your derivative works or by other works in which the Apple
823 Software may be incorporated.
824
825 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
826 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
827 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
828 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
829 COMBINATION WITH YOUR PRODUCTS.
830
831 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
832 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
833 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
834 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
835 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
836 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
837 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
838
839 Change History (most recent first):
840 Fri, Jan 28, 2000 -- created
841 */
842
843 #include "MacTextEditor.h"
844
845 /* part codes */
846
847 /* kmUPTextPart is the part code we return to indicate the user has clicked
848 in the text area of our control */
849 #define kmUPTextPart 1
850
851 /* kmUPScrollPart is the part code we return to indicate the user has clicked
852 in the scroll bar part of the control. */
853 #define kmUPScrollPart 2
854
855
856 /* routines for using existing user pane controls.
857 These routines are useful for cases where you would like to use an
858 existing user pane control in, say, a dialog window as a scrolling
859 text edit field.*/
860
861 /* mUPOpenControl initializes a user pane control so it will be drawn
862 and will behave as a scrolling text edit field inside of a window.
863 This routine performs all of the initialization steps necessary,
864 except it does not create the user pane control itself. theControl
865 should refer to a user pane control that you have either created
866 yourself or extracted from a dialog's control heirarchy using
867 the GetDialogItemAsControl routine. */
868 OSStatus mUPOpenControl(ControlHandle theControl);
869
870 /* mUPCloseControl deallocates all of the structures allocated
871 by mUPOpenControl. */
872 OSStatus mUPCloseControl(ControlHandle theControl);
873
874
875
876 /* routines for creating new scrolling text user pane controls.
877 These routines allow you to create new scrolling text
878 user pane controls. */
879
880 /* mUPCreateControl creates a new user pane control and then it passes it
881 to mUPOpenControl to initialize it as a scrolling text user pane control. */
882 OSStatus mUPCreateControl(WindowPtr theWindow, Rect *bounds, ControlHandle *theControl);
883
884 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
885 OSStatus mUPDisposeControl(ControlHandle theControl);
886
887
888 /* Utility Routines */
889
890 /* mUPSetText replaces the contents of the selection with the unicode
891 text described by the text and count parameters:.
892 text = pointer to unicode text buffer
893 count = number of bytes in the buffer. */
894 OSStatus mUPSetText(ControlHandle theControl, char* text, long count);
895
896 /* mUPGetText returns the current text data being displayed inside of
897 the mUPControl. When noErr is returned, *theText contain a new
898 handle containing all of the Unicode text copied from the current
899 selection. It is the caller's responsibiliby to dispose of this handle. */
900 OSStatus mUPGetText(ControlHandle theControl, Handle *theText);
901
902
903 /* mUPSetSelection sets the text selection and autoscrolls the text view
904 so either the cursor or the selction is in the view. */
905 void mUPSetSelection(ControlHandle theControl, long selStart, long selEnd);
906
907
908
909 /* IsmUPControl returns true if theControl is not NULL
910 and theControl refers to a mUP Control. */
911 Boolean IsmUPControl(ControlHandle theControl);
912
913
914
915 /* Edit commands for mUP Controls. */
916 enum {
917 kmUPCut = 1,
918 kmUPCopy = 2,
919 kmUPPaste = 3,
920 kmUPClear = 4
921 };
922
923
924 /* mUPDoEditCommand performs the editing command specified
925 in the editCommand parameter. The mUPControl's text
926 and scroll bar are redrawn and updated as necessary. */
927 void mUPDoEditCommand(ControlHandle theControl, short editCommand);
928
929
930
931
932 /* mUPGetContents returns the entire contents of the control including the text
933 and the formatting information. */
934 OSStatus mUPGetContents(ControlHandle theControl, Handle *theContents);
935 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
936 OSStatus mUPSetContents(ControlHandle theControl, Handle theContents);
937
938 enum {
939 kShiftKeyCode = 56
940 };
941
942 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
943 routine. In our focus switching routine this part code is understood
944 as meaning 'the user has clicked in the control and we need to switch
945 the current focus to ourselves before we can continue'. */
946 #define kUserClickedToFocusPart 100
947
948
949 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
950 slow the speed of 'auto scrolling' inside of our clickloop routine.
951 This value prevents the text from wizzzzzing by while the mouse
952 is being held down inside of the text area. */
953 #define kmUPClickScrollDelayTicks 3
954
955
956 /* STPTextPaneVars is a structure used for storing the the mUP Control's
957 internal variables and state information. A handle to this record is
958 stored in the pane control's reference value field using the
959 SetControlReference routine. */
960
961 typedef struct {
962 /* OS records referenced */
963 TXNObject fTXNRec; /* the txn record */
964 TXNFrameID fTXNFrame; /* the txn frame ID */
965 ControlHandle fUserPaneRec; /* handle to the user pane control */
966 WindowPtr fOwner; /* window containing control */
967 GrafPtr fDrawingEnvironment; /* grafport where control is drawn */
968 /* flags */
969 Boolean fInFocus; /* true while the focus rect is drawn around the control */
970 Boolean fIsActive; /* true while the control is drawn in the active state */
971 Boolean fTEActive; /* reflects the activation state of the text edit record */
972 Boolean fInDialogWindow; /* true if displayed in a dialog window */
973 /* calculated locations */
974 Rect fRTextArea; /* area where the text is drawn */
975 Rect fRFocusOutline; /* rectangle used to draw the focus box */
976 Rect fRTextOutline; /* rectangle used to draw the border */
977 RgnHandle fTextBackgroundRgn; /* background region for the text, erased before calling TEUpdate */
978 /* our focus advance override routine */
979 EventHandlerUPP handlerUPP;
980 EventHandlerRef handlerRef;
981 } STPTextPaneVars;
982
983
984
985
986 /* Univerals Procedure Pointer variables used by the
987 mUP Control. These variables are set up
988 the first time that mUPOpenControl is called. */
989 ControlUserPaneDrawUPP gTPDrawProc = NULL;
990 ControlUserPaneHitTestUPP gTPHitProc = NULL;
991 ControlUserPaneTrackingUPP gTPTrackProc = NULL;
992 ControlUserPaneIdleUPP gTPIdleProc = NULL;
993 ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
994 ControlUserPaneActivateUPP gTPActivateProc = NULL;
995 ControlUserPaneFocusUPP gTPFocusProc = NULL;
996
997 /* events handled by our focus advance override routine */
998 #if TARGET_CARBON
999 static const EventTypeSpec gMLTEEvents[] = { { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } };
1000 #define kMLTEEventCount (sizeof( gMLTEEvents ) / sizeof( EventTypeSpec ))
1001 #endif
1002
1003
1004 /* TPActivatePaneText activates or deactivates the text edit record
1005 according to the value of setActive. The primary purpose of this
1006 routine is to ensure each call is only made once. */
1007 static void TPActivatePaneText(STPTextPaneVars **tpvars, Boolean setActive) {
1008 STPTextPaneVars *varsp;
1009 varsp = *tpvars;
1010 if (varsp->fTEActive != setActive) {
1011
1012 varsp->fTEActive = setActive;
1013
1014 TXNActivate(varsp->fTXNRec, varsp->fTXNFrame, varsp->fTEActive);
1015
1016 if (varsp->fInFocus)
1017 TXNFocus( varsp->fTXNRec, varsp->fTEActive);
1018 }
1019 }
1020
1021
1022 /* TPFocusPaneText set the focus state for the text record. */
1023 static void TPFocusPaneText(STPTextPaneVars **tpvars, Boolean setFocus) {
1024 STPTextPaneVars *varsp;
1025 varsp = *tpvars;
1026 if (varsp->fInFocus != setFocus) {
1027 varsp->fInFocus = setFocus;
1028 TXNFocus( varsp->fTXNRec, varsp->fInFocus);
1029 }
1030 }
1031
1032
1033 /* TPPaneDrawProc is called to redraw the control and for update events
1034 referring to the control. This routine erases the text area's background,
1035 and redraws the text. This routine assumes the scroll bar has been
1036 redrawn by a call to DrawControls. */
1037 static pascal void TPPaneDrawProc(ControlRef theControl, ControlPartCode thePart) {
1038 STPTextPaneVars **tpvars, *varsp;
1039 char state;
1040 Rect bounds;
1041 /* set up our globals */
1042 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1043 if (tpvars != NULL) {
1044 state = HGetState((Handle) tpvars);
1045 HLock((Handle) tpvars);
1046 varsp = *tpvars;
1047
1048 /* save the drawing state */
1049 SetPort((**tpvars).fDrawingEnvironment);
1050 /* verify our boundary */
1051 GetControlBounds(theControl, &bounds);
1052 if ( ! EqualRect(&bounds, &varsp->fRTextArea) ) {
1053 SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
1054 SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
1055 SetRect(&varsp->fRTextArea, bounds.left, bounds.top, bounds.right, bounds.bottom);
1056 RectRgn(varsp->fTextBackgroundRgn, &varsp->fRTextOutline);
1057 TXNSetFrameBounds( varsp->fTXNRec, bounds.top, bounds.left, bounds.bottom, bounds.right, varsp->fTXNFrame);
1058 }
1059
1060 /* update the text region */
1061 EraseRgn(varsp->fTextBackgroundRgn);
1062 TXNDraw(varsp->fTXNRec, NULL);
1063 /* restore the drawing environment */
1064 /* draw the text frame and focus frame (if necessary) */
1065 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
1066 if ((**tpvars).fIsActive && varsp->fInFocus) DrawThemeFocusRect(&varsp->fRFocusOutline, true);
1067 /* release our globals */
1068 HSetState((Handle) tpvars, state);
1069 }
1070 }
1071
1072
1073 /* TPPaneHitTestProc is called when the control manager would
1074 like to determine what part of the control the mouse resides over.
1075 We also call this routine from our tracking proc to determine how
1076 to handle mouse clicks. */
1077 static pascal ControlPartCode TPPaneHitTestProc(ControlHandle theControl, Point where) {
1078 STPTextPaneVars **tpvars;
1079 ControlPartCode result;
1080 char state;
1081 /* set up our locals and lock down our globals*/
1082 result = 0;
1083 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1084 if (tpvars != NULL) {
1085 state = HGetState((Handle) tpvars);
1086 HLock((Handle) tpvars);
1087 /* find the region where we clicked */
1088 if (PtInRect(where, &(**tpvars).fRTextArea)) {
1089 result = kmUPTextPart;
1090 } else result = 0;
1091 /* release oure globals */
1092 HSetState((Handle) tpvars, state);
1093 }
1094 return result;
1095 }
1096
1097
1098
1099
1100
1101 /* TPPaneTrackingProc is called when the mouse is being held down
1102 over our control. This routine handles clicks in the text area
1103 and in the scroll bar. */
1104 static pascal ControlPartCode TPPaneTrackingProc(ControlHandle theControl, Point startPt, ControlActionUPP actionProc) {
1105 STPTextPaneVars **tpvars, *varsp;
1106 char state;
1107 ControlPartCode partCodeResult;
1108 /* make sure we have some variables... */
1109 partCodeResult = 0;
1110 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1111 if (tpvars != NULL) {
1112 /* lock 'em down */
1113 state = HGetState((Handle) tpvars);
1114 HLock((Handle) tpvars);
1115 varsp = *tpvars;
1116 /* we don't do any of these functions unless we're in focus */
1117 if ( ! varsp->fInFocus) {
1118 WindowPtr owner;
1119 owner = GetControlOwner(theControl);
1120 ClearKeyboardFocus(owner);
1121 SetKeyboardFocus(owner, theControl, kUserClickedToFocusPart);
1122 }
1123 /* find the location for the click */
1124 switch (TPPaneHitTestProc(theControl, startPt)) {
1125
1126 /* handle clicks in the text part */
1127 case kmUPTextPart:
1128 { SetPort((**tpvars).fDrawingEnvironment);
1129 TXNClick( varsp->fTXNRec, GetCurrentEventRecord());
1130 }
1131 break;
1132
1133 }
1134
1135 HSetState((Handle) tpvars, state);
1136 }
1137 return partCodeResult;
1138 }
1139
1140
1141 /* TPPaneIdleProc is our user pane idle routine. When our text field
1142 is active and in focus, we use this routine to set the cursor. */
1143 static pascal void TPPaneIdleProc(ControlHandle theControl) {
1144 STPTextPaneVars **tpvars, *varsp;
1145 /* set up locals */
1146 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1147 if (tpvars != NULL) {
1148 /* if we're not active, then we have nothing to say about the cursor */
1149 if ((**tpvars).fIsActive) {
1150 char state;
1151 Rect bounds;
1152 Point mousep;
1153 /* lock down the globals */
1154 state = HGetState((Handle) tpvars);
1155 HLock((Handle) tpvars);
1156 varsp = *tpvars;
1157 /* get the current mouse coordinates (in our window) */
1158 #if TARGET_CARBON
1159 SetPort(GetWindowPort(GetControlOwner(theControl)));
1160 #else
1161 SetPort((GrafPtr) GetWindowPort(GetControlOwner(theControl)));
1162 #endif
1163 GetMouse(&mousep);
1164 /* there's a 'focus thing' and an 'unfocused thing' */
1165 if (varsp->fInFocus) {
1166 /* flash the cursor */
1167 SetPort((**tpvars).fDrawingEnvironment);
1168 TXNIdle(varsp->fTXNRec);
1169 /* set the cursor */
1170 if (PtInRect(mousep, &varsp->fRTextArea)) {
1171 RgnHandle theRgn;
1172 RectRgn((theRgn = NewRgn()), &varsp->fRTextArea);
1173 TXNAdjustCursor(varsp->fTXNRec, theRgn);
1174 DisposeRgn(theRgn);
1175 } else SetThemeCursor(kThemeArrowCursor);
1176 } else {
1177 /* if it's in our bounds, set the cursor */
1178 GetControlBounds(theControl, &bounds);
1179 if (PtInRect(mousep, &bounds))
1180 SetThemeCursor(kThemeArrowCursor);
1181 }
1182
1183 HSetState((Handle) tpvars, state);
1184 }
1185 }
1186 }
1187
1188
1189 /* TPPaneKeyDownProc is called whenever a keydown event is directed
1190 at our control. Here, we direct the keydown event to the text
1191 edit record and redraw the scroll bar and text field as appropriate. */
1192 static pascal ControlPartCode TPPaneKeyDownProc(ControlHandle theControl,
1193 SInt16 keyCode, SInt16 charCode, SInt16 modifiers) {
1194 STPTextPaneVars **tpvars;
1195 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1196 if (tpvars != NULL) {
1197 if ((**tpvars).fInFocus) {
1198 /* turn autoscrolling on and send the key event to text edit */
1199 SetPort((**tpvars).fDrawingEnvironment);
1200 TXNKeyDown( (**tpvars).fTXNRec, GetCurrentEventRecord());
1201 }
1202 }
1203 return kControlEntireControl;
1204 }
1205
1206
1207 /* TPPaneActivateProc is called when the window containing
1208 the user pane control receives activate events. Here, we redraw
1209 the control and it's text as necessary for the activation state. */
1210 static pascal void TPPaneActivateProc(ControlHandle theControl, Boolean activating) {
1211 Rect bounds;
1212 STPTextPaneVars **tpvars, *varsp;
1213 char state;
1214 /* set up locals */
1215 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1216 if (tpvars != NULL) {
1217 state = HGetState((Handle) tpvars);
1218 HLock((Handle) tpvars);
1219 varsp = *tpvars;
1220 /* de/activate the text edit record */
1221 SetPort((**tpvars).fDrawingEnvironment);
1222 GetControlBounds(theControl, &bounds);
1223 varsp->fIsActive = activating;
1224 TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
1225 /* redraw the frame */
1226 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
1227 if (varsp->fInFocus) DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive);
1228 HSetState((Handle) tpvars, state);
1229 }
1230 }
1231
1232
1233 /* TPPaneFocusProc is called when every the focus changes to or
1234 from our control. Herein, switch the focus appropriately
1235 according to the parameters and redraw the control as
1236 necessary. */
1237 static pascal ControlPartCode TPPaneFocusProc(ControlHandle theControl, ControlFocusPart action) {
1238 ControlPartCode focusResult;
1239 STPTextPaneVars **tpvars, *varsp;
1240 char state;
1241 /* set up locals */
1242 focusResult = kControlFocusNoPart;
1243 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1244 if (tpvars != NULL) {
1245 state = HGetState((Handle) tpvars);
1246 HLock((Handle) tpvars);
1247 varsp = *tpvars;
1248 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
1249 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
1250 and kControlFocusNextPart will be received. When the user clicks in our field
1251 and it is not the current focus, then the constant kUserClickedToFocusPart will
1252 be received. The constant kControlFocusNoPart will be received when our control
1253 is the current focus and the user clicks in another control. In your focus routine,
1254 you should respond to these codes as follows:
1255
1256 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
1257 the control and the focus rectangle as necessary.
1258
1259 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
1260 depending on its current state. redraw the control and the focus rectangle
1261 as appropriate for the new focus state. If the focus state is 'off', return the constant
1262 kControlFocusNoPart, otherwise return a non-zero part code.
1263 kUserClickedToFocusPart - is a constant defined for this example. You should
1264 define your own value for handling click-to-focus type events. */
1265 /* save the drawing state */
1266 SetPort((**tpvars).fDrawingEnvironment);
1267 /* calculate the next highlight state */
1268 switch (action) {
1269 default:
1270 case kControlFocusNoPart:
1271 TPFocusPaneText(tpvars, false);
1272 focusResult = kControlFocusNoPart;
1273 break;
1274 case kUserClickedToFocusPart:
1275 TPFocusPaneText(tpvars, true);
1276 focusResult = 1;
1277 break;
1278 case kControlFocusPrevPart:
1279 case kControlFocusNextPart:
1280 TPFocusPaneText(tpvars, ( ! varsp->fInFocus));
1281 focusResult = varsp->fInFocus ? 1 : kControlFocusNoPart;
1282 break;
1283 }
1284 TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
1285 /* redraw the text fram and focus rectangle to indicate the
1286 new focus state */
1287 DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
1288 DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive && varsp->fInFocus);
1289 /* done */
1290 HSetState((Handle) tpvars, state);
1291 }
1292 return focusResult;
1293 }
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305 //This our carbon event handler for unicode key downs
1306 #if TARGET_CARBON
1307 static pascal OSStatus FocusAdvanceOverride(EventHandlerCallRef myHandler, EventRef event, void* userData) {
1308 WindowRef window;
1309 STPTextPaneVars **tpvars;
1310 OSStatus err;
1311 unsigned short mUnicodeText;
1312 ByteCount charCounts=0;
1313 /* get our window pointer */
1314 tpvars = (STPTextPaneVars **) userData;
1315 window = (**tpvars).fOwner;
1316 //find out how many bytes are needed
1317 err = GetEventParameter(event, kEventParamTextInputSendText,
1318 typeUnicodeText, NULL, 0, &charCounts, NULL);
1319 if (err != noErr) goto bail;
1320 /* we're only looking at single characters */
1321 if (charCounts != 2) { err = eventNotHandledErr; goto bail; }
1322 /* get the character */
1323 err = GetEventParameter(event, kEventParamTextInputSendText,
1324 typeUnicodeText, NULL, sizeof(mUnicodeText),
1325 &charCounts, (char*) &mUnicodeText);
1326 if (err != noErr) goto bail;
1327 /* if it's not the tab key, forget it... */
1328 if ((mUnicodeText != '\t')) { err = eventNotHandledErr; goto bail; }
1329 /* advance the keyboard focus */
1330 AdvanceKeyboardFocus(window);
1331 /* noErr lets the CEM know we handled the event */
1332 return noErr;
1333 bail:
1334 return eventNotHandledErr;
1335 }
1336 #endif
1337
1338
1339 /* mUPOpenControl initializes a user pane control so it will be drawn
1340 and will behave as a scrolling text edit field inside of a window.
1341 This routine performs all of the initialization steps necessary,
1342 except it does not create the user pane control itself. theControl
1343 should refer to a user pane control that you have either created
1344 yourself or extracted from a dialog's control heirarchy using
1345 the GetDialogItemAsControl routine. */
1346 OSStatus mUPOpenControl(ControlHandle theControl, bool multiline) {
1347 Rect bounds;
1348 WindowPtr theWindow;
1349 STPTextPaneVars **tpvars, *varsp;
1350 OSStatus err;
1351 RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF};
1352 TXNBackground tback;
1353
1354 /* set up our globals */
1355 if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(TPPaneDrawProc);
1356 if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(TPPaneHitTestProc);
1357 if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(TPPaneTrackingProc);
1358 if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(TPPaneIdleProc);
1359 if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc);
1360 if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(TPPaneActivateProc);
1361 if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(TPPaneFocusProc);
1362
1363 /* allocate our private storage */
1364 tpvars = (STPTextPaneVars **) NewHandleClear(sizeof(STPTextPaneVars));
1365 SetControlReference(theControl, (long) tpvars);
1366 HLock((Handle) tpvars);
1367 varsp = *tpvars;
1368 /* set the initial settings for our private data */
1369 varsp->fInFocus = false;
1370 varsp->fIsActive = true;
1371 varsp->fTEActive = false;
1372 varsp->fUserPaneRec = theControl;
1373 theWindow = varsp->fOwner = GetControlOwner(theControl);
1374 #if TARGET_CARBON
1375 varsp->fDrawingEnvironment = GetWindowPort(varsp->fOwner);
1376 #else
1377 varsp->fDrawingEnvironment = (GrafPtr) GetWindowPort(varsp->fOwner);
1378 #endif
1379 varsp->fInDialogWindow = ( GetWindowKind(varsp->fOwner) == kDialogWindowKind );
1380 /* set up the user pane procedures */
1381 SetControlData(theControl, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
1382 SetControlData(theControl, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
1383 SetControlData(theControl, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
1384 SetControlData(theControl, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
1385 SetControlData(theControl, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
1386 SetControlData(theControl, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
1387 SetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
1388 /* calculate the rectangles used by the control */
1389 GetControlBounds(theControl, &bounds);
1390 SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
1391 SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
1392 SetRect(&varsp->fRTextArea, bounds.left, bounds.top, bounds.right, bounds.bottom);
1393 /* calculate the background region for the text. In this case, it's kindof
1394 and irregular region because we're setting the scroll bar a little ways inside
1395 of the text area. */
1396 RectRgn((varsp->fTextBackgroundRgn = NewRgn()), &varsp->fRTextOutline);
1397
1398 /* set up the drawing environment */
1399 SetPort(varsp->fDrawingEnvironment);
1400
1401 /* create the new edit field */
1402 TXNNewObject(NULL, varsp->fOwner, &varsp->fRTextArea,
1403 kTXNWantVScrollBarMask | kTXNAlwaysWrapAtViewEdgeMask,
1404 kTXNTextEditStyleFrameType,
1405 kTXNTextensionFile,
1406 kTXNSystemDefaultEncoding,
1407 &varsp->fTXNRec, &varsp->fTXNFrame, (TXNObjectRefcon) tpvars);
1408
1409 /* set the field's background */
1410 tback.bgType = kTXNBackgroundTypeRGB;
1411 tback.bg.color = rgbWhite;
1412 TXNSetBackground( varsp->fTXNRec, &tback);
1413
1414 /* install our focus advance override routine */
1415 #if TARGET_CARBON
1416 varsp->handlerUPP = NewEventHandlerUPP(FocusAdvanceOverride);
1417 err = InstallWindowEventHandler( varsp->fOwner, varsp->handlerUPP,
1418 kMLTEEventCount, gMLTEEvents, tpvars, &varsp->handlerRef );
1419 #endif
1420 /* unlock our storage */
1421 HUnlock((Handle) tpvars);
1422 /* perform final activations and setup for our text field. Here,
1423 we assume that the window is going to be the 'active' window. */
1424 TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
1425 /* all done */
1426 return noErr;
1427 }
1428
1429
1430
1431 /* mUPCloseControl deallocates all of the structures allocated
1432 by mUPOpenControl. */
1433 OSStatus mUPCloseControl(ControlHandle theControl) {
1434 STPTextPaneVars **tpvars;
1435 /* set up locals */
1436 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1437 /* release our sub records */
1438 TXNDeleteObject((**tpvars).fTXNRec);
1439 /* remove our focus advance override */
1440 RemoveEventHandler((**tpvars).handlerRef);
1441 DisposeEventHandlerUPP((**tpvars).handlerUPP);
1442 /* delete our private storage */
1443 DisposeHandle((Handle) tpvars);
1444 /* zero the control reference */
1445 SetControlReference(theControl, 0);
1446 return noErr;
1447 }
1448
1449
1450
1451
1452 /* mUPSetText replaces the contents of the selection with the unicode
1453 text described by the text and count parameters:.
1454 text = pointer to unicode text buffer
1455 count = number of bytes in the buffer. */
1456 OSStatus mUPSetText(ControlHandle theControl, char* text, long count) {
1457 STPTextPaneVars **tpvars;
1458 /* set up locals */
1459 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1460 /* set the text in the record */
1461 return TXNSetData( (**tpvars).fTXNRec, kTXNUnicodeTextData, text, count,
1462 kTXNUseCurrentSelection, kTXNUseCurrentSelection);
1463
1464 return noErr;
1465 }
1466
1467
1468 /* mUPSetSelection sets the text selection and autoscrolls the text view
1469 so either the cursor or the selction is in the view. */
1470 void mUPSetSelection(ControlHandle theControl, long selStart, long selEnd) {
1471 STPTextPaneVars **tpvars;
1472 /* set up our locals */
1473 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1474 /* and our drawing environment as the operation
1475 may force a redraw in the text area. */
1476 SetPort((**tpvars).fDrawingEnvironment);
1477 /* change the selection */
1478 TXNSetSelection( (**tpvars).fTXNRec, selStart, selEnd);
1479 }
1480
1481
1482
1483
1484
1485 /* mUPGetText returns the current text data being displayed inside of
1486 the mUPControl. When noErr is returned, *theText contain a new
1487 handle containing all of the Unicode text copied from the current
1488 selection. It is the caller's responsibiliby to dispose of this handle. */
1489 OSStatus mUPGetText(ControlHandle theControl, Handle *theText) {
1490 STPTextPaneVars **tpvars;
1491 OSStatus err;
1492 /* set up locals */
1493 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1494 /* extract the text from the record */
1495 err = TXNGetData( (**tpvars).fTXNRec, kTXNUseCurrentSelection, kTXNUseCurrentSelection, theText);
1496 /* all done */
1497 return err;
1498 }
1499
1500
1501
1502 /* mUPCreateControl creates a new user pane control and then it passes it
1503 to mUPOpenControl to initialize it as a scrolling text user pane control. */
1504 OSStatus mUPCreateControl(WindowPtr theWindow, Rect *bounds, ControlHandle *theControl) {
1505 short featurSet;
1506 /* the following feature set can be specified in CNTL resources by using
1507 the value 1214. When creating a user pane control, we pass this value
1508 in the 'value' parameter. */
1509 featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
1510 | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground
1511 | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
1512 /* create the control */
1513 *theControl = NewControl(theWindow, bounds, "\p", true, featurSet, 0, featurSet, kControlUserPaneProc, 0);
1514 /* set up the mUP specific features and data */
1515 mUPOpenControl(*theControl);
1516 /* all done.... */
1517 return noErr;
1518 }
1519
1520
1521 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
1522 OSStatus mUPDisposeControl(ControlHandle theControl) {
1523 /* deallocate the mUP specific data */
1524 mUPCloseControl(theControl);
1525 /* deallocate the user pane control itself */
1526 DisposeControl(theControl);
1527 return noErr;
1528 }
1529
1530
1531
1532
1533 /* IsmUPControl returns true if theControl is not NULL
1534 and theControl refers to a mUP Control. */
1535 Boolean IsmUPControl(ControlHandle theControl) {
1536 Size theSize;
1537 ControlUserPaneFocusUPP localFocusProc;
1538 /* a NULL control is not a mUP control */
1539 if (theControl == NULL) return false;
1540 /* check if the control is using our focus procedure */
1541 theSize = sizeof(localFocusProc);
1542 if (GetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag,
1543 sizeof(localFocusProc), &localFocusProc, &theSize) != noErr) return false;
1544 if (localFocusProc != gTPFocusProc) return false;
1545 /* all tests passed, it's a mUP control */
1546 return true;
1547 }
1548
1549
1550 /* mUPDoEditCommand performs the editing command specified
1551 in the editCommand parameter. The mUPControl's text
1552 and scroll bar are redrawn and updated as necessary. */
1553 void mUPDoEditCommand(ControlHandle theControl, short editCommand) {
1554 STPTextPaneVars **tpvars;
1555 /* set up our locals */
1556 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1557 /* and our drawing environment as the operation
1558 may force a redraw in the text area. */
1559 SetPort((**tpvars).fDrawingEnvironment);
1560 /* perform the editing command */
1561 switch (editCommand) {
1562 case kmUPCut:
1563 ClearCurrentScrap();
1564 TXNCut((**tpvars).fTXNRec);
1565 TXNConvertToPublicScrap();
1566 break;
1567 case kmUPCopy:
1568 ClearCurrentScrap();
1569 TXNCopy((**tpvars).fTXNRec);
1570 TXNConvertToPublicScrap();
1571 break;
1572 case kmUPPaste:
1573 TXNConvertFromPublicScrap();
1574 TXNPaste((**tpvars).fTXNRec);
1575 break;
1576 case kmUPClear:
1577 TXNClear((**tpvars).fTXNRec);
1578 break;
1579 }
1580 }
1581
1582
1583
1584
1585 /* mUPGetContents returns the entire contents of the control including the text
1586 and the formatting information. */
1587 OSStatus mUPGetContents(ControlHandle theControl, Handle *theContents) {
1588 STPTextPaneVars **tpvars;
1589 OSStatus err;
1590 short vRefNum;
1591 long dirID;
1592 FSSpec tspec;
1593 short trefnum;
1594 Boolean texists;
1595 long bytecount;
1596 Handle localdata;
1597 /* set up locals */
1598 trefnum = 0;
1599 texists = false;
1600 localdata = NULL;
1601 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1602 if (theContents == NULL) return paramErr;
1603 /* create a temporary file */
1604 err = FindFolder(kOnSystemDisk, kTemporaryFolderType, true, &vRefNum, &dirID);
1605 if (err != noErr) goto bail;
1606 FSMakeFSSpec(vRefNum, dirID, "\pmUPGetContents", &tspec);
1607 err = FSpCreate(&tspec, 'trsh', 'trsh', smSystemScript);
1608 if (err != noErr) goto bail;
1609 texists = true;
1610 /* open the file */
1611 err = FSpOpenDF(&tspec, fsRdWrPerm, &trefnum);
1612 if (err != noErr) goto bail;
1613 /* save the data */
1614 err = TXNSave( (**tpvars).fTXNRec, kTXNTextensionFile, 0, kTXNSystemDefaultEncoding, &tspec, trefnum, 0);
1615 if (err != noErr) goto bail;
1616 /* get the file length and set the position */
1617 err = GetEOF(trefnum, &bytecount);
1618 if (err != noErr) goto bail;
1619 err = SetFPos(trefnum, fsFromStart, 0);
1620 if (err != noErr) goto bail;
1621 /* copy the data fork to a handle */
1622 localdata = NewHandle(bytecount);
1623 if (localdata == NULL) { err = memFullErr; goto bail; }
1624 HLock(localdata);
1625 err = FSRead(trefnum, &bytecount, *localdata);
1626 HUnlock(localdata);
1627 if (err != noErr) goto bail;
1628 /* store result */
1629 *theContents = localdata;
1630 /* clean up */
1631 FSClose(trefnum);
1632 FSpDelete(&tspec);
1633 /* all done */
1634 return noErr;
1635 bail:
1636 if (trefnum != 0) FSClose(trefnum);
1637 if (texists) FSpDelete(&tspec);
1638 if (localdata != NULL) DisposeHandle(localdata);
1639 return err;
1640 }
1641
1642
1643
1644
1645 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
1646 OSStatus mUPSetContents(ControlHandle theControl, Handle theContents) {
1647 STPTextPaneVars **tpvars;
1648 OSStatus err;
1649 short vRefNum;
1650 long dirID;
1651 FSSpec tspec;
1652 short trefnum;
1653 Boolean texists;
1654 long bytecount;
1655 char state;
1656 /* set up locals */
1657 trefnum = 0;
1658 texists = false;
1659 tpvars = (STPTextPaneVars **) GetControlReference(theControl);
1660 if (theContents == NULL) return paramErr;
1661 /* create a temporary file */
1662 err = FindFolder(kOnSystemDisk, kTemporaryFolderType, true, &vRefNum, &dirID);
1663 if (err != noErr) goto bail;
1664 FSMakeFSSpec(vRefNum, dirID, "\pmUPSetContents", &tspec);
1665 err = FSpCreate(&tspec, 'trsh', 'trsh', smSystemScript);
1666 if (err != noErr) goto bail;
1667 texists = true;
1668 /* open the file */
1669 err = FSpOpenDF(&tspec, fsRdWrPerm, &trefnum);
1670 if (err != noErr) goto bail;
1671 /* save the data to the temporary file */
1672 state = HGetState(theContents);
1673 HLock(theContents);
1674 bytecount = GetHandleSize(theContents);
1675 err = FSWrite(trefnum, &bytecount, *theContents);
1676 HSetState(theContents, state);
1677 if (err != noErr) goto bail;
1678 /* reset the file position */
1679 err = SetFPos(trefnum, fsFromStart, 0);
1680 if (err != noErr) goto bail;
1681 /* load the data */
1682 err = TXNSetDataFromFile((**tpvars).fTXNRec, trefnum, kTXNTextensionFile, bytecount, kTXNUseCurrentSelection, kTXNUseCurrentSelection);
1683 if (err != noErr) goto bail;
1684 /* clean up */
1685 FSClose(trefnum);
1686 FSpDelete(&tspec);
1687 /* all done */
1688 return noErr;
1689 bail:
1690 if (trefnum != 0) FSClose(trefnum);
1691 if (texists) FSpDelete(&tspec);
1692 return err;
1693 }
1694
1695 #if !USE_SHARED_LIBRARY
1696 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
1697
1698 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
1699 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
1700 EVT_CHAR(wxTextCtrl::OnChar)
1701 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
1702 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
1703 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
1704 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
1705 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
1706
1707 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
1708 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
1709 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
1710 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
1711 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
1712 END_EVENT_TABLE()
1713 #endif
1714
1715 // Text item
1716 wxTextCtrl::wxTextCtrl()
1717 {
1718 }
1719
1720 const short kVerticalMargin = 2 ;
1721 const short kHorizontalMargin = 2 ;
1722
1723 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
1724 const wxString& st,
1725 const wxPoint& pos,
1726 const wxSize& size, long style,
1727 const wxValidator& validator,
1728 const wxString& name)
1729 {
1730 // base initialization
1731 if ( !CreateBase(parent, id, pos, size, style, validator, name) )
1732 return FALSE;
1733
1734 wxSize mySize = size ;
1735 if ( UMAHasAppearance() )
1736 {
1737 m_macHorizontalBorder = 5 ; // additional pixels around the real control
1738 m_macVerticalBorder = 5 ;
1739 }
1740 else
1741 {
1742 m_macHorizontalBorder = 0 ; // additional pixels around the real control
1743 m_macVerticalBorder = 0 ;
1744 }
1745
1746
1747 Rect bounds ;
1748 Str255 title ;
1749
1750 if ( mySize.y == -1 )
1751 {
1752 if ( UMAHasAppearance() )
1753 mySize.y = 13 ;
1754 else
1755 mySize.y = 24 ;
1756
1757 mySize.y += 2 * m_macVerticalBorder ;
1758 }
1759
1760 MacPreControlCreate( parent , id , "" , pos , mySize ,style, validator , name , &bounds , title ) ;
1761
1762 if ( m_windowStyle & wxTE_MULTILINE )
1763 {
1764 wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
1765 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
1766
1767 m_windowStyle |= wxTE_PROCESS_ENTER;
1768 }
1769
1770
1771 if ( style & wxTE_PASSWORD )
1772 {
1773 m_macControl = ::NewControl( parent->MacGetRootWindow() , &bounds , "\p" , true , 0 , 0 , 1,
1774 kControlEditTextPasswordProc , (long) this ) ;
1775 }
1776 else
1777 {
1778 if ( mUPCreateControl(parent->MacGetRootWindow(), &bounds, &m_macControl) != noErr )
1779 return FALSE ;
1780 }
1781 MacPostControlCreate() ;
1782
1783 wxString value ;
1784
1785 if( wxApp::s_macDefaultEncodingIsPC )
1786 value = wxMacMakeMacStringFromPC( st ) ;
1787 else
1788 value = st ;
1789
1790 if ( style & wxTE_PASSWORD )
1791 {
1792 ::SetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
1793 }
1794 else
1795 {
1796 STPTextPaneVars **tpvars;
1797 /* set up locals */
1798 tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
1799 /* set the text in the record */
1800 TXNSetData( (**tpvars).fTXNRec, kTXNTextData, (const char*)value, value.Length(),
1801 kTXNStartOffset, kTXNEndOffset);
1802 }
1803
1804 return TRUE;
1805 }
1806
1807 wxString wxTextCtrl::GetValue() const
1808 {
1809 Size actualsize;
1810 if ( m_windowStyle & wxTE_PASSWORD )
1811 {
1812 ::GetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
1813 }
1814 else
1815 {
1816 STPTextPaneVars **tpvars;
1817 OSStatus err;
1818 /* set up locals */
1819 tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
1820 /* extract the text from the record */
1821 Handle theText ;
1822 err = TXNGetDataEncoded( (**tpvars).fTXNRec, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
1823 /* all done */
1824 if ( err )
1825 {
1826 actualsize = 0 ;
1827 }
1828 else
1829 {
1830 actualsize = GetHandleSize( theText ) ;
1831 strncpy( wxBuffer , *theText , actualsize ) ;
1832 DisposeHandle( theText ) ;
1833 }
1834 }
1835 wxBuffer[actualsize] = 0 ;
1836 if( wxApp::s_macDefaultEncodingIsPC )
1837 return wxMacMakePCStringFromMac( wxBuffer ) ;
1838 else
1839 return wxString(wxBuffer);
1840 }
1841
1842 void wxTextCtrl::GetSelection(long* from, long* to) const
1843 {
1844 if ( m_windowStyle & wxTE_PASSWORD )
1845 {
1846 ControlEditTextSelectionRec selection ;
1847 TEHandle teH ;
1848 long size ;
1849
1850 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
1851
1852 *from = (**teH).selStart;
1853 *to = (**teH).selEnd;
1854 }
1855 else
1856 {
1857 STPTextPaneVars **tpvars;
1858
1859 /* set up locals */
1860 tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
1861
1862 TXNGetSelection( (**tpvars).fTXNRec , (TXNOffset*) from , (TXNOffset*) to ) ;
1863
1864 }
1865 }
1866
1867 void wxTextCtrl::SetValue(const wxString& st)
1868 {
1869 wxString value ;
1870
1871 if( wxApp::s_macDefaultEncodingIsPC )
1872 value = wxMacMakeMacStringFromPC( st ) ;
1873 else
1874 value = st ;
1875 if ( m_windowStyle & wxTE_PASSWORD )
1876 {
1877 ::SetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
1878 }
1879 else
1880 {
1881 STPTextPaneVars **tpvars;
1882 /* set up locals */
1883 tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
1884 /* set the text in the record */
1885 TXNSetData( (**tpvars).fTXNRec, kTXNTextData, (const char*)value, value.Length(),
1886 kTXNStartOffset, kTXNEndOffset);
1887 }
1888 WindowRef window = MacGetRootWindow() ;
1889 if ( window )
1890 {
1891 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1892 if ( win )
1893 {
1894 wxMacDrawingHelper help( win ) ;
1895 // the mac control manager always assumes to have the origin at 0,0
1896
1897 bool hasTabBehind = false ;
1898 wxWindow* parent = GetParent() ;
1899 while ( parent )
1900 {
1901 if( parent->MacGetWindowData() )
1902 {
1903 UMASetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , kThemeBrushDialogBackgroundActive , false ) ;
1904 break ;
1905 }
1906
1907 if( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
1908 {
1909 if ( ((wxControl*)parent)->GetMacControl() )
1910 SetUpControlBackground( ((wxControl*)parent)->GetMacControl() , -1 , true ) ;
1911 break ;
1912 }
1913
1914 parent = parent->GetParent() ;
1915 }
1916
1917 UMADrawControl( m_macControl ) ;
1918 UMASetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
1919 }
1920 }
1921 }
1922
1923 // Clipboard operations
1924 void wxTextCtrl::Copy()
1925 {
1926 if (CanCopy())
1927 {
1928 if ( m_windowStyle & wxTE_PASSWORD )
1929 {
1930 TEHandle teH ;
1931 long size ;
1932
1933 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
1934 TECopy( teH ) ;
1935 ClearCurrentScrap();
1936 TEToScrap() ;
1937 }
1938 else
1939 {
1940 mUPDoEditCommand( m_macControl , kmUPCopy ) ;
1941 }
1942 }
1943 }
1944
1945 void wxTextCtrl::Cut()
1946 {
1947 if (CanCut())
1948 {
1949 if ( m_windowStyle & wxTE_PASSWORD )
1950 {
1951 TEHandle teH ;
1952 long size ;
1953
1954 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
1955 TECut( teH ) ;
1956 ClearCurrentScrap();
1957 TEToScrap() ;
1958 // MacInvalidateControl() ;
1959 }
1960 else
1961 {
1962 mUPDoEditCommand( m_macControl , kmUPCut ) ;
1963 }
1964 }
1965 }
1966
1967 void wxTextCtrl::Paste()
1968 {
1969 if (CanPaste())
1970 {
1971 if ( m_windowStyle & wxTE_PASSWORD )
1972 {
1973 TEHandle teH ;
1974 long size ;
1975
1976 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
1977 TEFromScrap() ;
1978 TEPaste( teH ) ;
1979 WindowRef window = MacGetRootWindow() ;
1980 if ( window )
1981 {
1982 wxWindow* win = wxFindWinFromMacWindow( window ) ;
1983 if ( win )
1984 {
1985 wxMacDrawingHelper help( win ) ;
1986 // the mac control manager always assumes to have the origin at 0,0
1987 bool hasTabBehind = false ;
1988 wxWindow* parent = GetParent() ;
1989 while ( parent )
1990 {
1991 if( parent->MacGetWindowData() )
1992 {
1993 ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , kThemeBrushDialogBackgroundActive , false ) ;
1994 break ;
1995 }
1996
1997 if( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
1998 {
1999 if ( ((wxControl*)parent)->GetMacControl() )
2000 SetUpControlBackground( ((wxControl*)parent)->GetMacControl() , -1 , true ) ;
2001 break ;
2002 }
2003
2004 parent = parent->GetParent() ;
2005 }
2006
2007 UMADrawControl( m_macControl ) ;
2008 ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
2009 }
2010 }
2011 }
2012 else
2013 {
2014 mUPDoEditCommand( m_macControl , kmUPPaste ) ;
2015 }
2016 }
2017 }
2018
2019 bool wxTextCtrl::CanCopy() const
2020 {
2021 // Can copy if there's a selection
2022 long from, to;
2023 GetSelection(& from, & to);
2024 return (from != to);
2025 }
2026
2027 bool wxTextCtrl::CanCut() const
2028 {
2029 // Can cut if there's a selection
2030 long from, to;
2031 GetSelection(& from, & to);
2032 return (from != to);
2033 }
2034
2035 bool wxTextCtrl::CanPaste() const
2036 {
2037 if (!IsEditable())
2038 return FALSE;
2039
2040 long offset ;
2041 #if TARGET_CARBON
2042 OSStatus err = noErr;
2043 ScrapRef scrapRef;
2044
2045 err = GetCurrentScrap( &scrapRef );
2046 if ( err != noTypeErr && err != memFullErr )
2047 {
2048 ScrapFlavorFlags flavorFlags;
2049 Size byteCount;
2050
2051 if (( err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags )) == noErr)
2052 {
2053 if (( err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount )) == noErr)
2054 {
2055 return TRUE ;
2056 }
2057 }
2058 }
2059 return FALSE;
2060
2061 #else
2062 if ( GetScrap( NULL , 'TEXT' , &offset ) > 0 )
2063 {
2064 return TRUE ;
2065 }
2066 #endif
2067 return FALSE ;
2068 }
2069
2070 void wxTextCtrl::SetEditable(bool editable)
2071 {
2072 if ( editable )
2073 UMAActivateControl( m_macControl ) ;
2074 else
2075 UMADeactivateControl( m_macControl ) ;
2076 }
2077
2078 void wxTextCtrl::SetInsertionPoint(long pos)
2079 {
2080 SetSelection( pos , pos ) ;
2081 }
2082
2083 void wxTextCtrl::SetInsertionPointEnd()
2084 {
2085 long pos = GetLastPosition();
2086 SetInsertionPoint(pos);
2087 }
2088
2089 long wxTextCtrl::GetInsertionPoint() const
2090 {
2091 long begin,end ;
2092 GetSelection( &begin , &end ) ;
2093 return begin ;
2094 }
2095
2096 long wxTextCtrl::GetLastPosition() const
2097 {
2098 if ( m_windowStyle & wxTE_PASSWORD )
2099 {
2100
2101 ControlEditTextSelectionRec selection ;
2102 TEHandle teH ;
2103 long size ;
2104
2105 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
2106
2107 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
2108 return (**teH).teLength ;
2109 }
2110 else
2111 {
2112 STPTextPaneVars** tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
2113
2114 int actualsize = 0 ;
2115 Handle theText ;
2116 OSErr err = TXNGetDataEncoded( (**tpvars).fTXNRec, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
2117 /* all done */
2118 if ( err )
2119 {
2120 actualsize = 0 ;
2121 }
2122 else
2123 {
2124 actualsize = GetHandleSize( theText ) ;
2125 DisposeHandle( theText ) ;
2126 }
2127 return actualsize ;
2128 }
2129 }
2130
2131 void wxTextCtrl::Replace(long from, long to, const wxString& value)
2132 {
2133 if ( m_windowStyle & wxTE_PASSWORD )
2134 {
2135 TEHandle teH ;
2136 long size ;
2137
2138 ControlEditTextSelectionRec selection ;
2139
2140 selection.selStart = from ;
2141 selection.selEnd = to ;
2142 ::SetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
2143 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
2144 TESetSelect( from , to , teH ) ;
2145 TEDelete( teH ) ;
2146 TEInsert( value , value.Length() , teH ) ;
2147 }
2148 else
2149 {
2150 // TODO
2151 }
2152 Refresh() ;
2153 }
2154
2155 void wxTextCtrl::Remove(long from, long to)
2156 {
2157 if ( m_windowStyle & wxTE_PASSWORD )
2158 {
2159 TEHandle teH ;
2160 long size ;
2161
2162 ControlEditTextSelectionRec selection ;
2163
2164 selection.selStart = from ;
2165 selection.selEnd = to ;
2166 ::SetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
2167 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
2168 TEDelete( teH ) ;
2169 }
2170 else
2171 {
2172 //TODO
2173 }
2174 Refresh() ;
2175 }
2176
2177 void wxTextCtrl::SetSelection(long from, long to)
2178 {
2179 if ( m_windowStyle & wxTE_PASSWORD )
2180 {
2181 ControlEditTextSelectionRec selection ;
2182 TEHandle teH ;
2183 long size ;
2184
2185 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
2186
2187 selection.selStart = from ;
2188 selection.selEnd = to ;
2189
2190 ::SetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
2191 TESetSelect( selection.selStart , selection.selEnd , teH ) ;
2192 }
2193 else
2194 {
2195 STPTextPaneVars **tpvars;
2196 /* set up our locals */
2197 tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
2198 /* and our drawing environment as the operation
2199 may force a redraw in the text area. */
2200 SetPort((**tpvars).fDrawingEnvironment);
2201 /* change the selection */
2202 TXNSetSelection( (**tpvars).fTXNRec, from, to);
2203 }
2204 }
2205
2206 bool wxTextCtrl::LoadFile(const wxString& file)
2207 {
2208 if ( wxTextCtrlBase::LoadFile(file) )
2209 {
2210 return TRUE;
2211 }
2212
2213 return FALSE;
2214 }
2215
2216 void wxTextCtrl::WriteText(const wxString& text)
2217 {
2218 wxString value ;
2219 if( wxApp::s_macDefaultEncodingIsPC )
2220 value = wxMacMakeMacStringFromPC( text ) ;
2221 else
2222 value = text ;
2223 if ( m_windowStyle & wxTE_PASSWORD )
2224 {
2225 TEHandle teH ;
2226 long size ;
2227
2228 ::GetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
2229 TEInsert( value , value.Length() , teH ) ;
2230 }
2231 else
2232 {
2233 STPTextPaneVars **tpvars;
2234 /* set up locals */
2235 tpvars = (STPTextPaneVars **) GetControlReference(m_macControl);
2236 /* set the text in the record */
2237 TXNSetData( (**tpvars).fTXNRec, kTXNTextData, (const char*)value, value.Length(),
2238 kTXNUseCurrentSelection, kTXNUseCurrentSelection);
2239 }
2240 Refresh() ;
2241 }
2242
2243 void wxTextCtrl::AppendText(const wxString& text)
2244 {
2245 SetInsertionPointEnd();
2246 WriteText(text);
2247 }
2248
2249 void wxTextCtrl::Clear()
2250 {
2251 if ( m_windowStyle & wxTE_PASSWORD )
2252 {
2253
2254 ::SetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 0 , (char*) ((const char*)NULL) ) ;
2255 }
2256 else
2257 {
2258 mUPDoEditCommand( m_macControl , kmUPClear) ;
2259 }
2260 Refresh() ;
2261 }
2262
2263 bool wxTextCtrl::IsModified() const
2264 {
2265 return TRUE;
2266 }
2267
2268 bool wxTextCtrl::IsEditable() const
2269 {
2270 return IsEnabled();
2271 }
2272
2273 bool wxTextCtrl::AcceptsFocus() const
2274 {
2275 // we don't want focus if we can't be edited
2276 return IsEditable() && wxControl::AcceptsFocus();
2277 }
2278
2279 wxSize wxTextCtrl::DoGetBestSize() const
2280 {
2281 int wText = 100 ;
2282
2283 int hText ;
2284 if ( UMAHasAppearance() )
2285 hText = 13 ;
2286 else
2287 hText = 24 ;
2288 hText += 2 * m_macHorizontalBorder ;
2289 /*
2290 int cx, cy;
2291 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
2292
2293 int wText = DEFAULT_ITEM_WIDTH;
2294
2295 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
2296
2297 return wxSize(wText, hText);
2298 */
2299 if ( m_windowStyle & wxTE_MULTILINE )
2300 {
2301 hText *= wxMin(GetNumberOfLines(), 5);
2302 }
2303 //else: for single line control everything is ok
2304 return wxSize(wText, hText);
2305 }
2306
2307 // ----------------------------------------------------------------------------
2308 // Undo/redo
2309 // ----------------------------------------------------------------------------
2310
2311 void wxTextCtrl::Undo()
2312 {
2313 if (CanUndo())
2314 {
2315 }
2316 }
2317
2318 void wxTextCtrl::Redo()
2319 {
2320 if (CanRedo())
2321 {
2322 }
2323 }
2324
2325 bool wxTextCtrl::CanUndo() const
2326 {
2327 return FALSE ;
2328 }
2329
2330 bool wxTextCtrl::CanRedo() const
2331 {
2332 return FALSE ;
2333 }
2334
2335 // Makes 'unmodified'
2336 void wxTextCtrl::DiscardEdits()
2337 {
2338 // TODO
2339 }
2340
2341 int wxTextCtrl::GetNumberOfLines() const
2342 {
2343 // TODO change this if possible to reflect real lines
2344 wxString content = GetValue() ;
2345
2346 int count = 1;
2347 for (int i = 0; i < content.Length() ; i++)
2348 {
2349 if (content[i] == '\r') count++;
2350 }
2351
2352 return count;
2353 }
2354
2355 long wxTextCtrl::XYToPosition(long x, long y) const
2356 {
2357 // TODO
2358 return 0;
2359 }
2360
2361 bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
2362 {
2363 return FALSE ;
2364 }
2365
2366 void wxTextCtrl::ShowPosition(long pos)
2367 {
2368 // TODO
2369 }
2370
2371 int wxTextCtrl::GetLineLength(long lineNo) const
2372 {
2373 // TODO change this if possible to reflect real lines
2374 wxString content = GetValue() ;
2375
2376 // Find line first
2377 int count = 0;
2378 for (int i = 0; i < content.Length() ; i++)
2379 {
2380 if (count == lineNo)
2381 {
2382 // Count chars in line then
2383 count = 0;
2384 for (int j = i; j < content.Length(); j++)
2385 {
2386 count++;
2387 if (content[j] == '\r') return count;
2388 }
2389
2390 return count;
2391 }
2392 if (content[i] == '\r') count++;
2393 }
2394 return 0;
2395 }
2396
2397 wxString wxTextCtrl::GetLineText(long lineNo) const
2398 {
2399 // TODO change this if possible to reflect real lines
2400 wxString content = GetValue() ;
2401
2402 // Find line first
2403 int count = 0;
2404 for (int i = 0; i < content.Length() ; i++)
2405 {
2406 if (count == lineNo)
2407 {
2408 // Add chars in line then
2409 wxString tmp("");
2410
2411 for (int j = i; j < content.Length(); j++)
2412 {
2413 if (content[j] == '\r')
2414 return tmp;
2415
2416 tmp += content[j];
2417 }
2418
2419 return tmp;
2420 }
2421 if (content[i] == '\r') count++;
2422 }
2423 return wxString("");
2424 }
2425
2426 /*
2427 * Text item
2428 */
2429
2430 void wxTextCtrl::Command(wxCommandEvent & event)
2431 {
2432 SetValue (event.GetString());
2433 ProcessCommand (event);
2434 }
2435
2436 void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
2437 {
2438 // By default, load the first file into the text window.
2439 if (event.GetNumberOfFiles() > 0)
2440 {
2441 LoadFile(event.GetFiles()[0]);
2442 }
2443 }
2444
2445 void wxTextCtrl::OnChar(wxKeyEvent& event)
2446 {
2447 switch ( event.KeyCode() )
2448 {
2449 case WXK_RETURN:
2450 if (m_windowStyle & wxPROCESS_ENTER)
2451 {
2452 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
2453 event.SetEventObject( this );
2454 if ( GetEventHandler()->ProcessEvent(event) )
2455 return;
2456 }
2457 if ( !(m_windowStyle & wxTE_MULTILINE) )
2458 {
2459 wxWindow *parent = GetParent();
2460 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
2461 parent = parent->GetParent() ;
2462 }
2463 if ( parent && parent->GetDefaultItem() )
2464 {
2465 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
2466 wxButton);
2467 if ( def && def->IsEnabled() )
2468 {
2469 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
2470 event.SetEventObject(def);
2471 def->Command(event);
2472 return ;
2473 }
2474 }
2475 }
2476 //else: multiline controls need Enter for themselves
2477
2478 break;
2479
2480 case WXK_TAB:
2481 // always produce navigation event - even if we process TAB
2482 // ourselves the fact that we got here means that the user code
2483 // decided to skip processing of this TAB - probably to let it
2484 // do its default job.
2485 {
2486 wxNavigationKeyEvent eventNav;
2487 eventNav.SetDirection(!event.ShiftDown());
2488 eventNav.SetWindowChange(event.ControlDown());
2489 eventNav.SetEventObject(this);
2490
2491 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
2492 return;
2493 event.Skip() ;
2494 return ;
2495 }
2496 break;
2497 }
2498
2499 EventRecord *ev = wxTheApp->MacGetCurrentEvent() ;
2500 short keycode ;
2501 short keychar ;
2502 keychar = short(ev->message & charCodeMask);
2503 keycode = short(ev->message & keyCodeMask) >> 8 ;
2504 UMAHandleControlKey( m_macControl , keycode , keychar , ev->modifiers ) ;
2505 if ( keychar >= 0x20 || event.KeyCode() == WXK_RETURN || event.KeyCode() == WXK_DELETE || event.KeyCode() == WXK_BACK)
2506 {
2507 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
2508 event.SetString( GetValue() ) ;
2509 event.SetEventObject( this );
2510 GetEventHandler()->ProcessEvent(event);
2511 }
2512
2513 }
2514
2515 // ----------------------------------------------------------------------------
2516 // standard handlers for standard edit menu events
2517 // ----------------------------------------------------------------------------
2518
2519 void wxTextCtrl::OnCut(wxCommandEvent& event)
2520 {
2521 Cut();
2522 }
2523
2524 void wxTextCtrl::OnCopy(wxCommandEvent& event)
2525 {
2526 Copy();
2527 }
2528
2529 void wxTextCtrl::OnPaste(wxCommandEvent& event)
2530 {
2531 Paste();
2532 }
2533
2534 void wxTextCtrl::OnUndo(wxCommandEvent& event)
2535 {
2536 Undo();
2537 }
2538
2539 void wxTextCtrl::OnRedo(wxCommandEvent& event)
2540 {
2541 Redo();
2542 }
2543
2544 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
2545 {
2546 event.Enable( CanCut() );
2547 }
2548
2549 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
2550 {
2551 event.Enable( CanCopy() );
2552 }
2553
2554 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
2555 {
2556 event.Enable( CanPaste() );
2557 }
2558
2559 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
2560 {
2561 event.Enable( CanUndo() );
2562 }
2563
2564 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
2565 {
2566 event.Enable( CanRedo() );
2567 }
2568
2569 #endif
2570
2571 #endif
2572 // wxUSE_TEXTCTRL