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"
31 #include "wx/toplevel.h"
32 #include "wx/textctrl.h"
33 #include "wx/notebook.h"
34 #include "wx/tabctrl.h"
35 #include "wx/settings.h"
36 #include "wx/filefn.h"
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
->MacGetRootWindow() , &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
= MacGetRootWindow() ;
185 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
188 wxMacDrawingHelper
help( win
) ;
189 // the mac control manager always assumes to have the origin at 0,0
191 bool hasTabBehind
= false ;
192 wxWindow
* parent
= GetParent() ;
195 if( parent
->IsTopLevel() )
197 // ::SetThemeWindowBackground( win->MacGetRootWindow() , kThemeBrushDialogBackgroundActive , false ) ;
201 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
203 if ( ((wxControl
*)parent
)->GetMacControl() )
204 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
208 parent
= parent
->GetParent() ;
211 UMADrawControl( m_macControl
) ;
212 // ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
217 // Clipboard operations
218 void wxTextCtrl::Copy()
225 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
232 void wxTextCtrl::Cut()
239 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
243 // MacInvalidateControl() ;
247 void wxTextCtrl::Paste()
254 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
257 WindowRef window
= MacGetRootWindow() ;
260 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
263 wxMacDrawingHelper
help( win
) ;
264 // the mac control manager always assumes to have the origin at 0,0
266 bool hasTabBehind
= false ;
267 wxWindow
* parent
= GetParent() ;
270 if( parent
->IsTopLevel() )
272 // ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , kThemeBrushDialogBackgroundActive , false ) ;
276 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
278 if ( ((wxControl
*)parent
)->GetMacControl() )
279 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
283 parent
= parent
->GetParent() ;
286 UMADrawControl( m_macControl
) ;
287 // ::SetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
293 bool wxTextCtrl::CanCopy() const
295 // Can copy if there's a selection
297 GetSelection(& from
, & to
);
301 bool wxTextCtrl::CanCut() const
303 // Can cut if there's a selection
305 GetSelection(& from
, & to
);
309 bool wxTextCtrl::CanPaste() const
316 OSStatus err
= noErr
;
319 err
= GetCurrentScrap( &scrapRef
);
320 if ( err
!= noTypeErr
&& err
!= memFullErr
)
322 ScrapFlavorFlags flavorFlags
;
325 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
327 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
336 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
344 void wxTextCtrl::SetEditable(bool editable
)
347 UMAActivateControl( m_macControl
) ;
349 UMADeactivateControl( m_macControl
) ;
352 void wxTextCtrl::SetInsertionPoint(long pos
)
354 SetSelection( pos
, pos
) ;
357 void wxTextCtrl::SetInsertionPointEnd()
359 long pos
= GetLastPosition();
360 SetInsertionPoint(pos
);
363 long wxTextCtrl::GetInsertionPoint() const
365 ControlEditTextSelectionRec selection
;
369 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
370 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
371 return (**teH
).selStart
;
374 long wxTextCtrl::GetLastPosition() const
376 ControlEditTextSelectionRec selection
;
380 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
382 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
383 return (**teH
).teLength
;
386 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
391 ControlEditTextSelectionRec selection
;
393 selection
.selStart
= from
;
394 selection
.selEnd
= to
;
395 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
396 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
397 TESetSelect( from
, to
, teH
) ;
399 TEInsert( value
, value
.Length() , teH
) ;
403 void wxTextCtrl::Remove(long from
, long to
)
408 ControlEditTextSelectionRec selection
;
410 selection
.selStart
= from
;
411 selection
.selEnd
= to
;
412 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
413 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
418 void wxTextCtrl::SetSelection(long from
, long to
)
420 ControlEditTextSelectionRec selection
;
424 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
426 selection
.selStart
= from
;
427 selection
.selEnd
= to
;
429 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
430 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
433 bool wxTextCtrl::LoadFile(const wxString
& file
)
435 if ( wxTextCtrlBase::LoadFile(file
) )
443 void wxTextCtrl::WriteText(const wxString
& text
)
448 memcpy( wxBuffer
, text
, text
.Length() ) ;
449 wxBuffer
[text
.Length() ] = 0 ;
450 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
452 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
454 TEInsert( wxBuffer
, strlen( wxBuffer
) , teH
) ;
458 void wxTextCtrl::AppendText(const wxString
& text
)
460 SetInsertionPointEnd();
464 void wxTextCtrl::Clear()
466 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
470 bool wxTextCtrl::IsModified() const
475 bool wxTextCtrl::IsEditable() const
480 bool wxTextCtrl::AcceptsFocus() const
482 // we don't want focus if we can't be edited
483 return IsEditable() && wxControl::AcceptsFocus();
486 wxSize
wxTextCtrl::DoGetBestSize() const
491 if ( UMAHasAppearance() )
495 hText
+= 2 * m_macHorizontalBorder
;
498 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
500 int wText = DEFAULT_ITEM_WIDTH;
502 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
504 return wxSize(wText, hText);
506 if ( m_windowStyle
& wxTE_MULTILINE
)
508 hText
*= wxMin(GetNumberOfLines(), 5);
510 //else: for single line control everything is ok
511 return wxSize(wText
, hText
);
514 // ----------------------------------------------------------------------------
516 // ----------------------------------------------------------------------------
518 void wxTextCtrl::Undo()
525 void wxTextCtrl::Redo()
532 bool wxTextCtrl::CanUndo() const
537 bool wxTextCtrl::CanRedo() const
542 // Makes 'unmodified'
543 void wxTextCtrl::DiscardEdits()
548 int wxTextCtrl::GetNumberOfLines() const
551 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
554 for (int i
= 0; i
< actualsize
; i
++)
556 if (wxBuffer
[i
] == '\r') count
++;
562 long wxTextCtrl::XYToPosition(long x
, long y
) const
568 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
573 void wxTextCtrl::ShowPosition(long pos
)
578 int wxTextCtrl::GetLineLength(long lineNo
) const
581 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
585 for (int i
= 0; i
< actualsize
; i
++)
589 // Count chars in line then
591 for (int j
= i
; j
< actualsize
; j
++)
594 if (wxBuffer
[j
] == '\r') return count
;
599 if (wxBuffer
[i
] == '\r') count
++;
605 wxString
wxTextCtrl::GetLineText(long lineNo
) const
608 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
612 for (int i
= 0; i
< actualsize
; i
++)
616 // Add chars in line then
619 for (int j
= i
; j
< actualsize
; j
++)
621 if (wxBuffer
[j
] == '\r')
629 if (wxBuffer
[i
] == '\r') count
++;
639 void wxTextCtrl::Command(wxCommandEvent
& event
)
641 SetValue (event
.GetString());
642 ProcessCommand (event
);
645 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
647 // By default, load the first file into the text window.
648 if (event
.GetNumberOfFiles() > 0)
650 LoadFile(event
.GetFiles()[0]);
654 void wxTextCtrl::OnChar(wxKeyEvent
& key_event
)
656 bool eat_key
= FALSE
;
658 switch ( key_event
.KeyCode() )
661 if (m_windowStyle
& wxPROCESS_ENTER
)
663 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
664 event
.SetEventObject( this );
665 event
.SetString( GetValue() );
666 if ( GetEventHandler()->ProcessEvent(event
) )
669 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
671 wxWindow
*parent
= GetParent();
672 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
673 parent
= parent
->GetParent() ;
675 if ( parent
&& parent
->GetDefaultItem() )
677 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
679 if ( def
&& def
->IsEnabled() )
681 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
682 event
.SetEventObject(def
);
688 // this will make wxWindows eat the ENTER key so that
689 // we actually prevent line wrapping in a single line
697 // always produce navigation event - even if we process TAB
698 // ourselves the fact that we got here means that the user code
699 // decided to skip processing of this TAB - probably to let it
700 // do its default job.
702 wxNavigationKeyEvent eventNav
;
703 eventNav
.SetDirection(!key_event
.ShiftDown());
704 eventNav
.SetWindowChange(key_event
.ControlDown());
705 eventNav
.SetEventObject(this);
707 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
716 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent();
717 short keychar
= short(ev
->message
& charCodeMask
);
720 short keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
721 ::HandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
);
723 if ( keychar
>= 0x20 ||
724 key_event
.KeyCode() == WXK_RETURN
||
725 key_event
.KeyCode() == WXK_DELETE
||
726 key_event
.KeyCode() == WXK_BACK
)
728 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
729 event
.SetString( GetValue() ) ;
730 event
.SetEventObject( this );
731 GetEventHandler()->ProcessEvent(event
);
735 // ----------------------------------------------------------------------------
736 // standard handlers for standard edit menu events
737 // ----------------------------------------------------------------------------
739 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
744 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
749 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
754 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
759 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
764 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
766 event
.Enable( CanCut() );
769 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
771 event
.Enable( CanCopy() );
774 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
776 event
.Enable( CanPaste() );
779 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
781 event
.Enable( CanUndo() );
784 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
786 event
.Enable( CanRedo() );
791 extern wxApp
*wxTheApp
;
792 // CS:We will replace the TextEdit by using the MultiLanguageTextEngine based on the following code written by apple
798 mUPControl implementation.
801 © Copyright 2000 Apple Computer, Inc. All rights reserved.
804 IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
805 ("Apple") in consideration of your agreement to the following terms, and your
806 use, installation, modification or redistribution of this Apple software
807 constitutes acceptance of these terms. If you do not agree with these terms,
808 please do not use, install, modify or redistribute this Apple software.
810 In consideration of your agreement to abide by the following terms, and subject
811 to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
812 copyrights in this original Apple software (the "Apple Software"), to use,
813 reproduce, modify and redistribute the Apple Software, with or without
814 modifications, in source and/or binary forms; provided that if you redistribute
815 the Apple Software in its entirety and without modifications, you must retain
816 this notice and the following text and disclaimers in all such redistributions of
817 the Apple Software. Neither the name, trademarks, service marks or logos of
818 Apple Computer, Inc. may be used to endorse or promote products derived from the
819 Apple Software without specific prior written permission from Apple. Except as
820 expressly stated in this notice, no other rights or licenses, express or implied,
821 are granted by Apple herein, including but not limited to any patent rights that
822 may be infringed by your derivative works or by other works in which the Apple
823 Software may be incorporated.
825 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
826 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
827 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
828 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
829 COMBINATION WITH YOUR PRODUCTS.
831 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
832 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
833 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
834 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
835 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
836 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
837 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
839 Change History (most recent first):
840 Fri, Jan 28, 2000 -- created
843 #include "MacTextEditor.h"
847 /* kmUPTextPart is the part code we return to indicate the user has clicked
848 in the text area of our control */
849 #define kmUPTextPart 1
851 /* kmUPScrollPart is the part code we return to indicate the user has clicked
852 in the scroll bar part of the control. */
853 #define kmUPScrollPart 2
856 /* routines for using existing user pane controls.
857 These routines are useful for cases where you would like to use an
858 existing user pane control in, say, a dialog window as a scrolling
861 /* mUPOpenControl initializes a user pane control so it will be drawn
862 and will behave as a scrolling text edit field inside of a window.
863 This routine performs all of the initialization steps necessary,
864 except it does not create the user pane control itself. theControl
865 should refer to a user pane control that you have either created
866 yourself or extracted from a dialog's control heirarchy using
867 the GetDialogItemAsControl routine. */
868 OSStatus
mUPOpenControl(ControlHandle theControl
);
870 /* mUPCloseControl deallocates all of the structures allocated
871 by mUPOpenControl. */
872 OSStatus
mUPCloseControl(ControlHandle theControl
);
876 /* routines for creating new scrolling text user pane controls.
877 These routines allow you to create new scrolling text
878 user pane controls. */
880 /* mUPCreateControl creates a new user pane control and then it passes it
881 to mUPOpenControl to initialize it as a scrolling text user pane control. */
882 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
);
884 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
885 OSStatus
mUPDisposeControl(ControlHandle theControl
);
888 /* Utility Routines */
890 /* mUPSetText replaces the contents of the selection with the unicode
891 text described by the text and count parameters:.
892 text = pointer to unicode text buffer
893 count = number of bytes in the buffer. */
894 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
);
896 /* mUPGetText returns the current text data being displayed inside of
897 the mUPControl. When noErr is returned, *theText contain a new
898 handle containing all of the Unicode text copied from the current
899 selection. It is the caller's responsibiliby to dispose of this handle. */
900 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
);
903 /* mUPSetSelection sets the text selection and autoscrolls the text view
904 so either the cursor or the selction is in the view. */
905 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
);
909 /* IsmUPControl returns true if theControl is not NULL
910 and theControl refers to a mUP Control. */
911 Boolean
IsmUPControl(ControlHandle theControl
);
915 /* Edit commands for mUP Controls. */
924 /* mUPDoEditCommand performs the editing command specified
925 in the editCommand parameter. The mUPControl's text
926 and scroll bar are redrawn and updated as necessary. */
927 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
);
932 /* mUPGetContents returns the entire contents of the control including the text
933 and the formatting information. */
934 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
);
935 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
936 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
);
942 /* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
943 routine. In our focus switching routine this part code is understood
944 as meaning 'the user has clicked in the control and we need to switch
945 the current focus to ourselves before we can continue'. */
946 #define kUserClickedToFocusPart 100
949 /* kmUPClickScrollDelayTicks is a time measurement in ticks used to
950 slow the speed of 'auto scrolling' inside of our clickloop routine.
951 This value prevents the text from wizzzzzing by while the mouse
952 is being held down inside of the text area. */
953 #define kmUPClickScrollDelayTicks 3
956 /* STPTextPaneVars is a structure used for storing the the mUP Control's
957 internal variables and state information. A handle to this record is
958 stored in the pane control's reference value field using the
959 SetControlReference routine. */
962 /* OS records referenced */
963 TXNObject fTXNRec
; /* the txn record */
964 TXNFrameID fTXNFrame
; /* the txn frame ID */
965 ControlHandle fUserPaneRec
; /* handle to the user pane control */
966 WindowPtr fOwner
; /* window containing control */
967 GrafPtr fDrawingEnvironment
; /* grafport where control is drawn */
969 Boolean fInFocus
; /* true while the focus rect is drawn around the control */
970 Boolean fIsActive
; /* true while the control is drawn in the active state */
971 Boolean fTEActive
; /* reflects the activation state of the text edit record */
972 Boolean fInDialogWindow
; /* true if displayed in a dialog window */
973 /* calculated locations */
974 Rect fRTextArea
; /* area where the text is drawn */
975 Rect fRFocusOutline
; /* rectangle used to draw the focus box */
976 Rect fRTextOutline
; /* rectangle used to draw the border */
977 RgnHandle fTextBackgroundRgn
; /* background region for the text, erased before calling TEUpdate */
978 /* our focus advance override routine */
979 EventHandlerUPP handlerUPP
;
980 EventHandlerRef handlerRef
;
986 /* Univerals Procedure Pointer variables used by the
987 mUP Control. These variables are set up
988 the first time that mUPOpenControl is called. */
989 ControlUserPaneDrawUPP gTPDrawProc
= NULL
;
990 ControlUserPaneHitTestUPP gTPHitProc
= NULL
;
991 ControlUserPaneTrackingUPP gTPTrackProc
= NULL
;
992 ControlUserPaneIdleUPP gTPIdleProc
= NULL
;
993 ControlUserPaneKeyDownUPP gTPKeyProc
= NULL
;
994 ControlUserPaneActivateUPP gTPActivateProc
= NULL
;
995 ControlUserPaneFocusUPP gTPFocusProc
= NULL
;
997 /* events handled by our focus advance override routine */
999 static const EventTypeSpec gMLTEEvents
[] = { { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} };
1000 #define kMLTEEventCount (sizeof( gMLTEEvents ) / sizeof( EventTypeSpec ))
1004 /* TPActivatePaneText activates or deactivates the text edit record
1005 according to the value of setActive. The primary purpose of this
1006 routine is to ensure each call is only made once. */
1007 static void TPActivatePaneText(STPTextPaneVars
**tpvars
, Boolean setActive
) {
1008 STPTextPaneVars
*varsp
;
1010 if (varsp
->fTEActive
!= setActive
) {
1012 varsp
->fTEActive
= setActive
;
1014 TXNActivate(varsp
->fTXNRec
, varsp
->fTXNFrame
, varsp
->fTEActive
);
1016 if (varsp
->fInFocus
)
1017 TXNFocus( varsp
->fTXNRec
, varsp
->fTEActive
);
1022 /* TPFocusPaneText set the focus state for the text record. */
1023 static void TPFocusPaneText(STPTextPaneVars
**tpvars
, Boolean setFocus
) {
1024 STPTextPaneVars
*varsp
;
1026 if (varsp
->fInFocus
!= setFocus
) {
1027 varsp
->fInFocus
= setFocus
;
1028 TXNFocus( varsp
->fTXNRec
, varsp
->fInFocus
);
1033 /* TPPaneDrawProc is called to redraw the control and for update events
1034 referring to the control. This routine erases the text area's background,
1035 and redraws the text. This routine assumes the scroll bar has been
1036 redrawn by a call to DrawControls. */
1037 static pascal void TPPaneDrawProc(ControlRef theControl
, ControlPartCode thePart
) {
1038 STPTextPaneVars
**tpvars
, *varsp
;
1041 /* set up our globals */
1042 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1043 if (tpvars
!= NULL
) {
1044 state
= HGetState((Handle
) tpvars
);
1045 HLock((Handle
) tpvars
);
1048 /* save the drawing state */
1049 SetPort((**tpvars
).fDrawingEnvironment
);
1050 /* verify our boundary */
1051 GetControlBounds(theControl
, &bounds
);
1052 if ( ! EqualRect(&bounds
, &varsp
->fRTextArea
) ) {
1053 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1054 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1055 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1056 RectRgn(varsp
->fTextBackgroundRgn
, &varsp
->fRTextOutline
);
1057 TXNSetFrameBounds( varsp
->fTXNRec
, bounds
.top
, bounds
.left
, bounds
.bottom
, bounds
.right
, varsp
->fTXNFrame
);
1060 /* update the text region */
1061 EraseRgn(varsp
->fTextBackgroundRgn
);
1062 TXNDraw(varsp
->fTXNRec
, NULL
);
1063 /* restore the drawing environment */
1064 /* draw the text frame and focus frame (if necessary) */
1065 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1066 if ((**tpvars
).fIsActive
&& varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, true);
1067 /* release our globals */
1068 HSetState((Handle
) tpvars
, state
);
1073 /* TPPaneHitTestProc is called when the control manager would
1074 like to determine what part of the control the mouse resides over.
1075 We also call this routine from our tracking proc to determine how
1076 to handle mouse clicks. */
1077 static pascal ControlPartCode
TPPaneHitTestProc(ControlHandle theControl
, Point where
) {
1078 STPTextPaneVars
**tpvars
;
1079 ControlPartCode result
;
1081 /* set up our locals and lock down our globals*/
1083 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1084 if (tpvars
!= NULL
) {
1085 state
= HGetState((Handle
) tpvars
);
1086 HLock((Handle
) tpvars
);
1087 /* find the region where we clicked */
1088 if (PtInRect(where
, &(**tpvars
).fRTextArea
)) {
1089 result
= kmUPTextPart
;
1091 /* release oure globals */
1092 HSetState((Handle
) tpvars
, state
);
1101 /* TPPaneTrackingProc is called when the mouse is being held down
1102 over our control. This routine handles clicks in the text area
1103 and in the scroll bar. */
1104 static pascal ControlPartCode
TPPaneTrackingProc(ControlHandle theControl
, Point startPt
, ControlActionUPP actionProc
) {
1105 STPTextPaneVars
**tpvars
, *varsp
;
1107 ControlPartCode partCodeResult
;
1108 /* make sure we have some variables... */
1110 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1111 if (tpvars
!= NULL
) {
1113 state
= HGetState((Handle
) tpvars
);
1114 HLock((Handle
) tpvars
);
1116 /* we don't do any of these functions unless we're in focus */
1117 if ( ! varsp
->fInFocus
) {
1119 owner
= GetControlOwner(theControl
);
1120 ClearKeyboardFocus(owner
);
1121 SetKeyboardFocus(owner
, theControl
, kUserClickedToFocusPart
);
1123 /* find the location for the click */
1124 switch (TPPaneHitTestProc(theControl
, startPt
)) {
1126 /* handle clicks in the text part */
1128 { SetPort((**tpvars
).fDrawingEnvironment
);
1129 TXNClick( varsp
->fTXNRec
, GetCurrentEventRecord());
1135 HSetState((Handle
) tpvars
, state
);
1137 return partCodeResult
;
1141 /* TPPaneIdleProc is our user pane idle routine. When our text field
1142 is active and in focus, we use this routine to set the cursor. */
1143 static pascal void TPPaneIdleProc(ControlHandle theControl
) {
1144 STPTextPaneVars
**tpvars
, *varsp
;
1146 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1147 if (tpvars
!= NULL
) {
1148 /* if we're not active, then we have nothing to say about the cursor */
1149 if ((**tpvars
).fIsActive
) {
1153 /* lock down the globals */
1154 state
= HGetState((Handle
) tpvars
);
1155 HLock((Handle
) tpvars
);
1157 /* get the current mouse coordinates (in our window) */
1159 SetPort(GetWindowPort(GetControlOwner(theControl
)));
1161 SetPort((GrafPtr
) GetWindowPort(GetControlOwner(theControl
)));
1164 /* there's a 'focus thing' and an 'unfocused thing' */
1165 if (varsp
->fInFocus
) {
1166 /* flash the cursor */
1167 SetPort((**tpvars
).fDrawingEnvironment
);
1168 TXNIdle(varsp
->fTXNRec
);
1169 /* set the cursor */
1170 if (PtInRect(mousep
, &varsp
->fRTextArea
)) {
1172 RectRgn((theRgn
= NewRgn()), &varsp
->fRTextArea
);
1173 TXNAdjustCursor(varsp
->fTXNRec
, theRgn
);
1175 } else SetThemeCursor(kThemeArrowCursor
);
1177 /* if it's in our bounds, set the cursor */
1178 GetControlBounds(theControl
, &bounds
);
1179 if (PtInRect(mousep
, &bounds
))
1180 SetThemeCursor(kThemeArrowCursor
);
1183 HSetState((Handle
) tpvars
, state
);
1189 /* TPPaneKeyDownProc is called whenever a keydown event is directed
1190 at our control. Here, we direct the keydown event to the text
1191 edit record and redraw the scroll bar and text field as appropriate. */
1192 static pascal ControlPartCode
TPPaneKeyDownProc(ControlHandle theControl
,
1193 SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
) {
1194 STPTextPaneVars
**tpvars
;
1195 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1196 if (tpvars
!= NULL
) {
1197 if ((**tpvars
).fInFocus
) {
1198 /* turn autoscrolling on and send the key event to text edit */
1199 SetPort((**tpvars
).fDrawingEnvironment
);
1200 TXNKeyDown( (**tpvars
).fTXNRec
, GetCurrentEventRecord());
1203 return kControlEntireControl
;
1207 /* TPPaneActivateProc is called when the window containing
1208 the user pane control receives activate events. Here, we redraw
1209 the control and it's text as necessary for the activation state. */
1210 static pascal void TPPaneActivateProc(ControlHandle theControl
, Boolean activating
) {
1212 STPTextPaneVars
**tpvars
, *varsp
;
1215 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1216 if (tpvars
!= NULL
) {
1217 state
= HGetState((Handle
) tpvars
);
1218 HLock((Handle
) tpvars
);
1220 /* de/activate the text edit record */
1221 SetPort((**tpvars
).fDrawingEnvironment
);
1222 GetControlBounds(theControl
, &bounds
);
1223 varsp
->fIsActive
= activating
;
1224 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1225 /* redraw the frame */
1226 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1227 if (varsp
->fInFocus
) DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
);
1228 HSetState((Handle
) tpvars
, state
);
1233 /* TPPaneFocusProc is called when every the focus changes to or
1234 from our control. Herein, switch the focus appropriately
1235 according to the parameters and redraw the control as
1237 static pascal ControlPartCode
TPPaneFocusProc(ControlHandle theControl
, ControlFocusPart action
) {
1238 ControlPartCode focusResult
;
1239 STPTextPaneVars
**tpvars
, *varsp
;
1242 focusResult
= kControlFocusNoPart
;
1243 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1244 if (tpvars
!= NULL
) {
1245 state
= HGetState((Handle
) tpvars
);
1246 HLock((Handle
) tpvars
);
1248 /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
1249 tabbing forwards (or shift tabbing backwards) through the items in the dialog,
1250 and kControlFocusNextPart will be received. When the user clicks in our field
1251 and it is not the current focus, then the constant kUserClickedToFocusPart will
1252 be received. The constant kControlFocusNoPart will be received when our control
1253 is the current focus and the user clicks in another control. In your focus routine,
1254 you should respond to these codes as follows:
1256 kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
1257 the control and the focus rectangle as necessary.
1259 kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
1260 depending on its current state. redraw the control and the focus rectangle
1261 as appropriate for the new focus state. If the focus state is 'off', return the constant
1262 kControlFocusNoPart, otherwise return a non-zero part code.
1263 kUserClickedToFocusPart - is a constant defined for this example. You should
1264 define your own value for handling click-to-focus type events. */
1265 /* save the drawing state */
1266 SetPort((**tpvars
).fDrawingEnvironment
);
1267 /* calculate the next highlight state */
1270 case kControlFocusNoPart
:
1271 TPFocusPaneText(tpvars
, false);
1272 focusResult
= kControlFocusNoPart
;
1274 case kUserClickedToFocusPart
:
1275 TPFocusPaneText(tpvars
, true);
1278 case kControlFocusPrevPart
:
1279 case kControlFocusNextPart
:
1280 TPFocusPaneText(tpvars
, ( ! varsp
->fInFocus
));
1281 focusResult
= varsp
->fInFocus
? 1 : kControlFocusNoPart
;
1284 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1285 /* redraw the text fram and focus rectangle to indicate the
1287 DrawThemeEditTextFrame(&varsp
->fRTextOutline
, varsp
->fIsActive
? kThemeStateActive
: kThemeStateInactive
);
1288 DrawThemeFocusRect(&varsp
->fRFocusOutline
, varsp
->fIsActive
&& varsp
->fInFocus
);
1290 HSetState((Handle
) tpvars
, state
);
1305 //This our carbon event handler for unicode key downs
1307 static pascal OSStatus
FocusAdvanceOverride(EventHandlerCallRef myHandler
, EventRef event
, void* userData
) {
1309 STPTextPaneVars
**tpvars
;
1311 unsigned short mUnicodeText
;
1312 ByteCount charCounts
=0;
1313 /* get our window pointer */
1314 tpvars
= (STPTextPaneVars
**) userData
;
1315 window
= (**tpvars
).fOwner
;
1316 //find out how many bytes are needed
1317 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1318 typeUnicodeText
, NULL
, 0, &charCounts
, NULL
);
1319 if (err
!= noErr
) goto bail
;
1320 /* we're only looking at single characters */
1321 if (charCounts
!= 2) { err
= eventNotHandledErr
; goto bail
; }
1322 /* get the character */
1323 err
= GetEventParameter(event
, kEventParamTextInputSendText
,
1324 typeUnicodeText
, NULL
, sizeof(mUnicodeText
),
1325 &charCounts
, (char*) &mUnicodeText
);
1326 if (err
!= noErr
) goto bail
;
1327 /* if it's not the tab key, forget it... */
1328 if ((mUnicodeText
!= '\t')) { err
= eventNotHandledErr
; goto bail
; }
1329 /* advance the keyboard focus */
1330 AdvanceKeyboardFocus(window
);
1331 /* noErr lets the CEM know we handled the event */
1334 return eventNotHandledErr
;
1339 /* mUPOpenControl initializes a user pane control so it will be drawn
1340 and will behave as a scrolling text edit field inside of a window.
1341 This routine performs all of the initialization steps necessary,
1342 except it does not create the user pane control itself. theControl
1343 should refer to a user pane control that you have either created
1344 yourself or extracted from a dialog's control heirarchy using
1345 the GetDialogItemAsControl routine. */
1346 OSStatus
mUPOpenControl(ControlHandle theControl
, bool multiline
) {
1348 WindowPtr theWindow
;
1349 STPTextPaneVars
**tpvars
, *varsp
;
1351 RGBColor rgbWhite
= {0xFFFF, 0xFFFF, 0xFFFF};
1352 TXNBackground tback
;
1354 /* set up our globals */
1355 if (gTPDrawProc
== NULL
) gTPDrawProc
= NewControlUserPaneDrawUPP(TPPaneDrawProc
);
1356 if (gTPHitProc
== NULL
) gTPHitProc
= NewControlUserPaneHitTestUPP(TPPaneHitTestProc
);
1357 if (gTPTrackProc
== NULL
) gTPTrackProc
= NewControlUserPaneTrackingUPP(TPPaneTrackingProc
);
1358 if (gTPIdleProc
== NULL
) gTPIdleProc
= NewControlUserPaneIdleUPP(TPPaneIdleProc
);
1359 if (gTPKeyProc
== NULL
) gTPKeyProc
= NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc
);
1360 if (gTPActivateProc
== NULL
) gTPActivateProc
= NewControlUserPaneActivateUPP(TPPaneActivateProc
);
1361 if (gTPFocusProc
== NULL
) gTPFocusProc
= NewControlUserPaneFocusUPP(TPPaneFocusProc
);
1363 /* allocate our private storage */
1364 tpvars
= (STPTextPaneVars
**) NewHandleClear(sizeof(STPTextPaneVars
));
1365 SetControlReference(theControl
, (long) tpvars
);
1366 HLock((Handle
) tpvars
);
1368 /* set the initial settings for our private data */
1369 varsp
->fInFocus
= false;
1370 varsp
->fIsActive
= true;
1371 varsp
->fTEActive
= false;
1372 varsp
->fUserPaneRec
= theControl
;
1373 theWindow
= varsp
->fOwner
= GetControlOwner(theControl
);
1375 varsp
->fDrawingEnvironment
= GetWindowPort(varsp
->fOwner
);
1377 varsp
->fDrawingEnvironment
= (GrafPtr
) GetWindowPort(varsp
->fOwner
);
1379 varsp
->fInDialogWindow
= ( GetWindowKind(varsp
->fOwner
) == kDialogWindowKind
);
1380 /* set up the user pane procedures */
1381 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneDrawProcTag
, sizeof(gTPDrawProc
), &gTPDrawProc
);
1382 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneHitTestProcTag
, sizeof(gTPHitProc
), &gTPHitProc
);
1383 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneTrackingProcTag
, sizeof(gTPTrackProc
), &gTPTrackProc
);
1384 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneIdleProcTag
, sizeof(gTPIdleProc
), &gTPIdleProc
);
1385 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneKeyDownProcTag
, sizeof(gTPKeyProc
), &gTPKeyProc
);
1386 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneActivateProcTag
, sizeof(gTPActivateProc
), &gTPActivateProc
);
1387 SetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
, sizeof(gTPFocusProc
), &gTPFocusProc
);
1388 /* calculate the rectangles used by the control */
1389 GetControlBounds(theControl
, &bounds
);
1390 SetRect(&varsp
->fRFocusOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1391 SetRect(&varsp
->fRTextOutline
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1392 SetRect(&varsp
->fRTextArea
, bounds
.left
, bounds
.top
, bounds
.right
, bounds
.bottom
);
1393 /* calculate the background region for the text. In this case, it's kindof
1394 and irregular region because we're setting the scroll bar a little ways inside
1395 of the text area. */
1396 RectRgn((varsp
->fTextBackgroundRgn
= NewRgn()), &varsp
->fRTextOutline
);
1398 /* set up the drawing environment */
1399 SetPort(varsp
->fDrawingEnvironment
);
1401 /* create the new edit field */
1402 TXNNewObject(NULL
, varsp
->fOwner
, &varsp
->fRTextArea
,
1403 kTXNWantVScrollBarMask
| kTXNAlwaysWrapAtViewEdgeMask
,
1404 kTXNTextEditStyleFrameType
,
1406 kTXNSystemDefaultEncoding
,
1407 &varsp
->fTXNRec
, &varsp
->fTXNFrame
, (TXNObjectRefcon
) tpvars
);
1409 /* set the field's background */
1410 tback
.bgType
= kTXNBackgroundTypeRGB
;
1411 tback
.bg
.color
= rgbWhite
;
1412 TXNSetBackground( varsp
->fTXNRec
, &tback
);
1414 /* install our focus advance override routine */
1416 varsp
->handlerUPP
= NewEventHandlerUPP(FocusAdvanceOverride
);
1417 err
= InstallWindowEventHandler( varsp
->fOwner
, varsp
->handlerUPP
,
1418 kMLTEEventCount
, gMLTEEvents
, tpvars
, &varsp
->handlerRef
);
1420 /* unlock our storage */
1421 HUnlock((Handle
) tpvars
);
1422 /* perform final activations and setup for our text field. Here,
1423 we assume that the window is going to be the 'active' window. */
1424 TPActivatePaneText(tpvars
, varsp
->fIsActive
&& varsp
->fInFocus
);
1431 /* mUPCloseControl deallocates all of the structures allocated
1432 by mUPOpenControl. */
1433 OSStatus
mUPCloseControl(ControlHandle theControl
) {
1434 STPTextPaneVars
**tpvars
;
1436 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1437 /* release our sub records */
1438 TXNDeleteObject((**tpvars
).fTXNRec
);
1439 /* remove our focus advance override */
1440 RemoveEventHandler((**tpvars
).handlerRef
);
1441 DisposeEventHandlerUPP((**tpvars
).handlerUPP
);
1442 /* delete our private storage */
1443 DisposeHandle((Handle
) tpvars
);
1444 /* zero the control reference */
1445 SetControlReference(theControl
, 0);
1452 /* mUPSetText replaces the contents of the selection with the unicode
1453 text described by the text and count parameters:.
1454 text = pointer to unicode text buffer
1455 count = number of bytes in the buffer. */
1456 OSStatus
mUPSetText(ControlHandle theControl
, char* text
, long count
) {
1457 STPTextPaneVars
**tpvars
;
1459 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1460 /* set the text in the record */
1461 return TXNSetData( (**tpvars
).fTXNRec
, kTXNUnicodeTextData
, text
, count
,
1462 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1468 /* mUPSetSelection sets the text selection and autoscrolls the text view
1469 so either the cursor or the selction is in the view. */
1470 void mUPSetSelection(ControlHandle theControl
, long selStart
, long selEnd
) {
1471 STPTextPaneVars
**tpvars
;
1472 /* set up our locals */
1473 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1474 /* and our drawing environment as the operation
1475 may force a redraw in the text area. */
1476 SetPort((**tpvars
).fDrawingEnvironment
);
1477 /* change the selection */
1478 TXNSetSelection( (**tpvars
).fTXNRec
, selStart
, selEnd
);
1485 /* mUPGetText returns the current text data being displayed inside of
1486 the mUPControl. When noErr is returned, *theText contain a new
1487 handle containing all of the Unicode text copied from the current
1488 selection. It is the caller's responsibiliby to dispose of this handle. */
1489 OSStatus
mUPGetText(ControlHandle theControl
, Handle
*theText
) {
1490 STPTextPaneVars
**tpvars
;
1493 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1494 /* extract the text from the record */
1495 err
= TXNGetData( (**tpvars
).fTXNRec
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
, theText
);
1502 /* mUPCreateControl creates a new user pane control and then it passes it
1503 to mUPOpenControl to initialize it as a scrolling text user pane control. */
1504 OSStatus
mUPCreateControl(WindowPtr theWindow
, Rect
*bounds
, ControlHandle
*theControl
) {
1506 /* the following feature set can be specified in CNTL resources by using
1507 the value 1214. When creating a user pane control, we pass this value
1508 in the 'value' parameter. */
1509 featurSet
= kControlSupportsEmbedding
| kControlSupportsFocus
| kControlWantsIdle
1510 | kControlWantsActivate
| kControlHandlesTracking
| kControlHasSpecialBackground
1511 | kControlGetsFocusOnClick
| kControlSupportsLiveFeedback
;
1512 /* create the control */
1513 *theControl
= NewControl(theWindow
, bounds
, "\p", true, featurSet
, 0, featurSet
, kControlUserPaneProc
, 0);
1514 /* set up the mUP specific features and data */
1515 mUPOpenControl(*theControl
);
1521 /* mUPDisposeControl calls mUPCloseControl and then it calls DisposeControl. */
1522 OSStatus
mUPDisposeControl(ControlHandle theControl
) {
1523 /* deallocate the mUP specific data */
1524 mUPCloseControl(theControl
);
1525 /* deallocate the user pane control itself */
1526 DisposeControl(theControl
);
1533 /* IsmUPControl returns true if theControl is not NULL
1534 and theControl refers to a mUP Control. */
1535 Boolean
IsmUPControl(ControlHandle theControl
) {
1537 ControlUserPaneFocusUPP localFocusProc
;
1538 /* a NULL control is not a mUP control */
1539 if (theControl
== NULL
) return false;
1540 /* check if the control is using our focus procedure */
1541 theSize
= sizeof(localFocusProc
);
1542 if (GetControlData(theControl
, kControlEntireControl
, kControlUserPaneFocusProcTag
,
1543 sizeof(localFocusProc
), &localFocusProc
, &theSize
) != noErr
) return false;
1544 if (localFocusProc
!= gTPFocusProc
) return false;
1545 /* all tests passed, it's a mUP control */
1550 /* mUPDoEditCommand performs the editing command specified
1551 in the editCommand parameter. The mUPControl's text
1552 and scroll bar are redrawn and updated as necessary. */
1553 void mUPDoEditCommand(ControlHandle theControl
, short editCommand
) {
1554 STPTextPaneVars
**tpvars
;
1555 /* set up our locals */
1556 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1557 /* and our drawing environment as the operation
1558 may force a redraw in the text area. */
1559 SetPort((**tpvars
).fDrawingEnvironment
);
1560 /* perform the editing command */
1561 switch (editCommand
) {
1563 ClearCurrentScrap();
1564 TXNCut((**tpvars
).fTXNRec
);
1565 TXNConvertToPublicScrap();
1568 ClearCurrentScrap();
1569 TXNCopy((**tpvars
).fTXNRec
);
1570 TXNConvertToPublicScrap();
1573 TXNConvertFromPublicScrap();
1574 TXNPaste((**tpvars
).fTXNRec
);
1577 TXNClear((**tpvars
).fTXNRec
);
1585 /* mUPGetContents returns the entire contents of the control including the text
1586 and the formatting information. */
1587 OSStatus
mUPGetContents(ControlHandle theControl
, Handle
*theContents
) {
1588 STPTextPaneVars
**tpvars
;
1601 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1602 if (theContents
== NULL
) return paramErr
;
1603 /* create a temporary file */
1604 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1605 if (err
!= noErr
) goto bail
;
1606 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPGetContents", &tspec
);
1607 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1608 if (err
!= noErr
) goto bail
;
1611 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1612 if (err
!= noErr
) goto bail
;
1614 err
= TXNSave( (**tpvars
).fTXNRec
, kTXNTextensionFile
, 0, kTXNSystemDefaultEncoding
, &tspec
, trefnum
, 0);
1615 if (err
!= noErr
) goto bail
;
1616 /* get the file length and set the position */
1617 err
= GetEOF(trefnum
, &bytecount
);
1618 if (err
!= noErr
) goto bail
;
1619 err
= SetFPos(trefnum
, fsFromStart
, 0);
1620 if (err
!= noErr
) goto bail
;
1621 /* copy the data fork to a handle */
1622 localdata
= NewHandle(bytecount
);
1623 if (localdata
== NULL
) { err
= memFullErr
; goto bail
; }
1625 err
= FSRead(trefnum
, &bytecount
, *localdata
);
1627 if (err
!= noErr
) goto bail
;
1629 *theContents
= localdata
;
1636 if (trefnum
!= 0) FSClose(trefnum
);
1637 if (texists
) FSpDelete(&tspec
);
1638 if (localdata
!= NULL
) DisposeHandle(localdata
);
1645 /* mUPSetContents replaces the contents of the selection with the data stored in the handle. */
1646 OSStatus
mUPSetContents(ControlHandle theControl
, Handle theContents
) {
1647 STPTextPaneVars
**tpvars
;
1659 tpvars
= (STPTextPaneVars
**) GetControlReference(theControl
);
1660 if (theContents
== NULL
) return paramErr
;
1661 /* create a temporary file */
1662 err
= FindFolder(kOnSystemDisk
, kTemporaryFolderType
, true, &vRefNum
, &dirID
);
1663 if (err
!= noErr
) goto bail
;
1664 FSMakeFSSpec(vRefNum
, dirID
, "\pmUPSetContents", &tspec
);
1665 err
= FSpCreate(&tspec
, 'trsh', 'trsh', smSystemScript
);
1666 if (err
!= noErr
) goto bail
;
1669 err
= FSpOpenDF(&tspec
, fsRdWrPerm
, &trefnum
);
1670 if (err
!= noErr
) goto bail
;
1671 /* save the data to the temporary file */
1672 state
= HGetState(theContents
);
1674 bytecount
= GetHandleSize(theContents
);
1675 err
= FSWrite(trefnum
, &bytecount
, *theContents
);
1676 HSetState(theContents
, state
);
1677 if (err
!= noErr
) goto bail
;
1678 /* reset the file position */
1679 err
= SetFPos(trefnum
, fsFromStart
, 0);
1680 if (err
!= noErr
) goto bail
;
1682 err
= TXNSetDataFromFile((**tpvars
).fTXNRec
, trefnum
, kTXNTextensionFile
, bytecount
, kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
1683 if (err
!= noErr
) goto bail
;
1690 if (trefnum
!= 0) FSClose(trefnum
);
1691 if (texists
) FSpDelete(&tspec
);
1695 #if !USE_SHARED_LIBRARY
1696 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
1698 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
1699 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
1700 EVT_CHAR(wxTextCtrl::OnChar
)
1701 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
1702 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
1703 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
1704 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
1705 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
1707 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
1708 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
1709 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
1710 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
1711 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
1716 wxTextCtrl::wxTextCtrl()
1720 const short kVerticalMargin
= 2 ;
1721 const short kHorizontalMargin
= 2 ;
1723 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1726 const wxSize
& size
, long style
,
1727 const wxValidator
& validator
,
1728 const wxString
& name
)
1730 // base initialization
1731 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
1734 wxSize mySize
= size
;
1735 if ( UMAHasAppearance() )
1737 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
1738 m_macVerticalBorder
= 5 ;
1742 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
1743 m_macVerticalBorder
= 0 ;
1750 if ( mySize
.y
== -1 )
1752 if ( UMAHasAppearance() )
1757 mySize
.y
+= 2 * m_macVerticalBorder
;
1760 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
1762 if ( m_windowStyle
& wxTE_MULTILINE
)
1764 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
1765 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
1767 m_windowStyle
|= wxTE_PROCESS_ENTER
;
1771 if ( style
& wxTE_PASSWORD
)
1773 m_macControl
= ::NewControl( parent
->MacGetRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
1774 kControlEditTextPasswordProc
, (long) this ) ;
1778 if ( mUPCreateControl(parent
->MacGetRootWindow(), &bounds
, &m_macControl
) != noErr
)
1781 MacPostControlCreate() ;
1785 if( wxApp::s_macDefaultEncodingIsPC
)
1786 value
= wxMacMakeMacStringFromPC( st
) ;
1790 if ( style
& wxTE_PASSWORD
)
1792 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1796 STPTextPaneVars
**tpvars
;
1798 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1799 /* set the text in the record */
1800 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1801 kTXNStartOffset
, kTXNEndOffset
);
1807 wxString
wxTextCtrl::GetValue() const
1810 if ( m_windowStyle
& wxTE_PASSWORD
)
1812 ::GetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
1816 STPTextPaneVars
**tpvars
;
1819 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1820 /* extract the text from the record */
1822 err
= TXNGetDataEncoded( (**tpvars
).fTXNRec
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
1830 actualsize
= GetHandleSize( theText
) ;
1831 strncpy( wxBuffer
, *theText
, actualsize
) ;
1832 DisposeHandle( theText
) ;
1835 wxBuffer
[actualsize
] = 0 ;
1836 if( wxApp::s_macDefaultEncodingIsPC
)
1837 return wxMacMakePCStringFromMac( wxBuffer
) ;
1839 return wxString(wxBuffer
);
1842 void wxTextCtrl::GetSelection(long* from
, long* to
) const
1844 if ( m_windowStyle
& wxTE_PASSWORD
)
1846 ControlEditTextSelectionRec selection
;
1850 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1852 *from
= (**teH
).selStart
;
1853 *to
= (**teH
).selEnd
;
1857 STPTextPaneVars
**tpvars
;
1860 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1862 TXNGetSelection( (**tpvars
).fTXNRec
, (TXNOffset
*) from
, (TXNOffset
*) to
) ;
1867 void wxTextCtrl::SetValue(const wxString
& st
)
1871 if( wxApp::s_macDefaultEncodingIsPC
)
1872 value
= wxMacMakeMacStringFromPC( st
) ;
1875 if ( m_windowStyle
& wxTE_PASSWORD
)
1877 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
1881 STPTextPaneVars
**tpvars
;
1883 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
1884 /* set the text in the record */
1885 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
1886 kTXNStartOffset
, kTXNEndOffset
);
1888 WindowRef window
= MacGetRootWindow() ;
1891 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1894 wxMacDrawingHelper
help( win
) ;
1895 // the mac control manager always assumes to have the origin at 0,0
1897 bool hasTabBehind
= false ;
1898 wxWindow
* parent
= GetParent() ;
1901 if( parent
->MacGetWindowData() )
1903 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
1907 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
1909 if ( ((wxControl
*)parent
)->GetMacControl() )
1910 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
1914 parent
= parent
->GetParent() ;
1917 UMADrawControl( m_macControl
) ;
1918 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
1923 // Clipboard operations
1924 void wxTextCtrl::Copy()
1928 if ( m_windowStyle
& wxTE_PASSWORD
)
1933 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1935 ClearCurrentScrap();
1940 mUPDoEditCommand( m_macControl
, kmUPCopy
) ;
1945 void wxTextCtrl::Cut()
1949 if ( m_windowStyle
& wxTE_PASSWORD
)
1954 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1956 ClearCurrentScrap();
1958 // MacInvalidateControl() ;
1962 mUPDoEditCommand( m_macControl
, kmUPCut
) ;
1967 void wxTextCtrl::Paste()
1971 if ( m_windowStyle
& wxTE_PASSWORD
)
1976 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
1979 WindowRef window
= MacGetRootWindow() ;
1982 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
1985 wxMacDrawingHelper
help( win
) ;
1986 // the mac control manager always assumes to have the origin at 0,0
1987 bool hasTabBehind
= false ;
1988 wxWindow
* parent
= GetParent() ;
1991 if( parent
->MacGetWindowData() )
1993 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
1997 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
1999 if ( ((wxControl
*)parent
)->GetMacControl() )
2000 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
2004 parent
= parent
->GetParent() ;
2007 UMADrawControl( m_macControl
) ;
2008 ::SetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
2014 mUPDoEditCommand( m_macControl
, kmUPPaste
) ;
2019 bool wxTextCtrl::CanCopy() const
2021 // Can copy if there's a selection
2023 GetSelection(& from
, & to
);
2024 return (from
!= to
);
2027 bool wxTextCtrl::CanCut() const
2029 // Can cut if there's a selection
2031 GetSelection(& from
, & to
);
2032 return (from
!= to
);
2035 bool wxTextCtrl::CanPaste() const
2042 OSStatus err
= noErr
;
2045 err
= GetCurrentScrap( &scrapRef
);
2046 if ( err
!= noTypeErr
&& err
!= memFullErr
)
2048 ScrapFlavorFlags flavorFlags
;
2051 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
2053 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
2062 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
2070 void wxTextCtrl::SetEditable(bool editable
)
2073 UMAActivateControl( m_macControl
) ;
2075 UMADeactivateControl( m_macControl
) ;
2078 void wxTextCtrl::SetInsertionPoint(long pos
)
2080 SetSelection( pos
, pos
) ;
2083 void wxTextCtrl::SetInsertionPointEnd()
2085 long pos
= GetLastPosition();
2086 SetInsertionPoint(pos
);
2089 long wxTextCtrl::GetInsertionPoint() const
2092 GetSelection( &begin
, &end
) ;
2096 long wxTextCtrl::GetLastPosition() const
2098 if ( m_windowStyle
& wxTE_PASSWORD
)
2101 ControlEditTextSelectionRec selection
;
2105 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2107 // ::GetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
2108 return (**teH
).teLength
;
2112 STPTextPaneVars
** tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2114 int actualsize
= 0 ;
2116 OSErr err
= TXNGetDataEncoded( (**tpvars
).fTXNRec
, kTXNStartOffset
, kTXNEndOffset
, &theText
, kTXNTextData
);
2124 actualsize
= GetHandleSize( theText
) ;
2125 DisposeHandle( theText
) ;
2131 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
2133 if ( m_windowStyle
& wxTE_PASSWORD
)
2138 ControlEditTextSelectionRec selection
;
2140 selection
.selStart
= from
;
2141 selection
.selEnd
= to
;
2142 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2143 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2144 TESetSelect( from
, to
, teH
) ;
2146 TEInsert( value
, value
.Length() , teH
) ;
2155 void wxTextCtrl::Remove(long from
, long to
)
2157 if ( m_windowStyle
& wxTE_PASSWORD
)
2162 ControlEditTextSelectionRec selection
;
2164 selection
.selStart
= from
;
2165 selection
.selEnd
= to
;
2166 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2167 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2177 void wxTextCtrl::SetSelection(long from
, long to
)
2179 if ( m_windowStyle
& wxTE_PASSWORD
)
2181 ControlEditTextSelectionRec selection
;
2185 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2187 selection
.selStart
= from
;
2188 selection
.selEnd
= to
;
2190 ::SetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
2191 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
2195 STPTextPaneVars
**tpvars
;
2196 /* set up our locals */
2197 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2198 /* and our drawing environment as the operation
2199 may force a redraw in the text area. */
2200 SetPort((**tpvars
).fDrawingEnvironment
);
2201 /* change the selection */
2202 TXNSetSelection( (**tpvars
).fTXNRec
, from
, to
);
2206 bool wxTextCtrl::LoadFile(const wxString
& file
)
2208 if ( wxTextCtrlBase::LoadFile(file
) )
2216 void wxTextCtrl::WriteText(const wxString
& text
)
2219 if( wxApp::s_macDefaultEncodingIsPC
)
2220 value
= wxMacMakeMacStringFromPC( text
) ;
2223 if ( m_windowStyle
& wxTE_PASSWORD
)
2228 ::GetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
2229 TEInsert( value
, value
.Length() , teH
) ;
2233 STPTextPaneVars
**tpvars
;
2235 tpvars
= (STPTextPaneVars
**) GetControlReference(m_macControl
);
2236 /* set the text in the record */
2237 TXNSetData( (**tpvars
).fTXNRec
, kTXNTextData
, (const char*)value
, value
.Length(),
2238 kTXNUseCurrentSelection
, kTXNUseCurrentSelection
);
2243 void wxTextCtrl::AppendText(const wxString
& text
)
2245 SetInsertionPointEnd();
2249 void wxTextCtrl::Clear()
2251 if ( m_windowStyle
& wxTE_PASSWORD
)
2254 ::SetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
2258 mUPDoEditCommand( m_macControl
, kmUPClear
) ;
2263 bool wxTextCtrl::IsModified() const
2268 bool wxTextCtrl::IsEditable() const
2273 bool wxTextCtrl::AcceptsFocus() const
2275 // we don't want focus if we can't be edited
2276 return IsEditable() && wxControl::AcceptsFocus();
2279 wxSize
wxTextCtrl::DoGetBestSize() const
2284 if ( UMAHasAppearance() )
2288 hText
+= 2 * m_macHorizontalBorder
;
2291 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
2293 int wText = DEFAULT_ITEM_WIDTH;
2295 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
2297 return wxSize(wText, hText);
2299 if ( m_windowStyle
& wxTE_MULTILINE
)
2301 hText
*= wxMin(GetNumberOfLines(), 5);
2303 //else: for single line control everything is ok
2304 return wxSize(wText
, hText
);
2307 // ----------------------------------------------------------------------------
2309 // ----------------------------------------------------------------------------
2311 void wxTextCtrl::Undo()
2318 void wxTextCtrl::Redo()
2325 bool wxTextCtrl::CanUndo() const
2330 bool wxTextCtrl::CanRedo() const
2335 // Makes 'unmodified'
2336 void wxTextCtrl::DiscardEdits()
2341 int wxTextCtrl::GetNumberOfLines() const
2343 // TODO change this if possible to reflect real lines
2344 wxString content
= GetValue() ;
2347 for (int i
= 0; i
< content
.Length() ; i
++)
2349 if (content
[i
] == '\r') count
++;
2355 long wxTextCtrl::XYToPosition(long x
, long y
) const
2361 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
2366 void wxTextCtrl::ShowPosition(long pos
)
2371 int wxTextCtrl::GetLineLength(long lineNo
) const
2373 // TODO change this if possible to reflect real lines
2374 wxString content
= GetValue() ;
2378 for (int i
= 0; i
< content
.Length() ; i
++)
2380 if (count
== lineNo
)
2382 // Count chars in line then
2384 for (int j
= i
; j
< content
.Length(); j
++)
2387 if (content
[j
] == '\r') return count
;
2392 if (content
[i
] == '\r') count
++;
2397 wxString
wxTextCtrl::GetLineText(long lineNo
) const
2399 // TODO change this if possible to reflect real lines
2400 wxString content
= GetValue() ;
2404 for (int i
= 0; i
< content
.Length() ; i
++)
2406 if (count
== lineNo
)
2408 // Add chars in line then
2411 for (int j
= i
; j
< content
.Length(); j
++)
2413 if (content
[j
] == '\r')
2421 if (content
[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 while( parent
&& !parent
->IsTopLevel() && parent
->GetDefaultItem() == NULL
) {
2461 parent
= parent
->GetParent() ;
2463 if ( parent
&& parent
->GetDefaultItem() )
2465 wxButton
*def
= wxDynamicCast(parent
->GetDefaultItem(),
2467 if ( def
&& def
->IsEnabled() )
2469 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
2470 event
.SetEventObject(def
);
2471 def
->Command(event
);
2476 //else: multiline controls need Enter for themselves
2481 // always produce navigation event - even if we process TAB
2482 // ourselves the fact that we got here means that the user code
2483 // decided to skip processing of this TAB - probably to let it
2484 // do its default job.
2486 wxNavigationKeyEvent eventNav
;
2487 eventNav
.SetDirection(!event
.ShiftDown());
2488 eventNav
.SetWindowChange(event
.ControlDown());
2489 eventNav
.SetEventObject(this);
2491 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
2499 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
2502 keychar
= short(ev
->message
& charCodeMask
);
2503 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
2504 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
2505 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
|| event
.KeyCode() == WXK_DELETE
|| event
.KeyCode() == WXK_BACK
)
2507 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
2508 event
.SetString( GetValue() ) ;
2509 event
.SetEventObject( this );
2510 GetEventHandler()->ProcessEvent(event
);
2515 // ----------------------------------------------------------------------------
2516 // standard handlers for standard edit menu events
2517 // ----------------------------------------------------------------------------
2519 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
2524 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
2529 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
2534 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
2539 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
2544 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2546 event
.Enable( CanCut() );
2549 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2551 event
.Enable( CanCopy() );
2554 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2556 event
.Enable( CanPaste() );
2559 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2561 event
.Enable( CanUndo() );
2564 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2566 event
.Enable( CanRedo() );