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
& key_event
)
670 bool eat_key
= FALSE
;
672 switch ( key_event
.KeyCode() )
675 if (m_windowStyle
& wxPROCESS_ENTER
)
677 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
678 event
.SetEventObject( this );
679 event
.SetString( GetValue() );
680 if ( GetEventHandler()->ProcessEvent(event
) )
683 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
685 wxWindow
*parent
= GetParent();
686 wxPanel
*panel
= wxDynamicCast(parent
, wxPanel
);
687 while ( parent
!= NULL
&& panel
== NULL
)
689 parent
= parent
->GetParent() ;
690 panel
= wxDynamicCast(parent
, wxPanel
);
692 if ( panel
&& panel
->GetDefaultItem() )
694 wxButton
*def
= wxDynamicCast(panel
->GetDefaultItem(),
696 if ( def
&& def
->IsEnabled() )
698 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
699 event
.SetEventObject(def
);
705 // this will make wxWindows eat the ENTER key so that
706 // we actually prevent line wrapping in a single line
714 // always produce navigation event - even if we process TAB
715 // ourselves the fact that we got here means that the user code
716 // decided to skip processing of this TAB - probably to let it
717 // do its default job.
719 wxNavigationKeyEvent eventNav
;
720 eventNav
.SetDirection(!key_event
.ShiftDown());
721 eventNav
.SetWindowChange(key_event
.ControlDown());
722 eventNav
.SetEventObject(this);
724 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
733 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent();
734 short keychar
= short(ev
->message
& charCodeMask
);
737 short keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
738 ::HandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
);
740 if ( keychar
>= 0x20 ||
741 key_event
.KeyCode() == WXK_RETURN
||
742 key_event
.KeyCode() == WXK_DELETE
||
743 key_event
.KeyCode() == WXK_BACK
)
745 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
746 event
.SetString( GetValue() ) ;
747 event
.SetEventObject( this );
748 GetEventHandler()->ProcessEvent(event
);
752 // ----------------------------------------------------------------------------
753 // standard handlers for standard edit menu events
754 // ----------------------------------------------------------------------------
756 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
761 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
766 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
771 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
776 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
781 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
783 event
.Enable( CanCut() );
786 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
788 event
.Enable( CanCopy() );
791 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
793 event
.Enable( CanPaste() );
796 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
798 event
.Enable( CanUndo() );
801 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
803 event
.Enable( CanRedo() );
809 #define GetControlOwner( control ) (**control).contrlOwner
812 //todo add access to global event record
816 static EventRecord
*GetCurrentEventRecord()
821 // CS:We will replace the TextEdit by using the MultiLanguageTextEngine based on the following code written by apple
827 mUPControl implementation.
830 © Copyright 2000 Apple Computer, Inc. All rights reserved.
833 IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
834 ("Apple") in consideration of your agreement to the following terms, and your
835 use, installation, modification or redistribution of this Apple software
836 constitutes acceptance of these terms. If you do not agree with these terms,
837 please do not use, install, modify or redistribute this Apple software.
839 In consideration of your agreement to abide by the following terms, and subject
840 to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
841 copyrights in this original Apple software (the "Apple Software"), to use,
842 reproduce, modify and redistribute the Apple Software, with or without
843 modifications, in source and/or binary forms; provided that if you redistribute
844 the Apple Software in its entirety and without modifications, you must retain
845 this notice and the following text and disclaimers in all such redistributions of
846 the Apple Software. Neither the name, trademarks, service marks or logos of
847 Apple Computer, Inc. may be used to endorse or promote products derived from the
848 Apple Software without specific prior written permission from Apple. Except as
849 expressly stated in this notice, no other rights or licenses, express or implied,
850 are granted by Apple herein, including but not limited to any patent rights that
851 may be infringed by your derivative works or by other works in which the Apple
852 Software may be incorporated.
854 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
855 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
856 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
857 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
858 COMBINATION WITH YOUR PRODUCTS.
860 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
861 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
862 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
863 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
864 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
865 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
866 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
868 Change History (most recent first):
869 Fri, Jan 28, 2000 -- created
872 #include "MacTextEditor.h"
876 /* kmUPTextPart is the part code we return to indicate the user has clicked
877 in the text area of our control */
878 #define kmUPTextPart 1
880 /* kmUPScrollPart is the part code we return to indicate the user has clicked
881 in the scroll bar part of the control. */
882 #define kmUPScrollPart 2
885 /* routines for using existing user pane controls.
886 These routines are useful for cases where you would like to use an
887 existing user pane control in, say, a dialog window as a scrolling
890 /* mUPOpenControl initializes a user pane control so it will be drawn
891 and will behave as a scrolling text edit field inside of a window.
892 This routine performs all of the initialization steps necessary,
893 except it does not create the user pane control itself. theControl
894 should refer to a user pane control that you have either created
895 yourself or extracted from a dialog's control heirarchy using
896 the GetDialogItemAsControl routine. */
897 OSStatus
mUPOpenControl(ControlHandle theControl
);
899 /* mUPCloseControl deallocates all of the structures allocated
900 by mUPOpenControl. */
901 OSStatus
mUPCloseControl(ControlHandle theControl
);
905 /* routines for creating new scrolling text user pane controls.
906 These routines allow you to create new scrolling text
907 user pane controls. */
909 /* mUPCreateControl creates a new user pane control and then it passes it
910 to mUPOpenControl to initialize it as a scrolling text user pane control. */
911 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
);
913 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
914 OSStatus
mUPDisposeControl(ControlHandle theControl
);
917 /* Utility Routines */
919 /* mUPSetText replaces the contents of the selection with the unicode
920 text described by the text and count parameters:.
921 text = pointer to unicode text buffer
922 count = number of bytes in the buffer. */
923 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
);
925 /* mUPGetText returns the current text data being displayed inside of
926 the mUPControl. When noErr is returned, *theText contain a new
927 handle containing all of the Unicode text copied from the current
928 selection. It is the caller's responsibiliby to dispose of this handle. */
929 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
);
932 /* mUPSetSelection sets the text selection and autoscrolls the text view
933 so either the cursor or the selction is in the view. */
934 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
);
938 /* IsmUPControl returns true if theControl is not NULL
939 and theControl refers to a mUP Control. */
940 Boolean
IsmUPControl(ControlHandle theControl
);
944 /* Edit commands for mUP Controls. */
953 /* mUPDoEditCommand performs the editing command specified
954 in the editCommand parameter. The mUPControl's text
955 and scroll bar are redrawn and updated as necessary. */
956 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
);
961 /* mUPGetContents returns the entire contents of the control including the text
962 and the formatting information. */
963 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
);
964 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
965 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
);
971 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
972 routine. In our focus switching routine this part code is understood
973 as meaning 'the user has clicked in the control and we need to switch
974 the current focus to ourselves before we can continue'. */
975 #define kUserClickedToFocusPart 100
978 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
979 slow the speed of 'auto scrolling' inside of our clickloop routine.
980 This value prevents the text from wizzzzzing by while the mouse
981 is being held down inside of the text area. */
982 #define kmUPClickScrollDelayTicks 3
985 /* STPTextPaneVars is a structure used for storing the the mUP Control's
986 internal variables and state information. A handle to this record is
987 stored in the pane control's reference value field using the
988 SetControlReference routine. */
991 /* OS records referenced */
992 TXNObject fTXNRec
; /* the txn record */
993 TXNFrameID fTXNFrame
; /* the txn frame ID */
994 ControlHandle fUserPaneRec
; /* handle to the user pane control */
995 WindowPtr fOwner
; /* window containing control */
996 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
998 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
999 Boolean fIsActive
; /* true while the control is drawn in the active state */
1000 Boolean fTEActive
; /* reflects the activation state of the text edit record */
1001 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
1002 /* calculated locations */
1003 Rect fRTextArea
; /* area where the text is drawn */
1004 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
1005 Rect fRTextOutline
; /* rectangle used to draw the border */
1006 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
1007 /* our focus advance override routine */
1008 EventHandlerUPP handlerUPP
;
1009 EventHandlerRef handlerRef
;
1015 /* Univerals Procedure Pointer variables used by the
1016 mUP Control. These variables are set up
1017 the first time that mUPOpenControl is called. */
1018 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
1019 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
1020 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
1021 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
1022 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
1023 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
1024 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
1026 /* events handled by our focus advance override routine */
1028 static const EventTypeSpec gMLTEEvents
[] = { { kEventClassTextInput
, kEventUnicodeForKeyEvent
} };
1029 #define kMLTEEventCount (sizeof( gMLTEEvents ) / sizeof( EventTypeSpec ))
1033 /* TPActivatePaneText activates or deactivates the text edit record
1034 according to the value of setActive. The primary purpose of this
1035 routine is to ensure each call is only made once. */
1036 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
1037 STPTextPaneVars
*varsp
;
1039 if (varsp
->fTEActive
!= setActive
) {
1041 varsp
->fTEActive
= setActive
;
1043 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
1045 if (varsp
->fInFocus
)
1046 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
1051 /* TPFocusPaneText set the focus state for the text record. */
1052 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
1053 STPTextPaneVars
*varsp
;
1055 if (varsp
->fInFocus
!= setFocus
) {
1056 varsp
->fInFocus
= setFocus
;
1057 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
1062 /* TPPaneDrawProc is called to redraw the control and for update events
1063 referring to the control. This routine erases the text area's background,
1064 and redraws the text. This routine assumes the scroll bar has been
1065 redrawn by a call to DrawControls. */
1066 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
1067 STPTextPaneVars
**tpvars
, *varsp
;
1070 /* set up our globals */
1071 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1072 if (tpvars
!= NULL
) {
1073 state
= HGetState((Handle
) tpvars
);
1074 HLock((Handle
) tpvars
);
1077 /* save the drawing state */
1078 SetPort((**tpvars
).fDrawingEnvironment
);
1079 /* verify our boundary */
1080 GetControlBounds(theControl
, &bounds
);
1081 if ( ! EqualRect(&bounds
, &varsp
->fRTextArea
) ) {
1082 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1083 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1084 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1085 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
1086 TXNSetFrameBounds( varsp
->fTXNRec
, bounds
.top
, bounds
.left
, bounds
.bottom
, bounds
.right
, varsp
->fTXNFrame
);
1089 /* update the text region */
1090 EraseRgn(varsp
->fTextBackgroundRgn
);
1091 TXNDraw(varsp
->fTXNRec
, NULL
);
1092 /* restore the drawing environment */
1093 /* draw the text frame and focus frame (if necessary) */
1094 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1095 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
1096 /* release our globals */
1097 HSetState((Handle
) tpvars
, state
);
1102 /* TPPaneHitTestProc is called when the control manager would
1103 like to determine what part of the control the mouse resides over.
1104 We also call this routine from our tracking proc to determine how
1105 to handle mouse clicks. */
1106 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
1107 STPTextPaneVars
**tpvars
;
1108 ControlPartCode result
;
1110 /* set up our locals and lock down our globals*/
1112 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1113 if (tpvars
!= NULL
) {
1114 state
= HGetState((Handle
) tpvars
);
1115 HLock((Handle
) tpvars
);
1116 /* find the region where we clicked */
1117 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
1118 result
= kmUPTextPart
;
1120 /* release oure globals */
1121 HSetState((Handle
) tpvars
, state
);
1130 /* TPPaneTrackingProc is called when the mouse is being held down
1131 over our control. This routine handles clicks in the text area
1132 and in the scroll bar. */
1133 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
1134 STPTextPaneVars
**tpvars
, *varsp
;
1136 ControlPartCode partCodeResult
;
1137 /* make sure we have some variables... */
1139 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1140 if (tpvars
!= NULL
) {
1142 state
= HGetState((Handle
) tpvars
);
1143 HLock((Handle
) tpvars
);
1145 /* we don't do any of these functions unless we're in focus */
1146 if ( ! varsp
->fInFocus
) {
1148 owner
= GetControlOwner(theControl
);
1149 ClearKeyboardFocus(owner
);
1150 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
1152 /* find the location for the click */
1153 switch (TPPaneHitTestProc(theControl
, startPt
)) {
1155 /* handle clicks in the text part */
1157 { SetPort((**tpvars
).fDrawingEnvironment
);
1158 TXNClick( varsp
->fTXNRec
, GetCurrentEventRecord());
1164 HSetState((Handle
) tpvars
, state
);
1166 return partCodeResult
;
1170 /* TPPaneIdleProc is our user pane idle routine. When our text field
1171 is active and in focus, we use this routine to set the cursor. */
1172 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
1173 STPTextPaneVars
**tpvars
, *varsp
;
1175 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1176 if (tpvars
!= NULL
) {
1177 /* if we're not active, then we have nothing to say about the cursor */
1178 if ((**tpvars
).fIsActive
) {
1182 /* lock down the globals */
1183 state
= HGetState((Handle
) tpvars
);
1184 HLock((Handle
) tpvars
);
1186 /* get the current mouse coordinates (in our window) */
1188 SetPort(GetWindowPort(GetControlOwner(theControl
)));
1190 SetPort((GrafPtr
) GetWindowPort(GetControlOwner(theControl
)));
1193 /* there's a 'focus thing' and an 'unfocused thing' */
1194 if (varsp
->fInFocus
) {
1195 /* flash the cursor */
1196 SetPort((**tpvars
).fDrawingEnvironment
);
1197 TXNIdle(varsp
->fTXNRec
);
1198 /* set the cursor */
1199 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
1201 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
1202 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
1204 } else SetThemeCursor(kThemeArrowCursor
);
1206 /* if it's in our bounds, set the cursor */
1207 GetControlBounds(theControl
, &bounds
);
1208 if (PtInRect(mousep
, &bounds
))
1209 SetThemeCursor(kThemeArrowCursor
);
1212 HSetState((Handle
) tpvars
, state
);
1218 /* TPPaneKeyDownProc is called whenever a keydown event is directed
1219 at our control. Here, we direct the keydown event to the text
1220 edit record and redraw the scroll bar and text field as appropriate. */
1221 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
1222 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
1223 STPTextPaneVars
**tpvars
;
1224 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1225 if (tpvars
!= NULL
) {
1226 if ((**tpvars
).fInFocus
) {
1227 /* turn autoscrolling on and send the key event to text edit */
1228 SetPort((**tpvars
).fDrawingEnvironment
);
1229 TXNKeyDown( (**tpvars
).fTXNRec
, GetCurrentEventRecord());
1232 return kControlEntireControl
;
1236 /* TPPaneActivateProc is called when the window containing
1237 the user pane control receives activate events. Here, we redraw
1238 the control and it's text as necessary for the activation state. */
1239 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
1241 STPTextPaneVars
**tpvars
, *varsp
;
1244 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1245 if (tpvars
!= NULL
) {
1246 state
= HGetState((Handle
) tpvars
);
1247 HLock((Handle
) tpvars
);
1249 /* de/activate the text edit record */
1250 SetPort((**tpvars
).fDrawingEnvironment
);
1251 GetControlBounds(theControl
, &bounds
);
1252 varsp
->fIsActive
= activating
;
1253 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1254 /* redraw the frame */
1255 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1256 if (varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
1257 HSetState((Handle
) tpvars
, state
);
1262 /* TPPaneFocusProc is called when every the focus changes to or
1263 from our control. Herein, switch the focus appropriately
1264 according to the parameters and redraw the control as
1266 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
1267 ControlPartCode focusResult
;
1268 STPTextPaneVars
**tpvars
, *varsp
;
1271 focusResult
= kControlFocusNoPart
;
1272 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1273 if (tpvars
!= NULL
) {
1274 state
= HGetState((Handle
) tpvars
);
1275 HLock((Handle
) tpvars
);
1277 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
1278 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
1279 and kControlFocusNextPart will be received. When the user clicks in our field
1280 and it is not the current focus, then the constant kUserClickedToFocusPart will
1281 be received. The constant kControlFocusNoPart will be received when our control
1282 is the current focus and the user clicks in another control. In your focus routine,
1283 you should respond to these codes as follows:
1285 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
1286 the control and the focus rectangle as necessary.
1288 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
1289 depending on its current state. redraw the control and the focus rectangle
1290 as appropriate for the new focus state. If the focus state is 'off', return the constant
1291 kControlFocusNoPart, otherwise return a non-zero part code.
1292 kUserClickedToFocusPart - is a constant defined for this example. You should
1293 define your own value for handling click-to-focus type events. */
1294 /* save the drawing state */
1295 SetPort((**tpvars
).fDrawingEnvironment
);
1296 /* calculate the next highlight state */
1299 case kControlFocusNoPart
:
1300 TPFocusPaneText(tpvars
, false);
1301 focusResult
= kControlFocusNoPart
;
1303 case kUserClickedToFocusPart
:
1304 TPFocusPaneText(tpvars
, true);
1307 case kControlFocusPrevPart
:
1308 case kControlFocusNextPart
:
1309 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
1310 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
1313 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1314 /* redraw the text fram and focus rectangle to indicate the
1316 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1317 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
1319 HSetState((Handle
) tpvars
, state
);
1334 //This our carbon event handler for unicode key downs
1336 static pascal OSStatus
FocusAdvanceOverride(EventHandlerCallRef myHandler
, EventRef event
, void* userData
) {
1338 STPTextPaneVars
**tpvars
;
1340 unsigned short mUnicodeText
;
1341 ByteCount charCounts
=0;
1342 /* get our window pointer */
1343 tpvars
= (STPTextPaneVars
**) userData
;
1344 window
= (**tpvars
).fOwner
;
1345 //find out how many bytes are needed
1346 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1347 typeUnicodeText
, NULL
, 0, &charCounts
, NULL
);
1348 if (err
!= noErr
) goto bail
;
1349 /* we're only looking at single characters */
1350 if (charCounts
!= 2) { err
= eventNotHandledErr
; goto bail
; }
1351 /* get the character */
1352 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1353 typeUnicodeText
, NULL
, sizeof(mUnicodeText
),
1354 &charCounts
, (char*) &mUnicodeText
);
1355 if (err
!= noErr
) goto bail
;
1356 /* if it's not the tab key, forget it... */
1357 if ((mUnicodeText
!= '\t')) { err
= eventNotHandledErr
; goto bail
; }
1358 /* advance the keyboard focus */
1359 AdvanceKeyboardFocus(window
);
1360 /* noErr lets the CEM know we handled the event */
1363 return eventNotHandledErr
;
1368 /* mUPOpenControl initializes a user pane control so it will be drawn
1369 and will behave as a scrolling text edit field inside of a window.
1370 This routine performs all of the initialization steps necessary,
1371 except it does not create the user pane control itself. theControl
1372 should refer to a user pane control that you have either created
1373 yourself or extracted from a dialog's control heirarchy using
1374 the GetDialogItemAsControl routine. */
1375 OSStatus
mUPOpenControl(ControlHandle theControl
) {
1377 WindowPtr theWindow
;
1378 STPTextPaneVars
**tpvars
, *varsp
;
1380 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
1381 TXNBackground tback
;
1383 /* set up our globals */
1384 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
1385 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
1386 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
1387 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
1388 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
1389 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
1390 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
1392 /* allocate our private storage */
1393 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
1394 SetControlReference(theControl
, (long) tpvars
);
1395 HLock((Handle
) tpvars
);
1397 /* set the initial settings for our private data */
1398 varsp
->fInFocus
= false;
1399 varsp
->fIsActive
= true;
1400 varsp
->fTEActive
= false;
1401 varsp
->fUserPaneRec
= theControl
;
1402 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
1404 varsp
->fDrawingEnvironment
= GetWindowPort(varsp
->fOwner
);
1406 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(varsp
->fOwner
);
1408 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
1409 /* set up the user pane procedures */
1410 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
1411 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
1412 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
1413 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
1414 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
1415 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
1416 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
1417 /* calculate the rectangles used by the control */
1418 GetControlBounds(theControl
, &bounds
);
1419 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1420 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1421 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1422 /* calculate the background region for the text. In this case, it's kindof
1423 and irregular region because we're setting the scroll bar a little ways inside
1424 of the text area. */
1425 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
1427 /* set up the drawing environment */
1428 SetPort(varsp
->fDrawingEnvironment
);
1430 /* create the new edit field */
1431 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
1432 kTXNWantVScrollBarMask
| kTXNAlwaysWrapAtViewEdgeMask
,
1433 kTXNTextEditStyleFrameType
,
1435 kTXNSystemDefaultEncoding
,
1436 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
1438 /* set the field's background */
1439 tback
.bgType
= kTXNBackgroundTypeRGB
;
1440 tback
.bg
.color
= rgbWhite
;
1441 TXNSetBackground( varsp
->fTXNRec
, &tback
);
1443 /* install our focus advance override routine */
1445 varsp
->handlerUPP
= NewEventHandlerUPP(FocusAdvanceOverride
);
1446 err
= InstallWindowEventHandler( varsp
->fOwner
, varsp
->handlerUPP
,
1447 kMLTEEventCount
, gMLTEEvents
, tpvars
, &varsp
->handlerRef
);
1450 /* unlock our storage */
1451 HUnlock((Handle
) tpvars
);
1452 /* perform final activations and setup for our text field. Here,
1453 we assume that the window is going to be the 'active' window. */
1454 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1461 /* mUPCloseControl deallocates all of the structures allocated
1462 by mUPOpenControl. */
1463 OSStatus
mUPCloseControl(ControlHandle theControl
) {
1464 STPTextPaneVars
**tpvars
;
1466 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1467 /* release our sub records */
1468 TXNDeleteObject((**tpvars
).fTXNRec
);
1469 /* remove our focus advance override */
1470 RemoveEventHandler((**tpvars
).handlerRef
);
1471 DisposeEventHandlerUPP((**tpvars
).handlerUPP
);
1472 /* delete our private storage */
1473 DisposeHandle((Handle
) tpvars
);
1474 /* zero the control reference */
1475 SetControlReference(theControl
, 0);
1482 /* mUPSetText replaces the contents of the selection with the unicode
1483 text described by the text and count parameters:.
1484 text = pointer to unicode text buffer
1485 count = number of bytes in the buffer. */
1486 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
) {
1487 STPTextPaneVars
**tpvars
;
1489 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1490 /* set the text in the record */
1491 return TXNSetData( (**tpvars
).fTXNRec
, kTXNUnicodeTextData
, text
, count
,
1492 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1498 /* mUPSetSelection sets the text selection and autoscrolls the text view
1499 so either the cursor or the selction is in the view. */
1500 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
) {
1501 STPTextPaneVars
**tpvars
;
1502 /* set up our locals */
1503 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1504 /* and our drawing environment as the operation
1505 may force a redraw in the text area. */
1506 SetPort((**tpvars
).fDrawingEnvironment
);
1507 /* change the selection */
1508 TXNSetSelection( (**tpvars
).fTXNRec
, selStart
, selEnd
);
1515 /* mUPGetText returns the current text data being displayed inside of
1516 the mUPControl. When noErr is returned, *theText contain a new
1517 handle containing all of the Unicode text copied from the current
1518 selection. It is the caller's responsibiliby to dispose of this handle. */
1519 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
) {
1520 STPTextPaneVars
**tpvars
;
1523 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1524 /* extract the text from the record */
1525 err
= TXNGetData( (**tpvars
).fTXNRec
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, theText
);
1532 /* mUPCreateControl creates a new user pane control and then it passes it
1533 to mUPOpenControl to initialize it as a scrolling text user pane control. */
1534 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
) {
1536 /* the following feature set can be specified in CNTL resources by using
1537 the value 1214. When creating a user pane control, we pass this value
1538 in the 'value' parameter. */
1539 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
1540 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
1541 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
1542 /* create the control */
1543 *theControl
= NewControl(theWindow
, bounds
, "\p", true, featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
1544 /* set up the mUP specific features and data */
1545 mUPOpenControl(*theControl
);
1551 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
1552 OSStatus
mUPDisposeControl(ControlHandle theControl
) {
1553 /* deallocate the mUP specific data */
1554 mUPCloseControl(theControl
);
1555 /* deallocate the user pane control itself */
1556 DisposeControl(theControl
);
1563 /* IsmUPControl returns true if theControl is not NULL
1564 and theControl refers to a mUP Control. */
1565 Boolean
IsmUPControl(ControlHandle theControl
) {
1567 ControlUserPaneFocusUPP localFocusProc
;
1568 /* a NULL control is not a mUP control */
1569 if (theControl
== NULL
) return false;
1570 /* check if the control is using our focus procedure */
1571 theSize
= sizeof(localFocusProc
);
1572 if (GetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
,
1573 sizeof(localFocusProc
), &localFocusProc
, &theSize
) != noErr
) return false;
1574 if (localFocusProc
!= gTPFocusProc
) return false;
1575 /* all tests passed, it's a mUP control */
1580 /* mUPDoEditCommand performs the editing command specified
1581 in the editCommand parameter. The mUPControl's text
1582 and scroll bar are redrawn and updated as necessary. */
1583 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
) {
1584 STPTextPaneVars
**tpvars
;
1585 /* set up our locals */
1586 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1587 /* and our drawing environment as the operation
1588 may force a redraw in the text area. */
1589 SetPort((**tpvars
).fDrawingEnvironment
);
1590 /* perform the editing command */
1591 switch (editCommand
) {
1593 ClearCurrentScrap();
1594 TXNCut((**tpvars
).fTXNRec
);
1595 TXNConvertToPublicScrap();
1598 ClearCurrentScrap();
1599 TXNCopy((**tpvars
).fTXNRec
);
1600 TXNConvertToPublicScrap();
1603 TXNConvertFromPublicScrap();
1604 TXNPaste((**tpvars
).fTXNRec
);
1607 TXNClear((**tpvars
).fTXNRec
);
1615 /* mUPGetContents returns the entire contents of the control including the text
1616 and the formatting information. */
1617 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
) {
1618 STPTextPaneVars
**tpvars
;
1631 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1632 if (theContents
== NULL
) return paramErr
;
1633 /* create a temporary file */
1634 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1635 if (err
!= noErr
) goto bail
;
1636 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPGetContents", &tspec
);
1637 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1638 if (err
!= noErr
) goto bail
;
1641 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1642 if (err
!= noErr
) goto bail
;
1644 err
= TXNSave( (**tpvars
).fTXNRec
, kTXNTextensionFile
, 0, kTXNSystemDefaultEncoding
, &tspec
, trefnum
, 0);
1645 if (err
!= noErr
) goto bail
;
1646 /* get the file length and set the position */
1647 err
= GetEOF(trefnum
, &bytecount
);
1648 if (err
!= noErr
) goto bail
;
1649 err
= SetFPos(trefnum
, fsFromStart
, 0);
1650 if (err
!= noErr
) goto bail
;
1651 /* copy the data fork to a handle */
1652 localdata
= NewHandle(bytecount
);
1653 if (localdata
== NULL
) { err
= memFullErr
; goto bail
; }
1655 err
= FSRead(trefnum
, &bytecount
, *localdata
);
1657 if (err
!= noErr
) goto bail
;
1659 *theContents
= localdata
;
1666 if (trefnum
!= 0) FSClose(trefnum
);
1667 if (texists
) FSpDelete(&tspec
);
1668 if (localdata
!= NULL
) DisposeHandle(localdata
);
1675 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
1676 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
) {
1677 STPTextPaneVars
**tpvars
;
1689 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1690 if (theContents
== NULL
) return paramErr
;
1691 /* create a temporary file */
1692 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1693 if (err
!= noErr
) goto bail
;
1694 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPSetContents", &tspec
);
1695 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1696 if (err
!= noErr
) goto bail
;
1699 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1700 if (err
!= noErr
) goto bail
;
1701 /* save the data to the temporary file */
1702 state
= HGetState(theContents
);
1704 bytecount
= GetHandleSize(theContents
);
1705 err
= FSWrite(trefnum
, &bytecount
, *theContents
);
1706 HSetState(theContents
, state
);
1707 if (err
!= noErr
) goto bail
;
1708 /* reset the file position */
1709 err
= SetFPos(trefnum
, fsFromStart
, 0);
1710 if (err
!= noErr
) goto bail
;
1712 err
= TXNSetDataFromFile((**tpvars
).fTXNRec
, trefnum
, kTXNTextensionFile
, bytecount
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1713 if (err
!= noErr
) goto bail
;
1720 if (trefnum
!= 0) FSClose(trefnum
);
1721 if (texists
) FSpDelete(&tspec
);
1725 #if !USE_SHARED_LIBRARY
1726 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
1728 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
1729 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
1730 EVT_CHAR(wxTextCtrl::OnChar
)
1731 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
1732 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
1733 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
1734 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
1735 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
1737 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
1738 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
1739 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
1740 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
1741 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
1746 wxTextCtrl::wxTextCtrl()
1750 const short kVerticalMargin
= 2 ;
1751 const short kHorizontalMargin
= 2 ;
1753 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1756 const wxSize
& size
, long style
,
1757 const wxValidator
& validator
,
1758 const wxString
& name
)
1760 // base initialization
1761 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
1764 wxSize mySize
= size
;
1765 if ( UMAHasAppearance() )
1767 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
1768 m_macVerticalBorder
= 5 ;
1772 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
1773 m_macVerticalBorder
= 0 ;
1780 if ( mySize
.y
== -1 )
1782 if ( UMAHasAppearance() )
1787 mySize
.y
+= 2 * m_macVerticalBorder
;
1790 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
1792 if ( m_windowStyle
& wxTE_MULTILINE
)
1794 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
1795 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
1797 m_windowStyle
|= wxTE_PROCESS_ENTER
;
1801 if ( style
& wxTE_PASSWORD
)
1803 m_macControl
= ::NewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
1804 kControlEditTextPasswordProc
, (long) this ) ;
1808 if ( mUPCreateControl(parent
->GetMacRootWindow(), &bounds
, &m_macControl
) != noErr
)
1811 MacPostControlCreate() ;
1815 if( wxApp::s_macDefaultEncodingIsPC
)
1816 value
= wxMacMakeMacStringFromPC( st
) ;
1820 if ( style
& wxTE_PASSWORD
)
1822 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1826 STPTextPaneVars
**tpvars
;
1828 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1829 /* set the text in the record */
1830 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1831 kTXNStartOffset
, kTXNEndOffset
);
1837 wxString
wxTextCtrl::GetValue() const
1840 if ( m_windowStyle
& wxTE_PASSWORD
)
1842 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
1846 STPTextPaneVars
**tpvars
;
1849 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1850 /* extract the text from the record */
1852 err
= TXNGetDataEncoded( (**tpvars
).fTXNRec
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1860 actualsize
= GetHandleSize( theText
) ;
1861 strncpy( wxBuffer
, *theText
, actualsize
) ;
1862 DisposeHandle( theText
) ;
1865 wxBuffer
[actualsize
] = 0 ;
1866 if( wxApp::s_macDefaultEncodingIsPC
)
1867 return wxMacMakePCStringFromMac( wxBuffer
) ;
1869 return wxString(wxBuffer
);
1872 void wxTextCtrl::GetSelection(long* from
, long* to
) const
1874 if ( m_windowStyle
& wxTE_PASSWORD
)
1876 ControlEditTextSelectionRec selection
;
1880 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1882 *from
= (**teH
).selStart
;
1883 *to
= (**teH
).selEnd
;
1887 STPTextPaneVars
**tpvars
;
1890 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1892 TXNGetSelection( (**tpvars
).fTXNRec
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1897 void wxTextCtrl::SetValue(const wxString
& st
)
1901 if( wxApp::s_macDefaultEncodingIsPC
)
1902 value
= wxMacMakeMacStringFromPC( st
) ;
1905 if ( m_windowStyle
& wxTE_PASSWORD
)
1907 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1911 STPTextPaneVars
**tpvars
;
1913 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1914 /* set the text in the record */
1915 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1916 kTXNStartOffset
, kTXNEndOffset
);
1918 WindowRef window
= GetMacRootWindow() ;
1921 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1924 wxMacDrawingHelper
help( win
) ;
1925 // the mac control manager always assumes to have the origin at 0,0
1926 SetOrigin( 0 , 0 ) ;
1928 bool hasTabBehind
= false ;
1929 wxWindow
* parent
= GetParent() ;
1932 if( parent
->MacGetWindowData() )
1934 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
1938 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
1940 if ( ((wxControl
*)parent
)->GetMacControl() )
1941 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
1945 parent
= parent
->GetParent() ;
1948 UMADrawControl( m_macControl
) ;
1949 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
1954 // Clipboard operations
1955 void wxTextCtrl::Copy()
1959 if ( m_windowStyle
& wxTE_PASSWORD
)
1964 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1968 err
= ClearCurrentScrap( );
1978 void wxTextCtrl::Cut()
1982 if ( m_windowStyle
& wxTE_PASSWORD
)
1987 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1991 err
= ClearCurrentScrap( );
1997 // MacInvalidateControl() ;
2002 void wxTextCtrl::Paste()
2006 if ( m_windowStyle
& wxTE_PASSWORD
)
2011 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2014 WindowRef window
= GetMacRootWindow() ;
2017 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
2020 wxMacDrawingHelper
help( win
) ;
2021 // the mac control manager always assumes to have the origin at 0,0
2022 SetOrigin( 0 , 0 ) ;
2024 bool hasTabBehind
= false ;
2025 wxWindow
* parent
= GetParent() ;
2028 if( parent
->MacGetWindowData() )
2030 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
2034 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
2036 if ( ((wxControl
*)parent
)->GetMacControl() )
2037 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
2041 parent
= parent
->GetParent() ;
2044 UMADrawControl( m_macControl
) ;
2045 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
2052 bool wxTextCtrl::CanCopy() const
2054 // Can copy if there's a selection
2056 GetSelection(& from
, & to
);
2057 return (from
!= to
);
2060 bool wxTextCtrl::CanCut() const
2062 // Can cut if there's a selection
2064 GetSelection(& from
, & to
);
2065 return (from
!= to
);
2068 bool wxTextCtrl::CanPaste() const
2075 OSStatus err
= noErr
;
2078 err
= GetCurrentScrap( &scrapRef
);
2079 if ( err
!= noTypeErr
&& err
!= memFullErr
)
2081 ScrapFlavorFlags flavorFlags
;
2084 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
2086 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
2095 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
2103 void wxTextCtrl::SetEditable(bool editable
)
2106 UMAActivateControl( m_macControl
) ;
2108 UMADeactivateControl( m_macControl
) ;
2111 void wxTextCtrl::SetInsertionPoint(long pos
)
2113 SetSelection( pos
, pos
) ;
2116 void wxTextCtrl::SetInsertionPointEnd()
2118 long pos
= GetLastPosition();
2119 SetInsertionPoint(pos
);
2122 long wxTextCtrl::GetInsertionPoint() const
2125 GetSelection( &begin
, &end
) ;
2129 long wxTextCtrl::GetLastPosition() const
2131 if ( m_windowStyle
& wxTE_PASSWORD
)
2134 ControlEditTextSelectionRec selection
;
2138 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2140 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
2141 return (**teH
).teLength
;
2145 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
2147 if ( m_windowStyle
& wxTE_PASSWORD
)
2152 ControlEditTextSelectionRec selection
;
2154 selection
.selStart
= from
;
2155 selection
.selEnd
= to
;
2156 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2157 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2158 TESetSelect( from
, to
, teH
) ;
2160 TEInsert( value
, value
.Length() , teH
) ;
2165 void wxTextCtrl::Remove(long from
, long to
)
2167 if ( m_windowStyle
& wxTE_PASSWORD
)
2172 ControlEditTextSelectionRec selection
;
2174 selection
.selStart
= from
;
2175 selection
.selEnd
= to
;
2176 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2177 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2183 void wxTextCtrl::SetSelection(long from
, long to
)
2185 if ( m_windowStyle
& wxTE_PASSWORD
)
2187 ControlEditTextSelectionRec selection
;
2191 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2193 selection
.selStart
= from
;
2194 selection
.selEnd
= to
;
2196 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2197 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
2201 STPTextPaneVars
**tpvars
;
2202 /* set up our locals */
2203 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2204 /* and our drawing environment as the operation
2205 may force a redraw in the text area. */
2206 SetPort((**tpvars
).fDrawingEnvironment
);
2207 /* change the selection */
2208 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
2212 bool wxTextCtrl::LoadFile(const wxString
& file
)
2214 if ( wxTextCtrlBase::LoadFile(file
) )
2222 void wxTextCtrl::WriteText(const wxString
& text
)
2225 if( wxApp::s_macDefaultEncodingIsPC
)
2226 value
= wxMacMakeMacStringFromPC( text
) ;
2229 if ( m_windowStyle
& wxTE_PASSWORD
)
2234 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2235 TEInsert( value
, value
.Length() , teH
) ;
2239 STPTextPaneVars
**tpvars
;
2241 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2242 /* set the text in the record */
2243 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
2244 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
2249 void wxTextCtrl::AppendText(const wxString
& text
)
2251 SetInsertionPointEnd();
2255 void wxTextCtrl::Clear()
2257 if ( m_windowStyle
& wxTE_PASSWORD
)
2260 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
2265 bool wxTextCtrl::IsModified() const
2270 bool wxTextCtrl::IsEditable() const
2275 bool wxTextCtrl::AcceptsFocus() const
2277 // we don't want focus if we can't be edited
2278 return IsEditable() && wxControl::AcceptsFocus();
2281 wxSize
wxTextCtrl::DoGetBestSize() const
2286 if ( UMAHasAppearance() )
2290 hText
+= 2 * m_macHorizontalBorder
;
2293 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
2295 int wText = DEFAULT_ITEM_WIDTH;
2297 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
2299 return wxSize(wText, hText);
2301 if ( m_windowStyle
& wxTE_MULTILINE
)
2303 hText
*= wxMin(GetNumberOfLines(), 5);
2305 //else: for single line control everything is ok
2306 return wxSize(wText
, hText
);
2309 // ----------------------------------------------------------------------------
2311 // ----------------------------------------------------------------------------
2313 void wxTextCtrl::Undo()
2320 void wxTextCtrl::Redo()
2327 bool wxTextCtrl::CanUndo() const
2332 bool wxTextCtrl::CanRedo() const
2337 // Makes 'unmodified'
2338 void wxTextCtrl::DiscardEdits()
2343 int wxTextCtrl::GetNumberOfLines() const
2345 if ( m_windowStyle
& wxTE_PASSWORD
)
2348 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
2351 for (int i
= 0; i
< actualsize
; i
++)
2353 if (wxBuffer
[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 if ( m_windowStyle
& wxTE_PASSWORD
)
2381 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
2385 for (int i
= 0; i
< actualsize
; i
++)
2387 if (count
== lineNo
)
2389 // Count chars in line then
2391 for (int j
= i
; j
< actualsize
; j
++)
2394 if (wxBuffer
[j
] == '\r') return count
;
2399 if (wxBuffer
[i
] == '\r') count
++;
2405 wxString
wxTextCtrl::GetLineText(long lineNo
) const
2407 if ( m_windowStyle
& wxTE_PASSWORD
)
2410 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
2414 for (int i
= 0; i
< actualsize
; i
++)
2416 if (count
== lineNo
)
2418 // Add chars in line then
2421 for (int j
= i
; j
< actualsize
; j
++)
2423 if (wxBuffer
[j
] == '\r')
2431 if (wxBuffer
[i
] == '\r') count
++;
2434 return wxString("");
2441 void wxTextCtrl::Command(wxCommandEvent
& event
)
2443 SetValue (event
.GetString());
2444 ProcessCommand (event
);
2447 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
2449 // By default, load the first file into the text window.
2450 if (event
.GetNumberOfFiles() > 0)
2452 LoadFile(event
.GetFiles()[0]);
2456 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
2458 switch ( event
.KeyCode() )
2461 if (m_windowStyle
& wxPROCESS_ENTER
)
2463 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
2464 event
.SetEventObject( this );
2465 if ( GetEventHandler()->ProcessEvent(event
) )
2468 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
2470 wxWindow
*parent
= GetParent();
2471 wxPanel
*panel
= wxDynamicCast(parent
, wxPanel
);
2472 while ( parent
!= NULL
&& panel
== NULL
)
2474 parent
= parent
->GetParent() ;
2475 panel
= wxDynamicCast(parent
, wxPanel
);
2477 if ( panel
&& panel
->GetDefaultItem() )
2479 wxButton
*def
= wxDynamicCast(panel
->GetDefaultItem(),
2481 if ( def
&& def
->IsEnabled() )
2483 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
2484 event
.SetEventObject(def
);
2485 def
->Command(event
);
2490 //else: multiline controls need Enter for themselves
2495 // always produce navigation event - even if we process TAB
2496 // ourselves the fact that we got here means that the user code
2497 // decided to skip processing of this TAB - probably to let it
2498 // do its default job.
2500 wxNavigationKeyEvent eventNav
;
2501 eventNav
.SetDirection(!event
.ShiftDown());
2502 eventNav
.SetWindowChange(event
.ControlDown());
2503 eventNav
.SetEventObject(this);
2505 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
2513 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
2516 keychar
= short(ev
->message
& charCodeMask
);
2517 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
2518 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
2519 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
|| event
.KeyCode() == WXK_DELETE
|| event
.KeyCode() == WXK_BACK
)
2521 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
2522 event
.SetString( GetValue() ) ;
2523 event
.SetEventObject( this );
2524 GetEventHandler()->ProcessEvent(event
);
2529 // ----------------------------------------------------------------------------
2530 // standard handlers for standard edit menu events
2531 // ----------------------------------------------------------------------------
2533 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
2538 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
2543 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
2548 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
2553 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
2558 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2560 event
.Enable( CanCut() );
2563 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2565 event
.Enable( CanCopy() );
2568 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2570 event
.Enable( CanPaste() );
2573 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2575 event
.Enable( CanUndo() );
2578 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2580 event
.Enable( CanRedo() );