+ // only now the embedding is correct and we can do a positioning update
+
+ MacSuperChangedPosition() ;
+
+ if ( m_windowStyle & wxTE_READONLY)
+ {
+ SetEditable( false ) ;
+ }
+
+ SetCursor( wxCursor( wxCURSOR_IBEAM ) ) ;
+
+ return true;
+}
+
+void wxTextCtrl::MacSuperChangedPosition()
+{
+ wxWindow::MacSuperChangedPosition() ;
+ GetPeer()->SuperChangedPosition() ;
+}
+
+void wxTextCtrl::MacVisibilityChanged()
+{
+ GetPeer()->VisibilityChanged( MacIsReallyShown() ) ;
+}
+
+void wxTextCtrl::MacEnabledStateChanged()
+{
+}
+
+wxString wxTextCtrl::GetValue() const
+{
+ return GetPeer()->GetStringValue() ;
+}
+
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+ GetPeer()->GetSelection( from , to ) ;
+}
+
+void wxTextCtrl::SetValue(const wxString& str)
+{
+ // optimize redraws
+ if ( GetValue() == str )
+ return ;
+
+ GetPeer()->SetStringValue(str) ;
+
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event.SetString( GetValue() ) ;
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+}
+
+void wxTextCtrl::SetMaxLength(unsigned long len)
+{
+ m_maxLength = len ;
+}
+
+bool wxTextCtrl::SetFont( const wxFont& font )
+{
+ if ( !wxTextCtrlBase::SetFont( font ) )
+ return false ;
+
+ GetPeer()->SetFont( font , GetForegroundColour() , GetWindowStyle() ) ;
+ return true ;
+}
+
+bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
+{
+ GetPeer()->SetStyle( start , end , style ) ;
+ return true ;
+}
+
+bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style)
+{
+ wxTextCtrlBase::SetDefaultStyle( style ) ;
+ SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
+ return true ;
+}
+
+// Clipboard operations
+void wxTextCtrl::Copy()
+{
+ if (CanCopy())
+ {
+ GetPeer()->Copy() ;
+ }
+}
+
+void wxTextCtrl::Cut()
+{
+ if (CanCut())
+ {
+ GetPeer()->Cut() ;
+
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+ }
+}
+
+void wxTextCtrl::Paste()
+{
+ if (CanPaste())
+ {
+ GetPeer()->Paste() ;
+ // eventually we should add setting the default style again
+
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+ }
+}
+
+bool wxTextCtrl::CanCopy() const
+{
+ // Can copy if there's a selection
+ long from, to;
+ GetSelection(& from, & to);
+ return (from != to);
+}
+
+bool wxTextCtrl::CanCut() const
+{
+ if ( !IsEditable() )
+ {
+ return false ;
+ }
+ // Can cut if there's a selection
+ long from, to;
+ GetSelection(& from, & to);
+ return (from != to);
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+ if (!IsEditable())
+ return false;
+
+ return GetPeer()->CanPaste() ;
+}
+
+void wxTextCtrl::SetEditable(bool editable)
+{
+ if ( editable != m_editable )
+ {
+ m_editable = editable ;
+ GetPeer()->SetEditable( editable ) ;
+ }
+}
+
+void wxTextCtrl::SetInsertionPoint(long pos)
+{
+ SetSelection( pos , pos ) ;
+}
+
+void wxTextCtrl::SetInsertionPointEnd()
+{
+ wxTextPos pos = GetLastPosition();
+ SetInsertionPoint(pos);
+}
+
+long wxTextCtrl::GetInsertionPoint() const
+{
+ long begin,end ;
+ GetSelection( &begin , &end ) ;
+ return begin ;
+}
+
+wxTextPos wxTextCtrl::GetLastPosition() const
+{
+ return GetPeer()->GetLastPosition( ) ;
+}
+
+void wxTextCtrl::Replace(long from, long to, const wxString& str)
+{
+ GetPeer()->Replace( from , to , str) ;
+}
+
+void wxTextCtrl::Remove(long from, long to)
+{
+ GetPeer()->Remove( from , to ) ;
+}
+
+void wxTextCtrl::SetSelection(long from, long to)
+{
+ GetPeer()->SetSelection( from , to ) ;
+}
+
+bool wxTextCtrl::LoadFile(const wxString& file)
+{
+ if ( wxTextCtrlBase::LoadFile(file) )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void wxTextCtrl::WriteText(const wxString& str)
+{
+ // TODO this MPRemoting will be moved into a remoting peer proxy for any command
+ if ( !wxIsMainThread() )
+ {
+ // unfortunately CW 8 is not able to correctly deduce the template types, so we have
+ // to instantiate explicitely
+ wxMacMPRemoteGUICall<wxTextCtrl,wxString>( this , &wxTextCtrl::WriteText , str ) ;
+ return ;
+ }
+ else
+ {
+ GetPeer()->WriteText( str ) ;
+ }
+}
+
+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() )
+ {
+ wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
+ wxButton);
+ if ( def && def->IsEnabled() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
+ event.SetEventObject(def);
+ def->Command(event);
+ return ;
+ }
+ }
+
+ // this will make wxWidgets eat the ENTER key so that
+ // we actually prevent line wrapping in a single line
+ // text control
+ eat_key = true;
+ }