+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;
+ }
+
+ break;
+
+ case WXK_TAB:
+ if ( !(m_windowStyle & wxTE_PROCESS_TAB))
+ {
+ int flags = 0;
+ if (!event.ShiftDown())
+ flags |= wxNavigationKeyEvent::IsForward ;
+ if (event.ControlDown())
+ flags |= wxNavigationKeyEvent::WinChange ;
+ Navigate(flags);
+ return;
+ }
+ else
+ {
+ // This is necessary (don't know why) or the tab will not
+ // be inserted.
+ WriteText(wxT("\t"));
+ }
+
+ break;
+ }
+
+ if (!eat_key)
+ {
+ // perform keystroke handling
+ if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
+ CallNextEventHandler((EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
+ else
+ {
+ EventRecord rec ;
+ if ( wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) )
+ {
+ EventRecord *ev = &rec ;
+ short keycode ;
+ short keychar ;
+ keychar = short(ev->message & charCodeMask);
+ keycode = short(ev->message & keyCodeMask) >> 8 ;
+
+ m_peer->HandleKey( keycode , keychar , ev->modifiers ) ;
+ }
+ }
+ }
+ if ( ( key >= 0x20 && key < WXK_START ) ||
+ key == WXK_RETURN ||
+ key == WXK_DELETE ||
+ key == WXK_BACK)
+ {
+ wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event1.SetEventObject( this );
+ wxPostEvent(GetEventHandler(),event1);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// standard handlers for standard edit menu events
+// ----------------------------------------------------------------------------
+
+void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
+{
+ Cut();
+}
+
+void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
+{
+ Copy();
+}
+
+void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
+{
+ Paste();
+}
+
+void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
+{
+ Undo();
+}
+
+void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
+{
+ Redo();
+}
+
+void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
+{
+ event.Enable( CanCut() );
+}
+
+void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
+{
+ event.Enable( CanCopy() );
+}
+
+void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
+{
+ event.Enable( CanPaste() );
+}
+
+void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
+{
+ event.Enable( CanUndo() );
+}
+
+void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
+{
+ event.Enable( CanRedo() );
+}