+void wxTextCtrl::AppendText(const wxString& text)
+{
+ SetInsertionPointEnd();
+ WriteText(text);
+}
+
+void wxTextCtrl::Clear()
+{
+ GetPeer()->Clear() ;
+}
+
+bool wxTextCtrl::IsModified() const
+{
+ return m_dirty;
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+ return IsEnabled() && m_editable ;
+}
+
+bool wxTextCtrl::AcceptsFocus() const
+{
+ // we don't want focus if we can't be edited
+ return /*IsEditable() && */ wxControl::AcceptsFocus();
+}
+
+wxSize wxTextCtrl::DoGetBestSize() const
+{
+ int wText = 100 ;
+
+ int hText;
+
+ // these are the numbers from the HIG, we reduce them by the borders
+ // first
+
+ switch( m_windowVariant )
+ {
+ case wxWINDOW_VARIANT_NORMAL :
+ hText = 22 - 6 ;
+ break ;
+ case wxWINDOW_VARIANT_SMALL :
+ hText = 19 - 6 ;
+ break ;
+ case wxWINDOW_VARIANT_MINI :
+ hText= 15 - 6 ;
+ break ;
+ default :
+ hText = 22 - 6;
+ break ;
+ }
+
+ // as the above numbers have some free space around the text
+ // we get 5 lines like this anyway
+ if ( m_windowStyle & wxTE_MULTILINE )
+ {
+ hText *= 5 ;
+ }
+
+ if ( !HasFlag(wxNO_BORDER) )
+ hText += 6 ;
+
+ return wxSize(wText, hText);
+}
+
+// ----------------------------------------------------------------------------
+// Undo/redo
+// ----------------------------------------------------------------------------
+
+void wxTextCtrl::Undo()
+{
+ if (CanUndo())
+ {
+ GetPeer()->Undo() ;
+ }
+}
+
+void wxTextCtrl::Redo()
+{
+ if (CanRedo())
+ {
+ GetPeer()->Redo() ;
+ }
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+ if ( !IsEditable() )
+ {
+ return false ;
+ }
+ return GetPeer()->CanUndo() ;
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+ if ( !IsEditable() )
+ {
+ return false ;
+ }
+ return GetPeer()->CanRedo() ;
+}
+
+void wxTextCtrl::MarkDirty()
+{
+ m_dirty = true;
+}
+
+void wxTextCtrl::DiscardEdits()
+{
+ m_dirty = false;
+}
+
+int wxTextCtrl::GetNumberOfLines() const
+{
+ return GetPeer()->GetNumberOfLines() ;
+}
+
+long wxTextCtrl::XYToPosition(long x, long y) const
+{
+ return GetPeer()->XYToPosition( x , y ) ;
+}
+
+bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
+{
+ return GetPeer()->PositionToXY(pos , x , y ) ;
+}
+
+void wxTextCtrl::ShowPosition(long pos)
+{
+ return GetPeer()->ShowPosition(pos) ;
+}
+
+int wxTextCtrl::GetLineLength(long lineNo) const
+{
+ return GetPeer()->GetLineLength(lineNo) ;
+}
+
+wxString wxTextCtrl::GetLineText(long lineNo) const
+{
+ return GetPeer()->GetLineText(lineNo) ;
+}
+
+/*
+ * Text item
+ */
+
+void wxTextCtrl::Command(wxCommandEvent & event)
+{
+ SetValue (event.GetString());
+ ProcessCommand (event);
+}
+
+void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
+{
+ // By default, load the first file into the text window.
+ if (event.GetNumberOfFiles() > 0)
+ {
+ LoadFile(event.GetFiles()[0]);
+ }
+}
+
+void wxTextCtrl::OnEraseBackground(wxEraseEvent& event)
+{
+ // all erasing should be done by the real mac control implementation
+ // while this is true for MLTE under classic, the HITextView is somehow
+ // transparent but background erase is not working correctly, so intercept
+ // things while we can...
+ event.Skip() ;
+}
+
+void wxTextCtrl::OnChar(wxKeyEvent& event)
+{
+ int key = event.GetKeyCode() ;
+ bool eat_key = false ;
+
+ if ( key == 'c' && event.MetaDown() )
+ {
+ if ( CanCopy() )
+ Copy() ;
+ return ;
+ }
+
+ if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
+ !( key == WXK_RETURN && ( (m_windowStyle & wxPROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
+/* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
+ )
+ {
+ // eat it
+ return ;
+ }
+
+ // Check if we have reached the max # of chars, but still allow navigation and deletion
+ if ( !IsMultiLine() && GetValue().Length() >= m_maxLength &&
+ key != WXK_LEFT && key != WXK_RIGHT && key != WXK_TAB &&
+ key != WXK_BACK && !( key == WXK_RETURN && (m_windowStyle & wxPROCESS_ENTER) )
+ )
+ {
+ // eat it, we don't want to add more than allowed # of characters
+ return;
+ }
+
+ // assume that any key not processed yet is going to modify the control
+ m_dirty = true;
+
+ if ( key == 'v' && event.MetaDown() )
+ {
+ if ( CanPaste() )
+ Paste() ;
+ return ;
+ }
+ if ( key == 'x' && event.MetaDown() )
+ {
+ if ( CanCut() )
+ Cut() ;
+ return ;
+ }
+ switch ( key )
+ {
+ case WXK_RETURN:
+ if (m_windowStyle & wxPROCESS_ENTER)
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+ event.SetEventObject( this );
+ event.SetString( GetValue() );
+ if ( GetEventHandler()->ProcessEvent(event) )
+ return;
+ }
+ if ( !(m_windowStyle & wxTE_MULTILINE) )
+ {
+ wxWindow *parent = GetParent();
+ while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
+ parent = parent->GetParent() ;
+ }
+ if ( parent && parent->GetDefaultItem() )