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
) ;
230 err
= ClearCurrentScrap( );
239 void wxTextCtrl::Cut()
246 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
250 err
= ClearCurrentScrap( );
256 // MacInvalidateControl() ;
260 void wxTextCtrl::Paste()
267 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
270 WindowRef window
= GetMacRootWindow() ;
273 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
276 wxMacDrawingHelper
help( win
) ;
277 // the mac control manager always assumes to have the origin at 0,0
280 bool hasTabBehind
= false ;
281 wxWindow
* parent
= GetParent() ;
284 if( parent
->MacGetWindowData() )
286 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
290 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
292 if ( ((wxControl
*)parent
)->GetMacControl() )
293 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
297 parent
= parent
->GetParent() ;
300 UMADrawControl( m_macControl
) ;
301 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
307 bool wxTextCtrl::CanCopy() const
309 // Can copy if there's a selection
311 GetSelection(& from
, & to
);
315 bool wxTextCtrl::CanCut() const
317 // Can cut if there's a selection
319 GetSelection(& from
, & to
);
323 bool wxTextCtrl::CanPaste() const
330 OSStatus err
= noErr
;
333 err
= GetCurrentScrap( &scrapRef
);
334 if ( err
!= noTypeErr
&& err
!= memFullErr
)
336 ScrapFlavorFlags flavorFlags
;
339 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
341 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
350 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
358 void wxTextCtrl::SetEditable(bool editable
)
361 UMAActivateControl( m_macControl
) ;
363 UMADeactivateControl( m_macControl
) ;
366 void wxTextCtrl::SetInsertionPoint(long pos
)
368 SetSelection( pos
, pos
) ;
371 void wxTextCtrl::SetInsertionPointEnd()
373 long pos
= GetLastPosition();
374 SetInsertionPoint(pos
);
377 long wxTextCtrl::GetInsertionPoint() const
379 ControlEditTextSelectionRec selection
;
383 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
384 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
385 return (**teH
).selStart
;
388 long wxTextCtrl::GetLastPosition() const
390 ControlEditTextSelectionRec selection
;
394 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
396 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
397 return (**teH
).teLength
;
400 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
405 ControlEditTextSelectionRec selection
;
407 selection
.selStart
= from
;
408 selection
.selEnd
= to
;
409 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
410 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
411 TESetSelect( from
, to
, teH
) ;
413 TEInsert( value
, value
.Length() , teH
) ;
417 void wxTextCtrl::Remove(long from
, long to
)
422 ControlEditTextSelectionRec selection
;
424 selection
.selStart
= from
;
425 selection
.selEnd
= to
;
426 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
427 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
432 void wxTextCtrl::SetSelection(long from
, long to
)
434 ControlEditTextSelectionRec selection
;
438 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
440 selection
.selStart
= from
;
441 selection
.selEnd
= to
;
443 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
444 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
447 bool wxTextCtrl::LoadFile(const wxString
& file
)
449 if ( wxTextCtrlBase::LoadFile(file
) )
457 void wxTextCtrl::WriteText(const wxString
& text
)
462 memcpy( wxBuffer
, text
, text
.Length() ) ;
463 wxBuffer
[text
.Length() ] = 0 ;
464 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
466 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
468 TEInsert( wxBuffer
, strlen( wxBuffer
) , teH
) ;
472 void wxTextCtrl::AppendText(const wxString
& text
)
474 SetInsertionPointEnd();
478 void wxTextCtrl::Clear()
480 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
484 bool wxTextCtrl::IsModified() const
489 bool wxTextCtrl::IsEditable() const
494 bool wxTextCtrl::AcceptsFocus() const
496 // we don't want focus if we can't be edited
497 return IsEditable() && wxControl::AcceptsFocus();
500 wxSize
wxTextCtrl::DoGetBestSize() const
505 if ( UMAHasAppearance() )
509 hText
+= 2 * m_macHorizontalBorder
;
512 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
514 int wText = DEFAULT_ITEM_WIDTH;
516 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
518 return wxSize(wText, hText);
520 if ( m_windowStyle
& wxTE_MULTILINE
)
522 hText
*= wxMin(GetNumberOfLines(), 5);
524 //else: for single line control everything is ok
525 return wxSize(wText
, hText
);
528 // ----------------------------------------------------------------------------
530 // ----------------------------------------------------------------------------
532 void wxTextCtrl::Undo()
539 void wxTextCtrl::Redo()
546 bool wxTextCtrl::CanUndo() const
551 bool wxTextCtrl::CanRedo() const
556 // Makes 'unmodified'
557 void wxTextCtrl::DiscardEdits()
562 int wxTextCtrl::GetNumberOfLines() const
565 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
568 for (int i
= 0; i
< actualsize
; i
++)
570 if (wxBuffer
[i
] == '\r') count
++;
576 long wxTextCtrl::XYToPosition(long x
, long y
) const
582 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
587 void wxTextCtrl::ShowPosition(long pos
)
592 int wxTextCtrl::GetLineLength(long lineNo
) const
595 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
599 for (int i
= 0; i
< actualsize
; i
++)
603 // Count chars in line then
605 for (int j
= i
; j
< actualsize
; j
++)
608 if (wxBuffer
[j
] == '\r') return count
;
613 if (wxBuffer
[i
] == '\r') count
++;
619 wxString
wxTextCtrl::GetLineText(long lineNo
) const
622 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
626 for (int i
= 0; i
< actualsize
; i
++)
630 // Add chars in line then
633 for (int j
= i
; j
< actualsize
; j
++)
635 if (wxBuffer
[j
] == '\r')
643 if (wxBuffer
[i
] == '\r') count
++;
653 void wxTextCtrl::Command(wxCommandEvent
& event
)
655 SetValue (event
.GetString());
656 ProcessCommand (event
);
659 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
661 // By default, load the first file into the text window.
662 if (event
.GetNumberOfFiles() > 0)
664 LoadFile(event
.GetFiles()[0]);
668 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
670 switch ( event
.KeyCode() )
673 if (m_windowStyle
& wxPROCESS_ENTER
)
675 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
676 event
.SetEventObject( this );
677 if ( GetEventHandler()->ProcessEvent(event
) )
680 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
682 wxWindow
*parent
= GetParent();
683 wxPanel
*panel
= wxDynamicCast(parent
, wxPanel
);
684 while ( parent
!= NULL
&& panel
== NULL
)
686 parent
= parent
->GetParent() ;
687 panel
= wxDynamicCast(parent
, wxPanel
);
689 if ( panel
&& panel
->GetDefaultItem() )
691 wxButton
*def
= wxDynamicCast(panel
->GetDefaultItem(),
693 if ( def
&& def
->IsEnabled() )
695 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
696 event
.SetEventObject(def
);
702 //else: multiline controls need Enter for themselves
707 // always produce navigation event - even if we process TAB
708 // ourselves the fact that we got here means that the user code
709 // decided to skip processing of this TAB - probably to let it
710 // do its default job.
712 wxNavigationKeyEvent eventNav
;
713 eventNav
.SetDirection(!event
.ShiftDown());
714 eventNav
.SetWindowChange(event
.ControlDown());
715 eventNav
.SetEventObject(this);
717 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
725 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
728 keychar
= short(ev
->message
& charCodeMask
);
729 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
730 ::HandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
731 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
|| event
.KeyCode() == WXK_DELETE
|| event
.KeyCode() == WXK_BACK
)
733 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
734 event
.SetString( GetValue() ) ;
735 event
.SetEventObject( this );
736 GetEventHandler()->ProcessEvent(event
);
741 // ----------------------------------------------------------------------------
742 // standard handlers for standard edit menu events
743 // ----------------------------------------------------------------------------
745 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
750 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
755 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
760 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
765 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
770 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
772 event
.Enable( CanCut() );
775 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
777 event
.Enable( CanCopy() );
780 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
782 event
.Enable( CanPaste() );
785 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
787 event
.Enable( CanUndo() );
790 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
792 event
.Enable( CanRedo() );
798 #define GetControlOwner( control ) (**control).contrlOwner
801 //todo add access to global event record
805 static EventRecord
*GetCurrentEventRecord()
810 // CS:We will replace the TextEdit by using the MultiLanguageTextEngine based on the following code written by apple
816 mUPControl implementation.
819 © Copyright 2000 Apple Computer, Inc. All rights reserved.
822 IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
823 ("Apple") in consideration of your agreement to the following terms, and your
824 use, installation, modification or redistribution of this Apple software
825 constitutes acceptance of these terms. If you do not agree with these terms,
826 please do not use, install, modify or redistribute this Apple software.
828 In consideration of your agreement to abide by the following terms, and subject
829 to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
830 copyrights in this original Apple software (the "Apple Software"), to use,
831 reproduce, modify and redistribute the Apple Software, with or without
832 modifications, in source and/or binary forms; provided that if you redistribute
833 the Apple Software in its entirety and without modifications, you must retain
834 this notice and the following text and disclaimers in all such redistributions of
835 the Apple Software. Neither the name, trademarks, service marks or logos of
836 Apple Computer, Inc. may be used to endorse or promote products derived from the
837 Apple Software without specific prior written permission from Apple. Except as
838 expressly stated in this notice, no other rights or licenses, express or implied,
839 are granted by Apple herein, including but not limited to any patent rights that
840 may be infringed by your derivative works or by other works in which the Apple
841 Software may be incorporated.
843 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
844 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
845 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
846 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
847 COMBINATION WITH YOUR PRODUCTS.
849 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
850 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
851 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
852 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
853 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
854 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
855 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
857 Change History (most recent first):
858 Fri, Jan 28, 2000 -- created
861 #include "MacTextEditor.h"
865 /* kmUPTextPart is the part code we return to indicate the user has clicked
866 in the text area of our control */
867 #define kmUPTextPart 1
869 /* kmUPScrollPart is the part code we return to indicate the user has clicked
870 in the scroll bar part of the control. */
871 #define kmUPScrollPart 2
874 /* routines for using existing user pane controls.
875 These routines are useful for cases where you would like to use an
876 existing user pane control in, say, a dialog window as a scrolling
879 /* mUPOpenControl initializes a user pane control so it will be drawn
880 and will behave as a scrolling text edit field inside of a window.
881 This routine performs all of the initialization steps necessary,
882 except it does not create the user pane control itself. theControl
883 should refer to a user pane control that you have either created
884 yourself or extracted from a dialog's control heirarchy using
885 the GetDialogItemAsControl routine. */
886 OSStatus
mUPOpenControl(ControlHandle theControl
);
888 /* mUPCloseControl deallocates all of the structures allocated
889 by mUPOpenControl. */
890 OSStatus
mUPCloseControl(ControlHandle theControl
);
894 /* routines for creating new scrolling text user pane controls.
895 These routines allow you to create new scrolling text
896 user pane controls. */
898 /* mUPCreateControl creates a new user pane control and then it passes it
899 to mUPOpenControl to initialize it as a scrolling text user pane control. */
900 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
);
902 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
903 OSStatus
mUPDisposeControl(ControlHandle theControl
);
906 /* Utility Routines */
908 /* mUPSetText replaces the contents of the selection with the unicode
909 text described by the text and count parameters:.
910 text = pointer to unicode text buffer
911 count = number of bytes in the buffer. */
912 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
);
914 /* mUPGetText returns the current text data being displayed inside of
915 the mUPControl. When noErr is returned, *theText contain a new
916 handle containing all of the Unicode text copied from the current
917 selection. It is the caller's responsibiliby to dispose of this handle. */
918 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
);
921 /* mUPSetSelection sets the text selection and autoscrolls the text view
922 so either the cursor or the selction is in the view. */
923 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
);
927 /* IsmUPControl returns true if theControl is not NULL
928 and theControl refers to a mUP Control. */
929 Boolean
IsmUPControl(ControlHandle theControl
);
933 /* Edit commands for mUP Controls. */
942 /* mUPDoEditCommand performs the editing command specified
943 in the editCommand parameter. The mUPControl's text
944 and scroll bar are redrawn and updated as necessary. */
945 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
);
950 /* mUPGetContents returns the entire contents of the control including the text
951 and the formatting information. */
952 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
);
953 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
954 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
);
960 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
961 routine. In our focus switching routine this part code is understood
962 as meaning 'the user has clicked in the control and we need to switch
963 the current focus to ourselves before we can continue'. */
964 #define kUserClickedToFocusPart 100
967 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
968 slow the speed of 'auto scrolling' inside of our clickloop routine.
969 This value prevents the text from wizzzzzing by while the mouse
970 is being held down inside of the text area. */
971 #define kmUPClickScrollDelayTicks 3
974 /* STPTextPaneVars is a structure used for storing the the mUP Control's
975 internal variables and state information. A handle to this record is
976 stored in the pane control's reference value field using the
977 SetControlReference routine. */
980 /* OS records referenced */
981 TXNObject fTXNRec
; /* the txn record */
982 TXNFrameID fTXNFrame
; /* the txn frame ID */
983 ControlHandle fUserPaneRec
; /* handle to the user pane control */
984 WindowPtr fOwner
; /* window containing control */
985 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
987 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
988 Boolean fIsActive
; /* true while the control is drawn in the active state */
989 Boolean fTEActive
; /* reflects the activation state of the text edit record */
990 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
991 /* calculated locations */
992 Rect fRTextArea
; /* area where the text is drawn */
993 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
994 Rect fRTextOutline
; /* rectangle used to draw the border */
995 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
996 /* our focus advance override routine */
997 EventHandlerUPP handlerUPP
;
998 EventHandlerRef handlerRef
;
1004 /* Univerals Procedure Pointer variables used by the
1005 mUP Control. These variables are set up
1006 the first time that mUPOpenControl is called. */
1007 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
1008 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
1009 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
1010 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
1011 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
1012 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
1013 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
1015 /* events handled by our focus advance override routine */
1017 static const EventTypeSpec gMLTEEvents
[] = { { kEventClassTextInput
, kEventUnicodeForKeyEvent
} };
1018 #define kMLTEEventCount (sizeof( gMLTEEvents ) / sizeof( EventTypeSpec ))
1022 /* TPActivatePaneText activates or deactivates the text edit record
1023 according to the value of setActive. The primary purpose of this
1024 routine is to ensure each call is only made once. */
1025 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
1026 STPTextPaneVars
*varsp
;
1028 if (varsp
->fTEActive
!= setActive
) {
1030 varsp
->fTEActive
= setActive
;
1032 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
1034 if (varsp
->fInFocus
)
1035 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
1040 /* TPFocusPaneText set the focus state for the text record. */
1041 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
1042 STPTextPaneVars
*varsp
;
1044 if (varsp
->fInFocus
!= setFocus
) {
1045 varsp
->fInFocus
= setFocus
;
1046 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
1051 /* TPPaneDrawProc is called to redraw the control and for update events
1052 referring to the control. This routine erases the text area's background,
1053 and redraws the text. This routine assumes the scroll bar has been
1054 redrawn by a call to DrawControls. */
1055 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
1056 STPTextPaneVars
**tpvars
, *varsp
;
1059 /* set up our globals */
1060 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1061 if (tpvars
!= NULL
) {
1062 state
= HGetState((Handle
) tpvars
);
1063 HLock((Handle
) tpvars
);
1066 /* save the drawing state */
1067 SetPort((**tpvars
).fDrawingEnvironment
);
1068 /* verify our boundary */
1069 GetControlBounds(theControl
, &bounds
);
1070 if ( ! EqualRect(&bounds
, &varsp
->fRTextArea
) ) {
1071 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1072 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1073 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1074 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
1075 TXNSetFrameBounds( varsp
->fTXNRec
, bounds
.top
, bounds
.left
, bounds
.bottom
, bounds
.right
, varsp
->fTXNFrame
);
1078 /* update the text region */
1079 EraseRgn(varsp
->fTextBackgroundRgn
);
1080 TXNDraw(varsp
->fTXNRec
, NULL
);
1081 /* restore the drawing environment */
1082 /* draw the text frame and focus frame (if necessary) */
1083 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1084 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
1085 /* release our globals */
1086 HSetState((Handle
) tpvars
, state
);
1091 /* TPPaneHitTestProc is called when the control manager would
1092 like to determine what part of the control the mouse resides over.
1093 We also call this routine from our tracking proc to determine how
1094 to handle mouse clicks. */
1095 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
1096 STPTextPaneVars
**tpvars
;
1097 ControlPartCode result
;
1099 /* set up our locals and lock down our globals*/
1101 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1102 if (tpvars
!= NULL
) {
1103 state
= HGetState((Handle
) tpvars
);
1104 HLock((Handle
) tpvars
);
1105 /* find the region where we clicked */
1106 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
1107 result
= kmUPTextPart
;
1109 /* release oure globals */
1110 HSetState((Handle
) tpvars
, state
);
1119 /* TPPaneTrackingProc is called when the mouse is being held down
1120 over our control. This routine handles clicks in the text area
1121 and in the scroll bar. */
1122 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
1123 STPTextPaneVars
**tpvars
, *varsp
;
1125 ControlPartCode partCodeResult
;
1126 /* make sure we have some variables... */
1128 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1129 if (tpvars
!= NULL
) {
1131 state
= HGetState((Handle
) tpvars
);
1132 HLock((Handle
) tpvars
);
1134 /* we don't do any of these functions unless we're in focus */
1135 if ( ! varsp
->fInFocus
) {
1137 owner
= GetControlOwner(theControl
);
1138 ClearKeyboardFocus(owner
);
1139 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
1141 /* find the location for the click */
1142 switch (TPPaneHitTestProc(theControl
, startPt
)) {
1144 /* handle clicks in the text part */
1146 { SetPort((**tpvars
).fDrawingEnvironment
);
1147 TXNClick( varsp
->fTXNRec
, GetCurrentEventRecord());
1153 HSetState((Handle
) tpvars
, state
);
1155 return partCodeResult
;
1159 /* TPPaneIdleProc is our user pane idle routine. When our text field
1160 is active and in focus, we use this routine to set the cursor. */
1161 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
1162 STPTextPaneVars
**tpvars
, *varsp
;
1164 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1165 if (tpvars
!= NULL
) {
1166 /* if we're not active, then we have nothing to say about the cursor */
1167 if ((**tpvars
).fIsActive
) {
1171 /* lock down the globals */
1172 state
= HGetState((Handle
) tpvars
);
1173 HLock((Handle
) tpvars
);
1175 /* get the current mouse coordinates (in our window) */
1177 SetPort(GetWindowPort(GetControlOwner(theControl
)));
1179 SetPort((GrafPtr
) GetWindowPort(GetControlOwner(theControl
)));
1182 /* there's a 'focus thing' and an 'unfocused thing' */
1183 if (varsp
->fInFocus
) {
1184 /* flash the cursor */
1185 SetPort((**tpvars
).fDrawingEnvironment
);
1186 TXNIdle(varsp
->fTXNRec
);
1187 /* set the cursor */
1188 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
1190 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
1191 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
1193 } else SetThemeCursor(kThemeArrowCursor
);
1195 /* if it's in our bounds, set the cursor */
1196 GetControlBounds(theControl
, &bounds
);
1197 if (PtInRect(mousep
, &bounds
))
1198 SetThemeCursor(kThemeArrowCursor
);
1201 HSetState((Handle
) tpvars
, state
);
1207 /* TPPaneKeyDownProc is called whenever a keydown event is directed
1208 at our control. Here, we direct the keydown event to the text
1209 edit record and redraw the scroll bar and text field as appropriate. */
1210 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
1211 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
1212 STPTextPaneVars
**tpvars
;
1213 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1214 if (tpvars
!= NULL
) {
1215 if ((**tpvars
).fInFocus
) {
1216 /* turn autoscrolling on and send the key event to text edit */
1217 SetPort((**tpvars
).fDrawingEnvironment
);
1218 TXNKeyDown( (**tpvars
).fTXNRec
, GetCurrentEventRecord());
1221 return kControlEntireControl
;
1225 /* TPPaneActivateProc is called when the window containing
1226 the user pane control receives activate events. Here, we redraw
1227 the control and it's text as necessary for the activation state. */
1228 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
1230 STPTextPaneVars
**tpvars
, *varsp
;
1233 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1234 if (tpvars
!= NULL
) {
1235 state
= HGetState((Handle
) tpvars
);
1236 HLock((Handle
) tpvars
);
1238 /* de/activate the text edit record */
1239 SetPort((**tpvars
).fDrawingEnvironment
);
1240 GetControlBounds(theControl
, &bounds
);
1241 varsp
->fIsActive
= activating
;
1242 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1243 /* redraw the frame */
1244 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1245 if (varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
1246 HSetState((Handle
) tpvars
, state
);
1251 /* TPPaneFocusProc is called when every the focus changes to or
1252 from our control. Herein, switch the focus appropriately
1253 according to the parameters and redraw the control as
1255 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
1256 ControlPartCode focusResult
;
1257 STPTextPaneVars
**tpvars
, *varsp
;
1260 focusResult
= kControlFocusNoPart
;
1261 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1262 if (tpvars
!= NULL
) {
1263 state
= HGetState((Handle
) tpvars
);
1264 HLock((Handle
) tpvars
);
1266 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
1267 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
1268 and kControlFocusNextPart will be received. When the user clicks in our field
1269 and it is not the current focus, then the constant kUserClickedToFocusPart will
1270 be received. The constant kControlFocusNoPart will be received when our control
1271 is the current focus and the user clicks in another control. In your focus routine,
1272 you should respond to these codes as follows:
1274 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
1275 the control and the focus rectangle as necessary.
1277 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
1278 depending on its current state. redraw the control and the focus rectangle
1279 as appropriate for the new focus state. If the focus state is 'off', return the constant
1280 kControlFocusNoPart, otherwise return a non-zero part code.
1281 kUserClickedToFocusPart - is a constant defined for this example. You should
1282 define your own value for handling click-to-focus type events. */
1283 /* save the drawing state */
1284 SetPort((**tpvars
).fDrawingEnvironment
);
1285 /* calculate the next highlight state */
1288 case kControlFocusNoPart
:
1289 TPFocusPaneText(tpvars
, false);
1290 focusResult
= kControlFocusNoPart
;
1292 case kUserClickedToFocusPart
:
1293 TPFocusPaneText(tpvars
, true);
1296 case kControlFocusPrevPart
:
1297 case kControlFocusNextPart
:
1298 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
1299 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
1302 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1303 /* redraw the text fram and focus rectangle to indicate the
1305 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1306 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
1308 HSetState((Handle
) tpvars
, state
);
1323 //This our carbon event handler for unicode key downs
1325 static pascal OSStatus
FocusAdvanceOverride(EventHandlerCallRef myHandler
, EventRef event
, void* userData
) {
1327 STPTextPaneVars
**tpvars
;
1329 unsigned short mUnicodeText
;
1330 ByteCount charCounts
=0;
1331 /* get our window pointer */
1332 tpvars
= (STPTextPaneVars
**) userData
;
1333 window
= (**tpvars
).fOwner
;
1334 //find out how many bytes are needed
1335 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1336 typeUnicodeText
, NULL
, 0, &charCounts
, NULL
);
1337 if (err
!= noErr
) goto bail
;
1338 /* we're only looking at single characters */
1339 if (charCounts
!= 2) { err
= eventNotHandledErr
; goto bail
; }
1340 /* get the character */
1341 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1342 typeUnicodeText
, NULL
, sizeof(mUnicodeText
),
1343 &charCounts
, (char*) &mUnicodeText
);
1344 if (err
!= noErr
) goto bail
;
1345 /* if it's not the tab key, forget it... */
1346 if ((mUnicodeText
!= '\t')) { err
= eventNotHandledErr
; goto bail
; }
1347 /* advance the keyboard focus */
1348 AdvanceKeyboardFocus(window
);
1349 /* noErr lets the CEM know we handled the event */
1352 return eventNotHandledErr
;
1357 /* mUPOpenControl initializes a user pane control so it will be drawn
1358 and will behave as a scrolling text edit field inside of a window.
1359 This routine performs all of the initialization steps necessary,
1360 except it does not create the user pane control itself. theControl
1361 should refer to a user pane control that you have either created
1362 yourself or extracted from a dialog's control heirarchy using
1363 the GetDialogItemAsControl routine. */
1364 OSStatus
mUPOpenControl(ControlHandle theControl
) {
1366 WindowPtr theWindow
;
1367 STPTextPaneVars
**tpvars
, *varsp
;
1369 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
1370 TXNBackground tback
;
1372 /* set up our globals */
1373 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
1374 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
1375 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
1376 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
1377 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
1378 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
1379 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
1381 /* allocate our private storage */
1382 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
1383 SetControlReference(theControl
, (long) tpvars
);
1384 HLock((Handle
) tpvars
);
1386 /* set the initial settings for our private data */
1387 varsp
->fInFocus
= false;
1388 varsp
->fIsActive
= true;
1389 varsp
->fTEActive
= false;
1390 varsp
->fUserPaneRec
= theControl
;
1391 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
1393 varsp
->fDrawingEnvironment
= GetWindowPort(varsp
->fOwner
);
1395 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(varsp
->fOwner
);
1397 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
1398 /* set up the user pane procedures */
1399 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
1400 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
1401 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
1402 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
1403 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
1404 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
1405 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
1406 /* calculate the rectangles used by the control */
1407 GetControlBounds(theControl
, &bounds
);
1408 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1409 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1410 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1411 /* calculate the background region for the text. In this case, it's kindof
1412 and irregular region because we're setting the scroll bar a little ways inside
1413 of the text area. */
1414 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
1416 /* set up the drawing environment */
1417 SetPort(varsp
->fDrawingEnvironment
);
1419 /* create the new edit field */
1420 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
1421 kTXNWantVScrollBarMask
| kTXNAlwaysWrapAtViewEdgeMask
,
1422 kTXNTextEditStyleFrameType
,
1424 kTXNSystemDefaultEncoding
,
1425 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
1427 /* set the field's background */
1428 tback
.bgType
= kTXNBackgroundTypeRGB
;
1429 tback
.bg
.color
= rgbWhite
;
1430 TXNSetBackground( varsp
->fTXNRec
, &tback
);
1432 /* install our focus advance override routine */
1434 varsp
->handlerUPP
= NewEventHandlerUPP(FocusAdvanceOverride
);
1435 err
= InstallWindowEventHandler( varsp
->fOwner
, varsp
->handlerUPP
,
1436 kMLTEEventCount
, gMLTEEvents
, tpvars
, &varsp
->handlerRef
);
1439 /* unlock our storage */
1440 HUnlock((Handle
) tpvars
);
1441 /* perform final activations and setup for our text field. Here,
1442 we assume that the window is going to be the 'active' window. */
1443 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1450 /* mUPCloseControl deallocates all of the structures allocated
1451 by mUPOpenControl. */
1452 OSStatus
mUPCloseControl(ControlHandle theControl
) {
1453 STPTextPaneVars
**tpvars
;
1455 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1456 /* release our sub records */
1457 TXNDeleteObject((**tpvars
).fTXNRec
);
1458 /* remove our focus advance override */
1459 RemoveEventHandler((**tpvars
).handlerRef
);
1460 DisposeEventHandlerUPP((**tpvars
).handlerUPP
);
1461 /* delete our private storage */
1462 DisposeHandle((Handle
) tpvars
);
1463 /* zero the control reference */
1464 SetControlReference(theControl
, 0);
1471 /* mUPSetText replaces the contents of the selection with the unicode
1472 text described by the text and count parameters:.
1473 text = pointer to unicode text buffer
1474 count = number of bytes in the buffer. */
1475 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
) {
1476 STPTextPaneVars
**tpvars
;
1478 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1479 /* set the text in the record */
1480 return TXNSetData( (**tpvars
).fTXNRec
, kTXNUnicodeTextData
, text
, count
,
1481 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1487 /* mUPSetSelection sets the text selection and autoscrolls the text view
1488 so either the cursor or the selction is in the view. */
1489 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
) {
1490 STPTextPaneVars
**tpvars
;
1491 /* set up our locals */
1492 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1493 /* and our drawing environment as the operation
1494 may force a redraw in the text area. */
1495 SetPort((**tpvars
).fDrawingEnvironment
);
1496 /* change the selection */
1497 TXNSetSelection( (**tpvars
).fTXNRec
, selStart
, selEnd
);
1504 /* mUPGetText returns the current text data being displayed inside of
1505 the mUPControl. When noErr is returned, *theText contain a new
1506 handle containing all of the Unicode text copied from the current
1507 selection. It is the caller's responsibiliby to dispose of this handle. */
1508 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
) {
1509 STPTextPaneVars
**tpvars
;
1512 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1513 /* extract the text from the record */
1514 err
= TXNGetData( (**tpvars
).fTXNRec
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, theText
);
1521 /* mUPCreateControl creates a new user pane control and then it passes it
1522 to mUPOpenControl to initialize it as a scrolling text user pane control. */
1523 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
) {
1525 /* the following feature set can be specified in CNTL resources by using
1526 the value 1214. When creating a user pane control, we pass this value
1527 in the 'value' parameter. */
1528 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
1529 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
1530 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
1531 /* create the control */
1532 *theControl
= NewControl(theWindow
, bounds
, "\p", true, featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
1533 /* set up the mUP specific features and data */
1534 mUPOpenControl(*theControl
);
1540 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
1541 OSStatus
mUPDisposeControl(ControlHandle theControl
) {
1542 /* deallocate the mUP specific data */
1543 mUPCloseControl(theControl
);
1544 /* deallocate the user pane control itself */
1545 DisposeControl(theControl
);
1552 /* IsmUPControl returns true if theControl is not NULL
1553 and theControl refers to a mUP Control. */
1554 Boolean
IsmUPControl(ControlHandle theControl
) {
1556 ControlUserPaneFocusUPP localFocusProc
;
1557 /* a NULL control is not a mUP control */
1558 if (theControl
== NULL
) return false;
1559 /* check if the control is using our focus procedure */
1560 theSize
= sizeof(localFocusProc
);
1561 if (GetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
,
1562 sizeof(localFocusProc
), &localFocusProc
, &theSize
) != noErr
) return false;
1563 if (localFocusProc
!= gTPFocusProc
) return false;
1564 /* all tests passed, it's a mUP control */
1569 /* mUPDoEditCommand performs the editing command specified
1570 in the editCommand parameter. The mUPControl's text
1571 and scroll bar are redrawn and updated as necessary. */
1572 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
) {
1573 STPTextPaneVars
**tpvars
;
1574 /* set up our locals */
1575 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1576 /* and our drawing environment as the operation
1577 may force a redraw in the text area. */
1578 SetPort((**tpvars
).fDrawingEnvironment
);
1579 /* perform the editing command */
1580 switch (editCommand
) {
1582 ClearCurrentScrap();
1583 TXNCut((**tpvars
).fTXNRec
);
1584 TXNConvertToPublicScrap();
1587 ClearCurrentScrap();
1588 TXNCopy((**tpvars
).fTXNRec
);
1589 TXNConvertToPublicScrap();
1592 TXNConvertFromPublicScrap();
1593 TXNPaste((**tpvars
).fTXNRec
);
1596 TXNClear((**tpvars
).fTXNRec
);
1604 /* mUPGetContents returns the entire contents of the control including the text
1605 and the formatting information. */
1606 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
) {
1607 STPTextPaneVars
**tpvars
;
1620 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1621 if (theContents
== NULL
) return paramErr
;
1622 /* create a temporary file */
1623 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1624 if (err
!= noErr
) goto bail
;
1625 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPGetContents", &tspec
);
1626 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1627 if (err
!= noErr
) goto bail
;
1630 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1631 if (err
!= noErr
) goto bail
;
1633 err
= TXNSave( (**tpvars
).fTXNRec
, kTXNTextensionFile
, 0, kTXNSystemDefaultEncoding
, &tspec
, trefnum
, 0);
1634 if (err
!= noErr
) goto bail
;
1635 /* get the file length and set the position */
1636 err
= GetEOF(trefnum
, &bytecount
);
1637 if (err
!= noErr
) goto bail
;
1638 err
= SetFPos(trefnum
, fsFromStart
, 0);
1639 if (err
!= noErr
) goto bail
;
1640 /* copy the data fork to a handle */
1641 localdata
= NewHandle(bytecount
);
1642 if (localdata
== NULL
) { err
= memFullErr
; goto bail
; }
1644 err
= FSRead(trefnum
, &bytecount
, *localdata
);
1646 if (err
!= noErr
) goto bail
;
1648 *theContents
= localdata
;
1655 if (trefnum
!= 0) FSClose(trefnum
);
1656 if (texists
) FSpDelete(&tspec
);
1657 if (localdata
!= NULL
) DisposeHandle(localdata
);
1664 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
1665 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
) {
1666 STPTextPaneVars
**tpvars
;
1678 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1679 if (theContents
== NULL
) return paramErr
;
1680 /* create a temporary file */
1681 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1682 if (err
!= noErr
) goto bail
;
1683 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPSetContents", &tspec
);
1684 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1685 if (err
!= noErr
) goto bail
;
1688 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1689 if (err
!= noErr
) goto bail
;
1690 /* save the data to the temporary file */
1691 state
= HGetState(theContents
);
1693 bytecount
= GetHandleSize(theContents
);
1694 err
= FSWrite(trefnum
, &bytecount
, *theContents
);
1695 HSetState(theContents
, state
);
1696 if (err
!= noErr
) goto bail
;
1697 /* reset the file position */
1698 err
= SetFPos(trefnum
, fsFromStart
, 0);
1699 if (err
!= noErr
) goto bail
;
1701 err
= TXNSetDataFromFile((**tpvars
).fTXNRec
, trefnum
, kTXNTextensionFile
, bytecount
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1702 if (err
!= noErr
) goto bail
;
1709 if (trefnum
!= 0) FSClose(trefnum
);
1710 if (texists
) FSpDelete(&tspec
);
1714 #if !USE_SHARED_LIBRARY
1715 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
1717 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
1718 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
1719 EVT_CHAR(wxTextCtrl::OnChar
)
1720 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
1721 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
1722 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
1723 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
1724 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
1726 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
1727 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
1728 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
1729 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
1730 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
1735 wxTextCtrl::wxTextCtrl()
1739 const short kVerticalMargin
= 2 ;
1740 const short kHorizontalMargin
= 2 ;
1742 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1745 const wxSize
& size
, long style
,
1746 const wxValidator
& validator
,
1747 const wxString
& name
)
1749 // base initialization
1750 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
1753 wxSize mySize
= size
;
1754 if ( UMAHasAppearance() )
1756 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
1757 m_macVerticalBorder
= 5 ;
1761 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
1762 m_macVerticalBorder
= 0 ;
1769 if ( mySize
.y
== -1 )
1771 if ( UMAHasAppearance() )
1776 mySize
.y
+= 2 * m_macVerticalBorder
;
1779 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
1781 if ( m_windowStyle
& wxTE_MULTILINE
)
1783 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
1784 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
1786 m_windowStyle
|= wxTE_PROCESS_ENTER
;
1790 if ( style
& wxTE_PASSWORD
)
1792 m_macControl
= ::NewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
1793 kControlEditTextPasswordProc
, (long) this ) ;
1797 if ( mUPCreateControl(parent
->GetMacRootWindow(), &bounds
, &m_macControl
) != noErr
)
1800 MacPostControlCreate() ;
1804 if( wxApp::s_macDefaultEncodingIsPC
)
1805 value
= wxMacMakeMacStringFromPC( st
) ;
1809 if ( style
& wxTE_PASSWORD
)
1811 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1815 STPTextPaneVars
**tpvars
;
1817 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1818 /* set the text in the record */
1819 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1820 kTXNStartOffset
, kTXNEndOffset
);
1826 wxString
wxTextCtrl::GetValue() const
1829 if ( m_windowStyle
& wxTE_PASSWORD
)
1831 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
1835 STPTextPaneVars
**tpvars
;
1838 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1839 /* extract the text from the record */
1841 err
= TXNGetDataEncoded( (**tpvars
).fTXNRec
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1849 actualsize
= GetHandleSize( theText
) ;
1850 strncpy( wxBuffer
, *theText
, actualsize
) ;
1851 DisposeHandle( theText
) ;
1854 wxBuffer
[actualsize
] = 0 ;
1855 if( wxApp::s_macDefaultEncodingIsPC
)
1856 return wxMacMakePCStringFromMac( wxBuffer
) ;
1858 return wxString(wxBuffer
);
1861 void wxTextCtrl::GetSelection(long* from
, long* to
) const
1863 if ( m_windowStyle
& wxTE_PASSWORD
)
1865 ControlEditTextSelectionRec selection
;
1869 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1871 *from
= (**teH
).selStart
;
1872 *to
= (**teH
).selEnd
;
1876 STPTextPaneVars
**tpvars
;
1879 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1881 TXNGetSelection( (**tpvars
).fTXNRec
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1886 void wxTextCtrl::SetValue(const wxString
& st
)
1890 if( wxApp::s_macDefaultEncodingIsPC
)
1891 value
= wxMacMakeMacStringFromPC( st
) ;
1894 if ( m_windowStyle
& wxTE_PASSWORD
)
1896 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1900 STPTextPaneVars
**tpvars
;
1902 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1903 /* set the text in the record */
1904 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1905 kTXNStartOffset
, kTXNEndOffset
);
1907 WindowRef window
= GetMacRootWindow() ;
1910 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1913 wxMacDrawingHelper
help( win
) ;
1914 // the mac control manager always assumes to have the origin at 0,0
1915 SetOrigin( 0 , 0 ) ;
1917 bool hasTabBehind
= false ;
1918 wxWindow
* parent
= GetParent() ;
1921 if( parent
->MacGetWindowData() )
1923 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
1927 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
1929 if ( ((wxControl
*)parent
)->GetMacControl() )
1930 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
1934 parent
= parent
->GetParent() ;
1937 UMADrawControl( m_macControl
) ;
1938 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
1943 // Clipboard operations
1944 void wxTextCtrl::Copy()
1948 if ( m_windowStyle
& wxTE_PASSWORD
)
1953 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1957 err
= ClearCurrentScrap( );
1967 void wxTextCtrl::Cut()
1971 if ( m_windowStyle
& wxTE_PASSWORD
)
1976 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1980 err
= ClearCurrentScrap( );
1986 // MacInvalidateControl() ;
1991 void wxTextCtrl::Paste()
1995 if ( m_windowStyle
& wxTE_PASSWORD
)
2000 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2003 WindowRef window
= GetMacRootWindow() ;
2006 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
2009 wxMacDrawingHelper
help( win
) ;
2010 // the mac control manager always assumes to have the origin at 0,0
2011 SetOrigin( 0 , 0 ) ;
2013 bool hasTabBehind
= false ;
2014 wxWindow
* parent
= GetParent() ;
2017 if( parent
->MacGetWindowData() )
2019 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
2023 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
2025 if ( ((wxControl
*)parent
)->GetMacControl() )
2026 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
2030 parent
= parent
->GetParent() ;
2033 UMADrawControl( m_macControl
) ;
2034 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
2041 bool wxTextCtrl::CanCopy() const
2043 // Can copy if there's a selection
2045 GetSelection(& from
, & to
);
2046 return (from
!= to
);
2049 bool wxTextCtrl::CanCut() const
2051 // Can cut if there's a selection
2053 GetSelection(& from
, & to
);
2054 return (from
!= to
);
2057 bool wxTextCtrl::CanPaste() const
2064 OSStatus err
= noErr
;
2067 err
= GetCurrentScrap( &scrapRef
);
2068 if ( err
!= noTypeErr
&& err
!= memFullErr
)
2070 ScrapFlavorFlags flavorFlags
;
2073 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
2075 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
2084 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
2092 void wxTextCtrl::SetEditable(bool editable
)
2095 UMAActivateControl( m_macControl
) ;
2097 UMADeactivateControl( m_macControl
) ;
2100 void wxTextCtrl::SetInsertionPoint(long pos
)
2102 SetSelection( pos
, pos
) ;
2105 void wxTextCtrl::SetInsertionPointEnd()
2107 long pos
= GetLastPosition();
2108 SetInsertionPoint(pos
);
2111 long wxTextCtrl::GetInsertionPoint() const
2114 GetSelection( &begin
, &end
) ;
2118 long wxTextCtrl::GetLastPosition() const
2120 if ( m_windowStyle
& wxTE_PASSWORD
)
2123 ControlEditTextSelectionRec selection
;
2127 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2129 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
2130 return (**teH
).teLength
;
2134 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
2136 if ( m_windowStyle
& wxTE_PASSWORD
)
2141 ControlEditTextSelectionRec selection
;
2143 selection
.selStart
= from
;
2144 selection
.selEnd
= to
;
2145 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2146 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2147 TESetSelect( from
, to
, teH
) ;
2149 TEInsert( value
, value
.Length() , teH
) ;
2154 void wxTextCtrl::Remove(long from
, long to
)
2156 if ( m_windowStyle
& wxTE_PASSWORD
)
2161 ControlEditTextSelectionRec selection
;
2163 selection
.selStart
= from
;
2164 selection
.selEnd
= to
;
2165 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2166 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2172 void wxTextCtrl::SetSelection(long from
, long to
)
2174 if ( m_windowStyle
& wxTE_PASSWORD
)
2176 ControlEditTextSelectionRec selection
;
2180 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2182 selection
.selStart
= from
;
2183 selection
.selEnd
= to
;
2185 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2186 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
2190 STPTextPaneVars
**tpvars
;
2191 /* set up our locals */
2192 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2193 /* and our drawing environment as the operation
2194 may force a redraw in the text area. */
2195 SetPort((**tpvars
).fDrawingEnvironment
);
2196 /* change the selection */
2197 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
2201 bool wxTextCtrl::LoadFile(const wxString
& file
)
2203 if ( wxTextCtrlBase::LoadFile(file
) )
2211 void wxTextCtrl::WriteText(const wxString
& text
)
2214 if( wxApp::s_macDefaultEncodingIsPC
)
2215 value
= wxMacMakeMacStringFromPC( text
) ;
2218 if ( m_windowStyle
& wxTE_PASSWORD
)
2223 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2224 TEInsert( value
, value
.Length() , teH
) ;
2228 STPTextPaneVars
**tpvars
;
2230 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2231 /* set the text in the record */
2232 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
2233 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
2238 void wxTextCtrl::AppendText(const wxString
& text
)
2240 SetInsertionPointEnd();
2244 void wxTextCtrl::Clear()
2246 if ( m_windowStyle
& wxTE_PASSWORD
)
2249 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
2254 bool wxTextCtrl::IsModified() const
2259 bool wxTextCtrl::IsEditable() const
2264 bool wxTextCtrl::AcceptsFocus() const
2266 // we don't want focus if we can't be edited
2267 return IsEditable() && wxControl::AcceptsFocus();
2270 wxSize
wxTextCtrl::DoGetBestSize() const
2275 if ( UMAHasAppearance() )
2279 hText
+= 2 * m_macHorizontalBorder
;
2282 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
2284 int wText = DEFAULT_ITEM_WIDTH;
2286 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
2288 return wxSize(wText, hText);
2290 if ( m_windowStyle
& wxTE_MULTILINE
)
2292 hText
*= wxMin(GetNumberOfLines(), 5);
2294 //else: for single line control everything is ok
2295 return wxSize(wText
, hText
);
2298 // ----------------------------------------------------------------------------
2300 // ----------------------------------------------------------------------------
2302 void wxTextCtrl::Undo()
2309 void wxTextCtrl::Redo()
2316 bool wxTextCtrl::CanUndo() const
2321 bool wxTextCtrl::CanRedo() const
2326 // Makes 'unmodified'
2327 void wxTextCtrl::DiscardEdits()
2332 int wxTextCtrl::GetNumberOfLines() const
2334 if ( m_windowStyle
& wxTE_PASSWORD
)
2337 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
2340 for (int i
= 0; i
< actualsize
; i
++)
2342 if (wxBuffer
[i
] == '\r') count
++;
2349 long wxTextCtrl::XYToPosition(long x
, long y
) const
2355 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
2360 void wxTextCtrl::ShowPosition(long pos
)
2365 int wxTextCtrl::GetLineLength(long lineNo
) const
2367 if ( m_windowStyle
& wxTE_PASSWORD
)
2370 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
2374 for (int i
= 0; i
< actualsize
; i
++)
2376 if (count
== lineNo
)
2378 // Count chars in line then
2380 for (int j
= i
; j
< actualsize
; j
++)
2383 if (wxBuffer
[j
] == '\r') return count
;
2388 if (wxBuffer
[i
] == '\r') count
++;
2394 wxString
wxTextCtrl::GetLineText(long lineNo
) const
2396 if ( m_windowStyle
& wxTE_PASSWORD
)
2399 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
2403 for (int i
= 0; i
< actualsize
; i
++)
2405 if (count
== lineNo
)
2407 // Add chars in line then
2410 for (int j
= i
; j
< actualsize
; j
++)
2412 if (wxBuffer
[j
] == '\r')
2420 if (wxBuffer
[i
] == '\r') count
++;
2423 return wxString("");
2430 void wxTextCtrl::Command(wxCommandEvent
& event
)
2432 SetValue (event
.GetString());
2433 ProcessCommand (event
);
2436 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
2438 // By default, load the first file into the text window.
2439 if (event
.GetNumberOfFiles() > 0)
2441 LoadFile(event
.GetFiles()[0]);
2445 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
2447 switch ( event
.KeyCode() )
2450 if (m_windowStyle
& wxPROCESS_ENTER
)
2452 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
2453 event
.SetEventObject( this );
2454 if ( GetEventHandler()->ProcessEvent(event
) )
2457 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
2459 wxWindow
*parent
= GetParent();
2460 wxPanel
*panel
= wxDynamicCast(parent
, wxPanel
);
2461 while ( parent
!= NULL
&& panel
== NULL
)
2463 parent
= parent
->GetParent() ;
2464 panel
= wxDynamicCast(parent
, wxPanel
);
2466 if ( panel
&& panel
->GetDefaultItem() )
2468 wxButton
*def
= wxDynamicCast(panel
->GetDefaultItem(),
2470 if ( def
&& def
->IsEnabled() )
2472 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
2473 event
.SetEventObject(def
);
2474 def
->Command(event
);
2479 //else: multiline controls need Enter for themselves
2484 // always produce navigation event - even if we process TAB
2485 // ourselves the fact that we got here means that the user code
2486 // decided to skip processing of this TAB - probably to let it
2487 // do its default job.
2489 wxNavigationKeyEvent eventNav
;
2490 eventNav
.SetDirection(!event
.ShiftDown());
2491 eventNav
.SetWindowChange(event
.ControlDown());
2492 eventNav
.SetEventObject(this);
2494 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
2502 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
2505 keychar
= short(ev
->message
& charCodeMask
);
2506 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
2507 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
2508 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
|| event
.KeyCode() == WXK_DELETE
|| event
.KeyCode() == WXK_BACK
)
2510 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
2511 event
.SetString( GetValue() ) ;
2512 event
.SetEventObject( this );
2513 GetEventHandler()->ProcessEvent(event
);
2518 // ----------------------------------------------------------------------------
2519 // standard handlers for standard edit menu events
2520 // ----------------------------------------------------------------------------
2522 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
2527 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
2532 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
2537 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
2542 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
2547 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2549 event
.Enable( CanCut() );
2552 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2554 event
.Enable( CanCopy() );
2557 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2559 event
.Enable( CanPaste() );
2562 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2564 event
.Enable( CanUndo() );
2567 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2569 event
.Enable( CanRedo() );