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"
47 #if !USE_SHARED_LIBRARY
48 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
50 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
51 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
52 EVT_CHAR(wxTextCtrl::OnChar
)
53 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
54 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
55 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
56 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
57 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
59 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
60 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
61 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
62 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
63 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
68 wxTextCtrl::wxTextCtrl()
72 const short kVerticalMargin
= 2 ;
73 const short kHorizontalMargin
= 2 ;
75 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
78 const wxSize
& size
, long style
,
79 const wxValidator
& validator
,
82 // base initialization
83 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
86 wxSize mySize
= size
;
87 if ( UMAHasAppearance() )
89 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
90 m_macVerticalBorder
= 5 ;
94 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
95 m_macVerticalBorder
= 0 ;
102 if ( mySize
.y
== -1 )
104 if ( UMAHasAppearance() )
109 mySize
.y
+= 2 * m_macVerticalBorder
;
112 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
114 if ( m_windowStyle
& wxTE_MULTILINE
)
116 wxASSERT_MSG( !(m_windowStyle
& wxTE_PROCESS_ENTER
),
117 wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
119 m_windowStyle
|= wxTE_PROCESS_ENTER
;
123 m_macControl
= UMANewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
124 ( style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
125 MacPostControlCreate() ;
133 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
134 (*teH
)->lineHeight
= -1 ;
137 if( wxApp::s_macDefaultEncodingIsPC
)
138 value
= wxMacMakeMacStringFromPC( st
) ;
141 UMASetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
146 wxString
wxTextCtrl::GetValue() const
149 UMAGetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
150 wxBuffer
[actualsize
] = 0 ;
151 if( wxApp::s_macDefaultEncodingIsPC
)
152 return wxMacMakePCStringFromMac( wxBuffer
) ;
154 return wxString(wxBuffer
);
157 void wxTextCtrl::GetSelection(long* from
, long* to
) const
159 ControlEditTextSelectionRec selection
;
163 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
165 *from
= (**teH
).selStart
;
166 *to
= (**teH
).selEnd
;
169 void wxTextCtrl::SetValue(const wxString
& st
)
173 if( wxApp::s_macDefaultEncodingIsPC
)
174 value
= wxMacMakeMacStringFromPC( st
) ;
177 UMASetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
178 WindowRef window
= GetMacRootWindow() ;
181 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
184 wxMacDrawingHelper
help( win
) ;
185 // the mac control manager always assumes to have the origin at 0,0
188 bool hasTabBehind
= false ;
189 wxWindow
* parent
= GetParent() ;
192 if( parent
->MacGetWindowData() )
194 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
198 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
200 if ( ((wxControl
*)parent
)->GetMacControl() )
201 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
205 parent
= parent
->GetParent() ;
208 UMADrawControl( m_macControl
) ;
209 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
214 // Clipboard operations
215 void wxTextCtrl::Copy()
222 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
226 err
= ClearCurrentScrap( );
235 void wxTextCtrl::Cut()
242 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
246 err
= ClearCurrentScrap( );
252 // MacInvalidateControl() ;
256 void wxTextCtrl::Paste()
263 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
266 WindowRef window
= GetMacRootWindow() ;
269 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
272 wxMacDrawingHelper
help( win
) ;
273 // the mac control manager always assumes to have the origin at 0,0
276 bool hasTabBehind
= false ;
277 wxWindow
* parent
= GetParent() ;
280 if( parent
->MacGetWindowData() )
282 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
286 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
288 if ( ((wxControl
*)parent
)->GetMacControl() )
289 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
293 parent
= parent
->GetParent() ;
296 UMADrawControl( m_macControl
) ;
297 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
303 bool wxTextCtrl::CanCopy() const
305 // Can copy if there's a selection
307 GetSelection(& from
, & to
);
311 bool wxTextCtrl::CanCut() const
313 // Can cut if there's a selection
315 GetSelection(& from
, & to
);
319 bool wxTextCtrl::CanPaste() const
326 OSStatus err
= noErr
;
329 err
= GetCurrentScrap( &scrapRef
);
330 if ( err
!= noTypeErr
&& err
!= memFullErr
)
332 ScrapFlavorFlags flavorFlags
;
335 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
337 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
346 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
354 void wxTextCtrl::SetEditable(bool editable
)
357 UMAActivateControl( m_macControl
) ;
359 UMADeactivateControl( m_macControl
) ;
362 void wxTextCtrl::SetInsertionPoint(long pos
)
364 SetSelection( pos
, pos
) ;
367 void wxTextCtrl::SetInsertionPointEnd()
369 long pos
= GetLastPosition();
370 SetInsertionPoint(pos
);
373 long wxTextCtrl::GetInsertionPoint() const
375 ControlEditTextSelectionRec selection
;
379 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
380 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
381 return (**teH
).selStart
;
384 long wxTextCtrl::GetLastPosition() const
386 ControlEditTextSelectionRec selection
;
390 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
392 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
393 return (**teH
).teLength
;
396 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
401 ControlEditTextSelectionRec selection
;
403 selection
.selStart
= from
;
404 selection
.selEnd
= to
;
405 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
406 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
407 TESetSelect( from
, to
, teH
) ;
409 TEInsert( value
, value
.Length() , teH
) ;
413 void wxTextCtrl::Remove(long from
, long to
)
418 ControlEditTextSelectionRec selection
;
420 selection
.selStart
= from
;
421 selection
.selEnd
= to
;
422 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
423 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
428 void wxTextCtrl::SetSelection(long from
, long to
)
430 ControlEditTextSelectionRec selection
;
434 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
436 selection
.selStart
= from
;
437 selection
.selEnd
= to
;
439 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
440 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
443 bool wxTextCtrl::LoadFile(const wxString
& file
)
445 if ( wxTextCtrlBase::LoadFile(file
) )
453 void wxTextCtrl::WriteText(const wxString
& text
)
458 memcpy( wxBuffer
, text
, text
.Length() ) ;
459 wxBuffer
[text
.Length() ] = 0 ;
460 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
462 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
464 TEInsert( wxBuffer
, strlen( wxBuffer
) , teH
) ;
468 void wxTextCtrl::AppendText(const wxString
& text
)
470 SetInsertionPointEnd();
474 void wxTextCtrl::Clear()
476 UMASetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
480 bool wxTextCtrl::IsModified() const
485 bool wxTextCtrl::IsEditable() const
490 bool wxTextCtrl::AcceptsFocus() const
492 // we don't want focus if we can't be edited
493 return IsEditable() && wxControl::AcceptsFocus();
496 wxSize
wxTextCtrl::DoGetBestSize() const
501 if ( UMAHasAppearance() )
505 hText
+= 2 * m_macHorizontalBorder
;
508 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
510 int wText = DEFAULT_ITEM_WIDTH;
512 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
514 return wxSize(wText, hText);
516 if ( m_windowStyle
& wxTE_MULTILINE
)
518 hText
*= wxMin(GetNumberOfLines(), 5);
520 //else: for single line control everything is ok
521 return wxSize(wText
, hText
);
524 // ----------------------------------------------------------------------------
526 // ----------------------------------------------------------------------------
528 void wxTextCtrl::Undo()
535 void wxTextCtrl::Redo()
542 bool wxTextCtrl::CanUndo() const
547 bool wxTextCtrl::CanRedo() const
552 // Makes 'unmodified'
553 void wxTextCtrl::DiscardEdits()
558 int wxTextCtrl::GetNumberOfLines() const
561 UMAGetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
564 for (int i
= 0; i
< actualsize
; i
++)
566 if (wxBuffer
[i
] == '\r') count
++;
572 long wxTextCtrl::XYToPosition(long x
, long y
) const
578 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
583 void wxTextCtrl::ShowPosition(long pos
)
588 int wxTextCtrl::GetLineLength(long lineNo
) const
591 UMAGetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
595 for (int i
= 0; i
< actualsize
; i
++)
599 // Count chars in line then
601 for (int j
= i
; j
< actualsize
; j
++)
604 if (wxBuffer
[j
] == '\r') return count
;
609 if (wxBuffer
[i
] == '\r') count
++;
615 wxString
wxTextCtrl::GetLineText(long lineNo
) const
618 UMAGetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
622 for (int i
= 0; i
< actualsize
; i
++)
626 // Add chars in line then
629 for (int j
= i
; j
< actualsize
; j
++)
631 if (wxBuffer
[j
] == '\r')
639 if (wxBuffer
[i
] == '\r') count
++;
649 void wxTextCtrl::Command(wxCommandEvent
& event
)
651 SetValue (event
.GetString());
652 ProcessCommand (event
);
655 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
657 // By default, load the first file into the text window.
658 if (event
.GetNumberOfFiles() > 0)
660 LoadFile(event
.GetFiles()[0]);
664 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
666 switch ( event
.KeyCode() )
669 if (m_windowStyle
& wxPROCESS_ENTER
)
671 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
672 event
.SetEventObject( this );
673 if ( GetEventHandler()->ProcessEvent(event
) )
676 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
678 wxWindow
*parent
= GetParent();
679 wxPanel
*panel
= wxDynamicCast(parent
, wxPanel
);
680 while ( parent
!= NULL
&& panel
== NULL
)
682 parent
= parent
->GetParent() ;
683 panel
= wxDynamicCast(parent
, wxPanel
);
685 if ( panel
&& panel
->GetDefaultItem() )
687 wxButton
*def
= wxDynamicCast(panel
->GetDefaultItem(),
689 if ( def
&& def
->IsEnabled() )
691 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
692 event
.SetEventObject(def
);
698 //else: multiline controls need Enter for themselves
703 // always produce navigation event - even if we process TAB
704 // ourselves the fact that we got here means that the user code
705 // decided to skip processing of this TAB - probably to let it
706 // do its default job.
708 wxNavigationKeyEvent eventNav
;
709 eventNav
.SetDirection(!event
.ShiftDown());
710 eventNav
.SetWindowChange(event
.ControlDown());
711 eventNav
.SetEventObject(this);
713 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
721 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
724 keychar
= short(ev
->message
& charCodeMask
);
725 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
726 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
727 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
|| event
.KeyCode() == WXK_DELETE
|| event
.KeyCode() == WXK_BACK
)
729 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
730 event
.SetString( GetValue() ) ;
731 event
.SetEventObject( this );
732 GetEventHandler()->ProcessEvent(event
);
737 // ----------------------------------------------------------------------------
738 // standard handlers for standard edit menu events
739 // ----------------------------------------------------------------------------
741 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
746 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
751 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
756 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
761 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
766 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
768 event
.Enable( CanCut() );
771 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
773 event
.Enable( CanCopy() );
776 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
778 event
.Enable( CanPaste() );
781 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
783 event
.Enable( CanUndo() );
786 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
788 event
.Enable( CanRedo() );