1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
21 #include <sys/types.h>
30 #include "wx/button.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"
39 #if defined(__BORLANDC__) && !defined(__WIN32__)
41 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
45 #include "wx/mac/uma.h"
49 #if wxUSE_MLTE == 0 // old textctrl implementation
51 #if !USE_SHARED_LIBRARY
52 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
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
)
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
)
72 wxTextCtrl::wxTextCtrl()
76 const short kVerticalMargin
= 2 ;
77 const short kHorizontalMargin
= 2 ;
79 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
82 const wxSize
& size
, long style
,
83 const wxValidator
& validator
,
86 // base initialization
87 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
90 wxSize mySize
= size
;
91 if ( UMAHasAppearance() )
93 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
94 m_macVerticalBorder
= 5 ;
98 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
99 m_macVerticalBorder
= 0 ;
106 if ( mySize
.y
== -1 )
108 if ( UMAHasAppearance() )
113 mySize
.y
+= 2 * m_macVerticalBorder
;
116 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
118 if ( m_windowStyle
& wxTE_MULTILINE
)
120 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
121 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
123 m_windowStyle
|= wxTE_PROCESS_ENTER
;
127 m_macControl
= ::NewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
128 ( style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
129 MacPostControlCreate() ;
137 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
138 (*teH
)->lineHeight
= -1 ;
141 if( wxApp::s_macDefaultEncodingIsPC
)
142 value
= wxMacMakeMacStringFromPC( st
) ;
145 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
150 wxString
wxTextCtrl::GetValue() const
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
) ;
158 return wxString(wxBuffer
);
161 void wxTextCtrl::GetSelection(long* from
, long* to
) const
163 ControlEditTextSelectionRec selection
;
167 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
169 *from
= (**teH
).selStart
;
170 *to
= (**teH
).selEnd
;
173 void wxTextCtrl::SetValue(const wxString
& st
)
177 if( wxApp::s_macDefaultEncodingIsPC
)
178 value
= wxMacMakeMacStringFromPC( st
) ;
181 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
182 WindowRef window
= GetMacRootWindow() ;
185 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
188 wxMacDrawingHelper
help( win
) ;
189 // the mac control manager always assumes to have the origin at 0,0
192 bool hasTabBehind
= false ;
193 wxWindow
* parent
= GetParent() ;
196 if( parent
->MacGetWindowData() )
198 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
202 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
204 if ( ((wxControl
*)parent
)->GetMacControl() )
205 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
209 parent
= parent
->GetParent() ;
212 UMADrawControl( m_macControl
) ;
213 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
218 // Clipboard operations
219 void wxTextCtrl::Copy()
226 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
233 void wxTextCtrl::Cut()
240 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
244 // MacInvalidateControl() ;
248 void wxTextCtrl::Paste()
255 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
258 WindowRef window
= GetMacRootWindow() ;
261 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
264 wxMacDrawingHelper
help( win
) ;
265 // the mac control manager always assumes to have the origin at 0,0
268 bool hasTabBehind
= false ;
269 wxWindow
* parent
= GetParent() ;
272 if( parent
->MacGetWindowData() )
274 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
278 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
280 if ( ((wxControl
*)parent
)->GetMacControl() )
281 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
285 parent
= parent
->GetParent() ;
288 UMADrawControl( m_macControl
) ;
289 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
295 bool wxTextCtrl::CanCopy() const
297 // Can copy if there's a selection
299 GetSelection(& from
, & to
);
303 bool wxTextCtrl::CanCut() const
305 // Can cut if there's a selection
307 GetSelection(& from
, & to
);
311 bool wxTextCtrl::CanPaste() const
318 OSStatus err
= noErr
;
321 err
= GetCurrentScrap( &scrapRef
);
322 if ( err
!= noTypeErr
&& err
!= memFullErr
)
324 ScrapFlavorFlags flavorFlags
;
327 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
329 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
338 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
346 void wxTextCtrl::SetEditable(bool editable
)
349 UMAActivateControl( m_macControl
) ;
351 UMADeactivateControl( m_macControl
) ;
354 void wxTextCtrl::SetInsertionPoint(long pos
)
356 SetSelection( pos
, pos
) ;
359 void wxTextCtrl::SetInsertionPointEnd()
361 long pos
= GetLastPosition();
362 SetInsertionPoint(pos
);
365 long wxTextCtrl::GetInsertionPoint() const
367 ControlEditTextSelectionRec selection
;
371 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
372 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
373 return (**teH
).selStart
;
376 long wxTextCtrl::GetLastPosition() const
378 ControlEditTextSelectionRec selection
;
382 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
384 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
385 return (**teH
).teLength
;
388 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
393 ControlEditTextSelectionRec selection
;
395 selection
.selStart
= from
;
396 selection
.selEnd
= to
;
397 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
398 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
399 TESetSelect( from
, to
, teH
) ;
401 TEInsert( value
, value
.Length() , teH
) ;
405 void wxTextCtrl::Remove(long from
, long to
)
410 ControlEditTextSelectionRec selection
;
412 selection
.selStart
= from
;
413 selection
.selEnd
= to
;
414 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
415 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
420 void wxTextCtrl::SetSelection(long from
, long to
)
422 ControlEditTextSelectionRec selection
;
426 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
428 selection
.selStart
= from
;
429 selection
.selEnd
= to
;
431 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
432 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
435 bool wxTextCtrl::LoadFile(const wxString
& file
)
437 if ( wxTextCtrlBase::LoadFile(file
) )
445 void wxTextCtrl::WriteText(const wxString
& text
)
450 memcpy( wxBuffer
, text
, text
.Length() ) ;
451 wxBuffer
[text
.Length() ] = 0 ;
452 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
454 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
456 TEInsert( wxBuffer
, strlen( wxBuffer
) , teH
) ;
460 void wxTextCtrl::AppendText(const wxString
& text
)
462 SetInsertionPointEnd();
466 void wxTextCtrl::Clear()
468 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
472 bool wxTextCtrl::IsModified() const
477 bool wxTextCtrl::IsEditable() const
482 bool wxTextCtrl::AcceptsFocus() const
484 // we don't want focus if we can't be edited
485 return IsEditable() && wxControl::AcceptsFocus();
488 wxSize
wxTextCtrl::DoGetBestSize() const
493 if ( UMAHasAppearance() )
497 hText
+= 2 * m_macHorizontalBorder
;
500 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
502 int wText = DEFAULT_ITEM_WIDTH;
504 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
506 return wxSize(wText, hText);
508 if ( m_windowStyle
& wxTE_MULTILINE
)
510 hText
*= wxMin(GetNumberOfLines(), 5);
512 //else: for single line control everything is ok
513 return wxSize(wText
, hText
);
516 // ----------------------------------------------------------------------------
518 // ----------------------------------------------------------------------------
520 void wxTextCtrl::Undo()
527 void wxTextCtrl::Redo()
534 bool wxTextCtrl::CanUndo() const
539 bool wxTextCtrl::CanRedo() const
544 // Makes 'unmodified'
545 void wxTextCtrl::DiscardEdits()
550 int wxTextCtrl::GetNumberOfLines() const
553 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
556 for (int i
= 0; i
< actualsize
; i
++)
558 if (wxBuffer
[i
] == '\r') count
++;
564 long wxTextCtrl::XYToPosition(long x
, long y
) const
570 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
575 void wxTextCtrl::ShowPosition(long pos
)
580 int wxTextCtrl::GetLineLength(long lineNo
) const
583 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
587 for (int i
= 0; i
< actualsize
; i
++)
591 // Count chars in line then
593 for (int j
= i
; j
< actualsize
; j
++)
596 if (wxBuffer
[j
] == '\r') return count
;
601 if (wxBuffer
[i
] == '\r') count
++;
607 wxString
wxTextCtrl::GetLineText(long lineNo
) const
610 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
614 for (int i
= 0; i
< actualsize
; i
++)
618 // Add chars in line then
621 for (int j
= i
; j
< actualsize
; j
++)
623 if (wxBuffer
[j
] == '\r')
631 if (wxBuffer
[i
] == '\r') count
++;
641 void wxTextCtrl::Command(wxCommandEvent
& event
)
643 SetValue (event
.GetString());
644 ProcessCommand (event
);
647 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
649 // By default, load the first file into the text window.
650 if (event
.GetNumberOfFiles() > 0)
652 LoadFile(event
.GetFiles()[0]);
656 void wxTextCtrl::OnChar(wxKeyEvent
& key_event
)
658 bool eat_key
= FALSE
;
660 switch ( key_event
.KeyCode() )
663 if (m_windowStyle
& wxPROCESS_ENTER
)
665 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
666 event
.SetEventObject( this );
667 event
.SetString( GetValue() );
668 if ( GetEventHandler()->ProcessEvent(event
) )
671 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
673 wxWindow
*parent
= GetParent();
674 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
675 parent
= parent
->GetParent() ;
677 if ( parent
&& parent
->GetDefaultItem() )
679 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
681 if ( def
&& def
->IsEnabled() )
683 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
684 event
.SetEventObject(def
);
690 // this will make wxWindows eat the ENTER key so that
691 // we actually prevent line wrapping in a single line
699 // always produce navigation event - even if we process TAB
700 // ourselves the fact that we got here means that the user code
701 // decided to skip processing of this TAB - probably to let it
702 // do its default job.
704 wxNavigationKeyEvent eventNav
;
705 eventNav
.SetDirection(!key_event
.ShiftDown());
706 eventNav
.SetWindowChange(key_event
.ControlDown());
707 eventNav
.SetEventObject(this);
709 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
718 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent();
719 short keychar
= short(ev
->message
& charCodeMask
);
722 short keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
723 ::HandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
);
725 if ( keychar
>= 0x20 ||
726 key_event
.KeyCode() == WXK_RETURN
||
727 key_event
.KeyCode() == WXK_DELETE
||
728 key_event
.KeyCode() == WXK_BACK
)
730 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
731 event
.SetString( GetValue() ) ;
732 event
.SetEventObject( this );
733 GetEventHandler()->ProcessEvent(event
);
737 // ----------------------------------------------------------------------------
738 // standard handlers for standard edit menu events
739 // ----------------------------------------------------------------------------
741 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
746 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
751 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
756 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
761 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
766 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
768 event
.Enable( CanCut() );
771 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
773 event
.Enable( CanCopy() );
776 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
778 event
.Enable( CanPaste() );
781 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
783 event
.Enable( CanUndo() );
786 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
788 event
.Enable( CanRedo() );
793 extern wxApp
*wxTheApp
;
794 // CS:We will replace the TextEdit by using the MultiLanguageTextEngine based on the following code written by apple
800 mUPControl implementation.
803 © Copyright 2000 Apple Computer, Inc. All rights reserved.
806 IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
807 ("Apple") in consideration of your agreement to the following terms, and your
808 use, installation, modification or redistribution of this Apple software
809 constitutes acceptance of these terms. If you do not agree with these terms,
810 please do not use, install, modify or redistribute this Apple software.
812 In consideration of your agreement to abide by the following terms, and subject
813 to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
814 copyrights in this original Apple software (the "Apple Software"), to use,
815 reproduce, modify and redistribute the Apple Software, with or without
816 modifications, in source and/or binary forms; provided that if you redistribute
817 the Apple Software in its entirety and without modifications, you must retain
818 this notice and the following text and disclaimers in all such redistributions of
819 the Apple Software. Neither the name, trademarks, service marks or logos of
820 Apple Computer, Inc. may be used to endorse or promote products derived from the
821 Apple Software without specific prior written permission from Apple. Except as
822 expressly stated in this notice, no other rights or licenses, express or implied,
823 are granted by Apple herein, including but not limited to any patent rights that
824 may be infringed by your derivative works or by other works in which the Apple
825 Software may be incorporated.
827 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
828 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
829 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
830 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
831 COMBINATION WITH YOUR PRODUCTS.
833 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
834 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
835 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
836 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
837 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
838 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
839 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
841 Change History (most recent first):
842 Fri, Jan 28, 2000 -- created
845 #include "MacTextEditor.h"
849 /* kmUPTextPart is the part code we return to indicate the user has clicked
850 in the text area of our control */
851 #define kmUPTextPart 1
853 /* kmUPScrollPart is the part code we return to indicate the user has clicked
854 in the scroll bar part of the control. */
855 #define kmUPScrollPart 2
858 /* routines for using existing user pane controls.
859 These routines are useful for cases where you would like to use an
860 existing user pane control in, say, a dialog window as a scrolling
863 /* mUPOpenControl initializes a user pane control so it will be drawn
864 and will behave as a scrolling text edit field inside of a window.
865 This routine performs all of the initialization steps necessary,
866 except it does not create the user pane control itself. theControl
867 should refer to a user pane control that you have either created
868 yourself or extracted from a dialog's control heirarchy using
869 the GetDialogItemAsControl routine. */
870 OSStatus
mUPOpenControl(ControlHandle theControl
);
872 /* mUPCloseControl deallocates all of the structures allocated
873 by mUPOpenControl. */
874 OSStatus
mUPCloseControl(ControlHandle theControl
);
878 /* routines for creating new scrolling text user pane controls.
879 These routines allow you to create new scrolling text
880 user pane controls. */
882 /* mUPCreateControl creates a new user pane control and then it passes it
883 to mUPOpenControl to initialize it as a scrolling text user pane control. */
884 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
);
886 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
887 OSStatus
mUPDisposeControl(ControlHandle theControl
);
890 /* Utility Routines */
892 /* mUPSetText replaces the contents of the selection with the unicode
893 text described by the text and count parameters:.
894 text = pointer to unicode text buffer
895 count = number of bytes in the buffer. */
896 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
);
898 /* mUPGetText returns the current text data being displayed inside of
899 the mUPControl. When noErr is returned, *theText contain a new
900 handle containing all of the Unicode text copied from the current
901 selection. It is the caller's responsibiliby to dispose of this handle. */
902 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
);
905 /* mUPSetSelection sets the text selection and autoscrolls the text view
906 so either the cursor or the selction is in the view. */
907 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
);
911 /* IsmUPControl returns true if theControl is not NULL
912 and theControl refers to a mUP Control. */
913 Boolean
IsmUPControl(ControlHandle theControl
);
917 /* Edit commands for mUP Controls. */
926 /* mUPDoEditCommand performs the editing command specified
927 in the editCommand parameter. The mUPControl's text
928 and scroll bar are redrawn and updated as necessary. */
929 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
);
934 /* mUPGetContents returns the entire contents of the control including the text
935 and the formatting information. */
936 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
);
937 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
938 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
);
944 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
945 routine. In our focus switching routine this part code is understood
946 as meaning 'the user has clicked in the control and we need to switch
947 the current focus to ourselves before we can continue'. */
948 #define kUserClickedToFocusPart 100
951 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
952 slow the speed of 'auto scrolling' inside of our clickloop routine.
953 This value prevents the text from wizzzzzing by while the mouse
954 is being held down inside of the text area. */
955 #define kmUPClickScrollDelayTicks 3
958 /* STPTextPaneVars is a structure used for storing the the mUP Control's
959 internal variables and state information. A handle to this record is
960 stored in the pane control's reference value field using the
961 SetControlReference routine. */
964 /* OS records referenced */
965 TXNObject fTXNRec
; /* the txn record */
966 TXNFrameID fTXNFrame
; /* the txn frame ID */
967 ControlHandle fUserPaneRec
; /* handle to the user pane control */
968 WindowPtr fOwner
; /* window containing control */
969 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
971 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
972 Boolean fIsActive
; /* true while the control is drawn in the active state */
973 Boolean fTEActive
; /* reflects the activation state of the text edit record */
974 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
975 /* calculated locations */
976 Rect fRTextArea
; /* area where the text is drawn */
977 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
978 Rect fRTextOutline
; /* rectangle used to draw the border */
979 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
980 /* our focus advance override routine */
981 EventHandlerUPP handlerUPP
;
982 EventHandlerRef handlerRef
;
988 /* Univerals Procedure Pointer variables used by the
989 mUP Control. These variables are set up
990 the first time that mUPOpenControl is called. */
991 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
992 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
993 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
994 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
995 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
996 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
997 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
999 /* events handled by our focus advance override routine */
1001 static const EventTypeSpec gMLTEEvents
[] = { { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} };
1002 #define kMLTEEventCount (sizeof( gMLTEEvents ) / sizeof( EventTypeSpec ))
1006 /* TPActivatePaneText activates or deactivates the text edit record
1007 according to the value of setActive. The primary purpose of this
1008 routine is to ensure each call is only made once. */
1009 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
1010 STPTextPaneVars
*varsp
;
1012 if (varsp
->fTEActive
!= setActive
) {
1014 varsp
->fTEActive
= setActive
;
1016 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
1018 if (varsp
->fInFocus
)
1019 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
1024 /* TPFocusPaneText set the focus state for the text record. */
1025 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
1026 STPTextPaneVars
*varsp
;
1028 if (varsp
->fInFocus
!= setFocus
) {
1029 varsp
->fInFocus
= setFocus
;
1030 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
1035 /* TPPaneDrawProc is called to redraw the control and for update events
1036 referring to the control. This routine erases the text area's background,
1037 and redraws the text. This routine assumes the scroll bar has been
1038 redrawn by a call to DrawControls. */
1039 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
1040 STPTextPaneVars
**tpvars
, *varsp
;
1043 /* set up our globals */
1044 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1045 if (tpvars
!= NULL
) {
1046 state
= HGetState((Handle
) tpvars
);
1047 HLock((Handle
) tpvars
);
1050 /* save the drawing state */
1051 SetPort((**tpvars
).fDrawingEnvironment
);
1052 /* verify our boundary */
1053 GetControlBounds(theControl
, &bounds
);
1054 if ( ! EqualRect(&bounds
, &varsp
->fRTextArea
) ) {
1055 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1056 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1057 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1058 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
1059 TXNSetFrameBounds( varsp
->fTXNRec
, bounds
.top
, bounds
.left
, bounds
.bottom
, bounds
.right
, varsp
->fTXNFrame
);
1062 /* update the text region */
1063 EraseRgn(varsp
->fTextBackgroundRgn
);
1064 TXNDraw(varsp
->fTXNRec
, NULL
);
1065 /* restore the drawing environment */
1066 /* draw the text frame and focus frame (if necessary) */
1067 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1068 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
1069 /* release our globals */
1070 HSetState((Handle
) tpvars
, state
);
1075 /* TPPaneHitTestProc is called when the control manager would
1076 like to determine what part of the control the mouse resides over.
1077 We also call this routine from our tracking proc to determine how
1078 to handle mouse clicks. */
1079 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
1080 STPTextPaneVars
**tpvars
;
1081 ControlPartCode result
;
1083 /* set up our locals and lock down our globals*/
1085 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1086 if (tpvars
!= NULL
) {
1087 state
= HGetState((Handle
) tpvars
);
1088 HLock((Handle
) tpvars
);
1089 /* find the region where we clicked */
1090 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
1091 result
= kmUPTextPart
;
1093 /* release oure globals */
1094 HSetState((Handle
) tpvars
, state
);
1103 /* TPPaneTrackingProc is called when the mouse is being held down
1104 over our control. This routine handles clicks in the text area
1105 and in the scroll bar. */
1106 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
1107 STPTextPaneVars
**tpvars
, *varsp
;
1109 ControlPartCode partCodeResult
;
1110 /* make sure we have some variables... */
1112 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1113 if (tpvars
!= NULL
) {
1115 state
= HGetState((Handle
) tpvars
);
1116 HLock((Handle
) tpvars
);
1118 /* we don't do any of these functions unless we're in focus */
1119 if ( ! varsp
->fInFocus
) {
1121 owner
= GetControlOwner(theControl
);
1122 ClearKeyboardFocus(owner
);
1123 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
1125 /* find the location for the click */
1126 switch (TPPaneHitTestProc(theControl
, startPt
)) {
1128 /* handle clicks in the text part */
1130 { SetPort((**tpvars
).fDrawingEnvironment
);
1131 TXNClick( varsp
->fTXNRec
, GetCurrentEventRecord());
1137 HSetState((Handle
) tpvars
, state
);
1139 return partCodeResult
;
1143 /* TPPaneIdleProc is our user pane idle routine. When our text field
1144 is active and in focus, we use this routine to set the cursor. */
1145 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
1146 STPTextPaneVars
**tpvars
, *varsp
;
1148 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1149 if (tpvars
!= NULL
) {
1150 /* if we're not active, then we have nothing to say about the cursor */
1151 if ((**tpvars
).fIsActive
) {
1155 /* lock down the globals */
1156 state
= HGetState((Handle
) tpvars
);
1157 HLock((Handle
) tpvars
);
1159 /* get the current mouse coordinates (in our window) */
1161 SetPort(GetWindowPort(GetControlOwner(theControl
)));
1163 SetPort((GrafPtr
) GetWindowPort(GetControlOwner(theControl
)));
1166 /* there's a 'focus thing' and an 'unfocused thing' */
1167 if (varsp
->fInFocus
) {
1168 /* flash the cursor */
1169 SetPort((**tpvars
).fDrawingEnvironment
);
1170 TXNIdle(varsp
->fTXNRec
);
1171 /* set the cursor */
1172 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
1174 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
1175 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
1177 } else SetThemeCursor(kThemeArrowCursor
);
1179 /* if it's in our bounds, set the cursor */
1180 GetControlBounds(theControl
, &bounds
);
1181 if (PtInRect(mousep
, &bounds
))
1182 SetThemeCursor(kThemeArrowCursor
);
1185 HSetState((Handle
) tpvars
, state
);
1191 /* TPPaneKeyDownProc is called whenever a keydown event is directed
1192 at our control. Here, we direct the keydown event to the text
1193 edit record and redraw the scroll bar and text field as appropriate. */
1194 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
1195 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
1196 STPTextPaneVars
**tpvars
;
1197 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1198 if (tpvars
!= NULL
) {
1199 if ((**tpvars
).fInFocus
) {
1200 /* turn autoscrolling on and send the key event to text edit */
1201 SetPort((**tpvars
).fDrawingEnvironment
);
1202 TXNKeyDown( (**tpvars
).fTXNRec
, GetCurrentEventRecord());
1205 return kControlEntireControl
;
1209 /* TPPaneActivateProc is called when the window containing
1210 the user pane control receives activate events. Here, we redraw
1211 the control and it's text as necessary for the activation state. */
1212 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
1214 STPTextPaneVars
**tpvars
, *varsp
;
1217 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1218 if (tpvars
!= NULL
) {
1219 state
= HGetState((Handle
) tpvars
);
1220 HLock((Handle
) tpvars
);
1222 /* de/activate the text edit record */
1223 SetPort((**tpvars
).fDrawingEnvironment
);
1224 GetControlBounds(theControl
, &bounds
);
1225 varsp
->fIsActive
= activating
;
1226 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1227 /* redraw the frame */
1228 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1229 if (varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
1230 HSetState((Handle
) tpvars
, state
);
1235 /* TPPaneFocusProc is called when every the focus changes to or
1236 from our control. Herein, switch the focus appropriately
1237 according to the parameters and redraw the control as
1239 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
1240 ControlPartCode focusResult
;
1241 STPTextPaneVars
**tpvars
, *varsp
;
1244 focusResult
= kControlFocusNoPart
;
1245 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1246 if (tpvars
!= NULL
) {
1247 state
= HGetState((Handle
) tpvars
);
1248 HLock((Handle
) tpvars
);
1250 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
1251 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
1252 and kControlFocusNextPart will be received. When the user clicks in our field
1253 and it is not the current focus, then the constant kUserClickedToFocusPart will
1254 be received. The constant kControlFocusNoPart will be received when our control
1255 is the current focus and the user clicks in another control. In your focus routine,
1256 you should respond to these codes as follows:
1258 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
1259 the control and the focus rectangle as necessary.
1261 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
1262 depending on its current state. redraw the control and the focus rectangle
1263 as appropriate for the new focus state. If the focus state is 'off', return the constant
1264 kControlFocusNoPart, otherwise return a non-zero part code.
1265 kUserClickedToFocusPart - is a constant defined for this example. You should
1266 define your own value for handling click-to-focus type events. */
1267 /* save the drawing state */
1268 SetPort((**tpvars
).fDrawingEnvironment
);
1269 /* calculate the next highlight state */
1272 case kControlFocusNoPart
:
1273 TPFocusPaneText(tpvars
, false);
1274 focusResult
= kControlFocusNoPart
;
1276 case kUserClickedToFocusPart
:
1277 TPFocusPaneText(tpvars
, true);
1280 case kControlFocusPrevPart
:
1281 case kControlFocusNextPart
:
1282 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
1283 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
1286 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1287 /* redraw the text fram and focus rectangle to indicate the
1289 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1290 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
1292 HSetState((Handle
) tpvars
, state
);
1307 //This our carbon event handler for unicode key downs
1309 static pascal OSStatus
FocusAdvanceOverride(EventHandlerCallRef myHandler
, EventRef event
, void* userData
) {
1311 STPTextPaneVars
**tpvars
;
1313 unsigned short mUnicodeText
;
1314 ByteCount charCounts
=0;
1315 /* get our window pointer */
1316 tpvars
= (STPTextPaneVars
**) userData
;
1317 window
= (**tpvars
).fOwner
;
1318 //find out how many bytes are needed
1319 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1320 typeUnicodeText
, NULL
, 0, &charCounts
, NULL
);
1321 if (err
!= noErr
) goto bail
;
1322 /* we're only looking at single characters */
1323 if (charCounts
!= 2) { err
= eventNotHandledErr
; goto bail
; }
1324 /* get the character */
1325 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1326 typeUnicodeText
, NULL
, sizeof(mUnicodeText
),
1327 &charCounts
, (char*) &mUnicodeText
);
1328 if (err
!= noErr
) goto bail
;
1329 /* if it's not the tab key, forget it... */
1330 if ((mUnicodeText
!= '\t')) { err
= eventNotHandledErr
; goto bail
; }
1331 /* advance the keyboard focus */
1332 AdvanceKeyboardFocus(window
);
1333 /* noErr lets the CEM know we handled the event */
1336 return eventNotHandledErr
;
1341 /* mUPOpenControl initializes a user pane control so it will be drawn
1342 and will behave as a scrolling text edit field inside of a window.
1343 This routine performs all of the initialization steps necessary,
1344 except it does not create the user pane control itself. theControl
1345 should refer to a user pane control that you have either created
1346 yourself or extracted from a dialog's control heirarchy using
1347 the GetDialogItemAsControl routine. */
1348 OSStatus
mUPOpenControl(ControlHandle theControl
, bool multiline
) {
1350 WindowPtr theWindow
;
1351 STPTextPaneVars
**tpvars
, *varsp
;
1353 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
1354 TXNBackground tback
;
1356 /* set up our globals */
1357 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
1358 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
1359 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
1360 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
1361 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
1362 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
1363 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
1365 /* allocate our private storage */
1366 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
1367 SetControlReference(theControl
, (long) tpvars
);
1368 HLock((Handle
) tpvars
);
1370 /* set the initial settings for our private data */
1371 varsp
->fInFocus
= false;
1372 varsp
->fIsActive
= true;
1373 varsp
->fTEActive
= false;
1374 varsp
->fUserPaneRec
= theControl
;
1375 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
1377 varsp
->fDrawingEnvironment
= GetWindowPort(varsp
->fOwner
);
1379 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(varsp
->fOwner
);
1381 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
1382 /* set up the user pane procedures */
1383 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
1384 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
1385 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
1386 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
1387 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
1388 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
1389 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
1390 /* calculate the rectangles used by the control */
1391 GetControlBounds(theControl
, &bounds
);
1392 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1393 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1394 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1395 /* calculate the background region for the text. In this case, it's kindof
1396 and irregular region because we're setting the scroll bar a little ways inside
1397 of the text area. */
1398 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
1400 /* set up the drawing environment */
1401 SetPort(varsp
->fDrawingEnvironment
);
1403 /* create the new edit field */
1404 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
1405 kTXNWantVScrollBarMask
| kTXNAlwaysWrapAtViewEdgeMask
,
1406 kTXNTextEditStyleFrameType
,
1408 kTXNSystemDefaultEncoding
,
1409 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
1411 /* set the field's background */
1412 tback
.bgType
= kTXNBackgroundTypeRGB
;
1413 tback
.bg
.color
= rgbWhite
;
1414 TXNSetBackground( varsp
->fTXNRec
, &tback
);
1416 /* install our focus advance override routine */
1418 varsp
->handlerUPP
= NewEventHandlerUPP(FocusAdvanceOverride
);
1419 err
= InstallWindowEventHandler( varsp
->fOwner
, varsp
->handlerUPP
,
1420 kMLTEEventCount
, gMLTEEvents
, tpvars
, &varsp
->handlerRef
);
1422 /* unlock our storage */
1423 HUnlock((Handle
) tpvars
);
1424 /* perform final activations and setup for our text field. Here,
1425 we assume that the window is going to be the 'active' window. */
1426 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1433 /* mUPCloseControl deallocates all of the structures allocated
1434 by mUPOpenControl. */
1435 OSStatus
mUPCloseControl(ControlHandle theControl
) {
1436 STPTextPaneVars
**tpvars
;
1438 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1439 /* release our sub records */
1440 TXNDeleteObject((**tpvars
).fTXNRec
);
1441 /* remove our focus advance override */
1442 RemoveEventHandler((**tpvars
).handlerRef
);
1443 DisposeEventHandlerUPP((**tpvars
).handlerUPP
);
1444 /* delete our private storage */
1445 DisposeHandle((Handle
) tpvars
);
1446 /* zero the control reference */
1447 SetControlReference(theControl
, 0);
1454 /* mUPSetText replaces the contents of the selection with the unicode
1455 text described by the text and count parameters:.
1456 text = pointer to unicode text buffer
1457 count = number of bytes in the buffer. */
1458 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
) {
1459 STPTextPaneVars
**tpvars
;
1461 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1462 /* set the text in the record */
1463 return TXNSetData( (**tpvars
).fTXNRec
, kTXNUnicodeTextData
, text
, count
,
1464 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1470 /* mUPSetSelection sets the text selection and autoscrolls the text view
1471 so either the cursor or the selction is in the view. */
1472 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
) {
1473 STPTextPaneVars
**tpvars
;
1474 /* set up our locals */
1475 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1476 /* and our drawing environment as the operation
1477 may force a redraw in the text area. */
1478 SetPort((**tpvars
).fDrawingEnvironment
);
1479 /* change the selection */
1480 TXNSetSelection( (**tpvars
).fTXNRec
, selStart
, selEnd
);
1487 /* mUPGetText returns the current text data being displayed inside of
1488 the mUPControl. When noErr is returned, *theText contain a new
1489 handle containing all of the Unicode text copied from the current
1490 selection. It is the caller's responsibiliby to dispose of this handle. */
1491 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
) {
1492 STPTextPaneVars
**tpvars
;
1495 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1496 /* extract the text from the record */
1497 err
= TXNGetData( (**tpvars
).fTXNRec
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, theText
);
1504 /* mUPCreateControl creates a new user pane control and then it passes it
1505 to mUPOpenControl to initialize it as a scrolling text user pane control. */
1506 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
) {
1508 /* the following feature set can be specified in CNTL resources by using
1509 the value 1214. When creating a user pane control, we pass this value
1510 in the 'value' parameter. */
1511 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
1512 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
1513 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
1514 /* create the control */
1515 *theControl
= NewControl(theWindow
, bounds
, "\p", true, featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
1516 /* set up the mUP specific features and data */
1517 mUPOpenControl(*theControl
);
1523 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
1524 OSStatus
mUPDisposeControl(ControlHandle theControl
) {
1525 /* deallocate the mUP specific data */
1526 mUPCloseControl(theControl
);
1527 /* deallocate the user pane control itself */
1528 DisposeControl(theControl
);
1535 /* IsmUPControl returns true if theControl is not NULL
1536 and theControl refers to a mUP Control. */
1537 Boolean
IsmUPControl(ControlHandle theControl
) {
1539 ControlUserPaneFocusUPP localFocusProc
;
1540 /* a NULL control is not a mUP control */
1541 if (theControl
== NULL
) return false;
1542 /* check if the control is using our focus procedure */
1543 theSize
= sizeof(localFocusProc
);
1544 if (GetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
,
1545 sizeof(localFocusProc
), &localFocusProc
, &theSize
) != noErr
) return false;
1546 if (localFocusProc
!= gTPFocusProc
) return false;
1547 /* all tests passed, it's a mUP control */
1552 /* mUPDoEditCommand performs the editing command specified
1553 in the editCommand parameter. The mUPControl's text
1554 and scroll bar are redrawn and updated as necessary. */
1555 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
) {
1556 STPTextPaneVars
**tpvars
;
1557 /* set up our locals */
1558 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1559 /* and our drawing environment as the operation
1560 may force a redraw in the text area. */
1561 SetPort((**tpvars
).fDrawingEnvironment
);
1562 /* perform the editing command */
1563 switch (editCommand
) {
1565 ClearCurrentScrap();
1566 TXNCut((**tpvars
).fTXNRec
);
1567 TXNConvertToPublicScrap();
1570 ClearCurrentScrap();
1571 TXNCopy((**tpvars
).fTXNRec
);
1572 TXNConvertToPublicScrap();
1575 TXNConvertFromPublicScrap();
1576 TXNPaste((**tpvars
).fTXNRec
);
1579 TXNClear((**tpvars
).fTXNRec
);
1587 /* mUPGetContents returns the entire contents of the control including the text
1588 and the formatting information. */
1589 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
) {
1590 STPTextPaneVars
**tpvars
;
1603 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1604 if (theContents
== NULL
) return paramErr
;
1605 /* create a temporary file */
1606 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1607 if (err
!= noErr
) goto bail
;
1608 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPGetContents", &tspec
);
1609 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1610 if (err
!= noErr
) goto bail
;
1613 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1614 if (err
!= noErr
) goto bail
;
1616 err
= TXNSave( (**tpvars
).fTXNRec
, kTXNTextensionFile
, 0, kTXNSystemDefaultEncoding
, &tspec
, trefnum
, 0);
1617 if (err
!= noErr
) goto bail
;
1618 /* get the file length and set the position */
1619 err
= GetEOF(trefnum
, &bytecount
);
1620 if (err
!= noErr
) goto bail
;
1621 err
= SetFPos(trefnum
, fsFromStart
, 0);
1622 if (err
!= noErr
) goto bail
;
1623 /* copy the data fork to a handle */
1624 localdata
= NewHandle(bytecount
);
1625 if (localdata
== NULL
) { err
= memFullErr
; goto bail
; }
1627 err
= FSRead(trefnum
, &bytecount
, *localdata
);
1629 if (err
!= noErr
) goto bail
;
1631 *theContents
= localdata
;
1638 if (trefnum
!= 0) FSClose(trefnum
);
1639 if (texists
) FSpDelete(&tspec
);
1640 if (localdata
!= NULL
) DisposeHandle(localdata
);
1647 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
1648 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
) {
1649 STPTextPaneVars
**tpvars
;
1661 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1662 if (theContents
== NULL
) return paramErr
;
1663 /* create a temporary file */
1664 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1665 if (err
!= noErr
) goto bail
;
1666 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPSetContents", &tspec
);
1667 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1668 if (err
!= noErr
) goto bail
;
1671 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1672 if (err
!= noErr
) goto bail
;
1673 /* save the data to the temporary file */
1674 state
= HGetState(theContents
);
1676 bytecount
= GetHandleSize(theContents
);
1677 err
= FSWrite(trefnum
, &bytecount
, *theContents
);
1678 HSetState(theContents
, state
);
1679 if (err
!= noErr
) goto bail
;
1680 /* reset the file position */
1681 err
= SetFPos(trefnum
, fsFromStart
, 0);
1682 if (err
!= noErr
) goto bail
;
1684 err
= TXNSetDataFromFile((**tpvars
).fTXNRec
, trefnum
, kTXNTextensionFile
, bytecount
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1685 if (err
!= noErr
) goto bail
;
1692 if (trefnum
!= 0) FSClose(trefnum
);
1693 if (texists
) FSpDelete(&tspec
);
1697 #if !USE_SHARED_LIBRARY
1698 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
1700 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
1701 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
1702 EVT_CHAR(wxTextCtrl::OnChar
)
1703 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
1704 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
1705 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
1706 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
1707 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
1709 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
1710 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
1711 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
1712 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
1713 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
1718 wxTextCtrl::wxTextCtrl()
1722 const short kVerticalMargin
= 2 ;
1723 const short kHorizontalMargin
= 2 ;
1725 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1728 const wxSize
& size
, long style
,
1729 const wxValidator
& validator
,
1730 const wxString
& name
)
1732 // base initialization
1733 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
1736 wxSize mySize
= size
;
1737 if ( UMAHasAppearance() )
1739 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
1740 m_macVerticalBorder
= 5 ;
1744 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
1745 m_macVerticalBorder
= 0 ;
1752 if ( mySize
.y
== -1 )
1754 if ( UMAHasAppearance() )
1759 mySize
.y
+= 2 * m_macVerticalBorder
;
1762 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
1764 if ( m_windowStyle
& wxTE_MULTILINE
)
1766 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
1767 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
1769 m_windowStyle
|= wxTE_PROCESS_ENTER
;
1773 if ( style
& wxTE_PASSWORD
)
1775 m_macControl
= ::NewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
1776 kControlEditTextPasswordProc
, (long) this ) ;
1780 if ( mUPCreateControl(parent
->GetMacRootWindow(), &bounds
, &m_macControl
) != noErr
)
1783 MacPostControlCreate() ;
1787 if( wxApp::s_macDefaultEncodingIsPC
)
1788 value
= wxMacMakeMacStringFromPC( st
) ;
1792 if ( style
& wxTE_PASSWORD
)
1794 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1798 STPTextPaneVars
**tpvars
;
1800 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1801 /* set the text in the record */
1802 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1803 kTXNStartOffset
, kTXNEndOffset
);
1809 wxString
wxTextCtrl::GetValue() const
1812 if ( m_windowStyle
& wxTE_PASSWORD
)
1814 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
1818 STPTextPaneVars
**tpvars
;
1821 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1822 /* extract the text from the record */
1824 err
= TXNGetDataEncoded( (**tpvars
).fTXNRec
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1832 actualsize
= GetHandleSize( theText
) ;
1833 strncpy( wxBuffer
, *theText
, actualsize
) ;
1834 DisposeHandle( theText
) ;
1837 wxBuffer
[actualsize
] = 0 ;
1838 if( wxApp::s_macDefaultEncodingIsPC
)
1839 return wxMacMakePCStringFromMac( wxBuffer
) ;
1841 return wxString(wxBuffer
);
1844 void wxTextCtrl::GetSelection(long* from
, long* to
) const
1846 if ( m_windowStyle
& wxTE_PASSWORD
)
1848 ControlEditTextSelectionRec selection
;
1852 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1854 *from
= (**teH
).selStart
;
1855 *to
= (**teH
).selEnd
;
1859 STPTextPaneVars
**tpvars
;
1862 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1864 TXNGetSelection( (**tpvars
).fTXNRec
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1869 void wxTextCtrl::SetValue(const wxString
& st
)
1873 if( wxApp::s_macDefaultEncodingIsPC
)
1874 value
= wxMacMakeMacStringFromPC( st
) ;
1877 if ( m_windowStyle
& wxTE_PASSWORD
)
1879 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1883 STPTextPaneVars
**tpvars
;
1885 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1886 /* set the text in the record */
1887 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1888 kTXNStartOffset
, kTXNEndOffset
);
1890 WindowRef window
= GetMacRootWindow() ;
1893 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1896 wxMacDrawingHelper
help( win
) ;
1897 // the mac control manager always assumes to have the origin at 0,0
1898 SetOrigin( 0 , 0 ) ;
1900 bool hasTabBehind
= false ;
1901 wxWindow
* parent
= GetParent() ;
1904 if( parent
->MacGetWindowData() )
1906 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
1910 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
1912 if ( ((wxControl
*)parent
)->GetMacControl() )
1913 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
1917 parent
= parent
->GetParent() ;
1920 UMADrawControl( m_macControl
) ;
1921 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
1926 // Clipboard operations
1927 void wxTextCtrl::Copy()
1931 if ( m_windowStyle
& wxTE_PASSWORD
)
1936 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1938 ClearCurrentScrap();
1943 mUPDoEditCommand( m_macControl
, kmUPCopy
) ;
1948 void wxTextCtrl::Cut()
1952 if ( m_windowStyle
& wxTE_PASSWORD
)
1957 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1959 ClearCurrentScrap();
1961 // MacInvalidateControl() ;
1965 mUPDoEditCommand( m_macControl
, kmUPCut
) ;
1970 void wxTextCtrl::Paste()
1974 if ( m_windowStyle
& wxTE_PASSWORD
)
1979 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1982 WindowRef window
= GetMacRootWindow() ;
1985 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1988 wxMacDrawingHelper
help( win
) ;
1989 // the mac control manager always assumes to have the origin at 0,0
1990 SetOrigin( 0 , 0 ) ;
1992 bool hasTabBehind
= false ;
1993 wxWindow
* parent
= GetParent() ;
1996 if( parent
->MacGetWindowData() )
1998 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
2002 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
2004 if ( ((wxControl
*)parent
)->GetMacControl() )
2005 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
2009 parent
= parent
->GetParent() ;
2012 UMADrawControl( m_macControl
) ;
2013 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
2019 mUPDoEditCommand( m_macControl
, kmUPPaste
) ;
2024 bool wxTextCtrl::CanCopy() const
2026 // Can copy if there's a selection
2028 GetSelection(& from
, & to
);
2029 return (from
!= to
);
2032 bool wxTextCtrl::CanCut() const
2034 // Can cut if there's a selection
2036 GetSelection(& from
, & to
);
2037 return (from
!= to
);
2040 bool wxTextCtrl::CanPaste() const
2047 OSStatus err
= noErr
;
2050 err
= GetCurrentScrap( &scrapRef
);
2051 if ( err
!= noTypeErr
&& err
!= memFullErr
)
2053 ScrapFlavorFlags flavorFlags
;
2056 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
2058 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
2067 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
2075 void wxTextCtrl::SetEditable(bool editable
)
2078 UMAActivateControl( m_macControl
) ;
2080 UMADeactivateControl( m_macControl
) ;
2083 void wxTextCtrl::SetInsertionPoint(long pos
)
2085 SetSelection( pos
, pos
) ;
2088 void wxTextCtrl::SetInsertionPointEnd()
2090 long pos
= GetLastPosition();
2091 SetInsertionPoint(pos
);
2094 long wxTextCtrl::GetInsertionPoint() const
2097 GetSelection( &begin
, &end
) ;
2101 long wxTextCtrl::GetLastPosition() const
2103 if ( m_windowStyle
& wxTE_PASSWORD
)
2106 ControlEditTextSelectionRec selection
;
2110 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2112 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
2113 return (**teH
).teLength
;
2117 STPTextPaneVars
** tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2119 int actualsize
= 0 ;
2121 OSErr err
= TXNGetDataEncoded( (**tpvars
).fTXNRec
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
2129 actualsize
= GetHandleSize( theText
) ;
2130 DisposeHandle( theText
) ;
2136 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
2138 if ( m_windowStyle
& wxTE_PASSWORD
)
2143 ControlEditTextSelectionRec selection
;
2145 selection
.selStart
= from
;
2146 selection
.selEnd
= to
;
2147 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2148 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2149 TESetSelect( from
, to
, teH
) ;
2151 TEInsert( value
, value
.Length() , teH
) ;
2160 void wxTextCtrl::Remove(long from
, long to
)
2162 if ( m_windowStyle
& wxTE_PASSWORD
)
2167 ControlEditTextSelectionRec selection
;
2169 selection
.selStart
= from
;
2170 selection
.selEnd
= to
;
2171 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2172 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2182 void wxTextCtrl::SetSelection(long from
, long to
)
2184 if ( m_windowStyle
& wxTE_PASSWORD
)
2186 ControlEditTextSelectionRec selection
;
2190 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2192 selection
.selStart
= from
;
2193 selection
.selEnd
= to
;
2195 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2196 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
2200 STPTextPaneVars
**tpvars
;
2201 /* set up our locals */
2202 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2203 /* and our drawing environment as the operation
2204 may force a redraw in the text area. */
2205 SetPort((**tpvars
).fDrawingEnvironment
);
2206 /* change the selection */
2207 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
2211 bool wxTextCtrl::LoadFile(const wxString
& file
)
2213 if ( wxTextCtrlBase::LoadFile(file
) )
2221 void wxTextCtrl::WriteText(const wxString
& text
)
2224 if( wxApp::s_macDefaultEncodingIsPC
)
2225 value
= wxMacMakeMacStringFromPC( text
) ;
2228 if ( m_windowStyle
& wxTE_PASSWORD
)
2233 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2234 TEInsert( value
, value
.Length() , teH
) ;
2238 STPTextPaneVars
**tpvars
;
2240 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2241 /* set the text in the record */
2242 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
2243 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
2248 void wxTextCtrl::AppendText(const wxString
& text
)
2250 SetInsertionPointEnd();
2254 void wxTextCtrl::Clear()
2256 if ( m_windowStyle
& wxTE_PASSWORD
)
2259 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
2263 mUPDoEditCommand( m_macControl
, kmUPClear
) ;
2268 bool wxTextCtrl::IsModified() const
2273 bool wxTextCtrl::IsEditable() const
2278 bool wxTextCtrl::AcceptsFocus() const
2280 // we don't want focus if we can't be edited
2281 return IsEditable() && wxControl::AcceptsFocus();
2284 wxSize
wxTextCtrl::DoGetBestSize() const
2289 if ( UMAHasAppearance() )
2293 hText
+= 2 * m_macHorizontalBorder
;
2296 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
2298 int wText = DEFAULT_ITEM_WIDTH;
2300 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
2302 return wxSize(wText, hText);
2304 if ( m_windowStyle
& wxTE_MULTILINE
)
2306 hText
*= wxMin(GetNumberOfLines(), 5);
2308 //else: for single line control everything is ok
2309 return wxSize(wText
, hText
);
2312 // ----------------------------------------------------------------------------
2314 // ----------------------------------------------------------------------------
2316 void wxTextCtrl::Undo()
2323 void wxTextCtrl::Redo()
2330 bool wxTextCtrl::CanUndo() const
2335 bool wxTextCtrl::CanRedo() const
2340 // Makes 'unmodified'
2341 void wxTextCtrl::DiscardEdits()
2346 int wxTextCtrl::GetNumberOfLines() const
2348 // TODO change this if possible to reflect real lines
2349 wxString content
= GetValue() ;
2352 for (int i
= 0; i
< content
.Length() ; i
++)
2354 if (content
[i
] == '\r') count
++;
2360 long wxTextCtrl::XYToPosition(long x
, long y
) const
2366 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
2371 void wxTextCtrl::ShowPosition(long pos
)
2376 int wxTextCtrl::GetLineLength(long lineNo
) const
2378 // TODO change this if possible to reflect real lines
2379 wxString content
= GetValue() ;
2383 for (int i
= 0; i
< content
.Length() ; i
++)
2385 if (count
== lineNo
)
2387 // Count chars in line then
2389 for (int j
= i
; j
< content
.Length(); j
++)
2392 if (content
[j
] == '\r') return count
;
2397 if (content
[i
] == '\r') count
++;
2402 wxString
wxTextCtrl::GetLineText(long lineNo
) const
2404 // TODO change this if possible to reflect real lines
2405 wxString content
= GetValue() ;
2409 for (int i
= 0; i
< content
.Length() ; i
++)
2411 if (count
== lineNo
)
2413 // Add chars in line then
2416 for (int j
= i
; j
< content
.Length(); j
++)
2418 if (content
[j
] == '\r')
2426 if (content
[i
] == '\r') count
++;
2428 return wxString("");
2435 void wxTextCtrl::Command(wxCommandEvent
& event
)
2437 SetValue (event
.GetString());
2438 ProcessCommand (event
);
2441 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
2443 // By default, load the first file into the text window.
2444 if (event
.GetNumberOfFiles() > 0)
2446 LoadFile(event
.GetFiles()[0]);
2450 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
2452 switch ( event
.KeyCode() )
2455 if (m_windowStyle
& wxPROCESS_ENTER
)
2457 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
2458 event
.SetEventObject( this );
2459 if ( GetEventHandler()->ProcessEvent(event
) )
2462 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
2464 wxWindow
*parent
= GetParent();
2465 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
2466 parent
= parent
->GetParent() ;
2468 if ( parent
&& parent
->GetDefaultItem() )
2470 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
2472 if ( def
&& def
->IsEnabled() )
2474 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
2475 event
.SetEventObject(def
);
2476 def
->Command(event
);
2481 //else: multiline controls need Enter for themselves
2486 // always produce navigation event - even if we process TAB
2487 // ourselves the fact that we got here means that the user code
2488 // decided to skip processing of this TAB - probably to let it
2489 // do its default job.
2491 wxNavigationKeyEvent eventNav
;
2492 eventNav
.SetDirection(!event
.ShiftDown());
2493 eventNav
.SetWindowChange(event
.ControlDown());
2494 eventNav
.SetEventObject(this);
2496 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
2504 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
2507 keychar
= short(ev
->message
& charCodeMask
);
2508 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
2509 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
2510 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
|| event
.KeyCode() == WXK_DELETE
|| event
.KeyCode() == WXK_BACK
)
2512 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
2513 event
.SetString( GetValue() ) ;
2514 event
.SetEventObject( this );
2515 GetEventHandler()->ProcessEvent(event
);
2520 // ----------------------------------------------------------------------------
2521 // standard handlers for standard edit menu events
2522 // ----------------------------------------------------------------------------
2524 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
2529 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
2534 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
2539 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
2544 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
2549 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2551 event
.Enable( CanCut() );
2554 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2556 event
.Enable( CanCopy() );
2559 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2561 event
.Enable( CanPaste() );
2564 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2566 event
.Enable( CanUndo() );
2569 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2571 event
.Enable( CanRedo() );