+ 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() );
+}
+
+bool wxTextCtrl::MacSetupCursor( const wxPoint& pt )
+{
+ return true ;
+}
+
+// user pane implementation
+
+void wxTextCtrl::MacControlUserPaneDrawProc(wxInt16 part)
+{
+}
+
+wxInt16 wxTextCtrl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
+{
+ return kControlNoPart ;
+}
+
+wxInt16 wxTextCtrl::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
+{
+ return kControlNoPart ;
+}
+
+void wxTextCtrl::MacControlUserPaneIdleProc()
+{
+}
+
+wxInt16 wxTextCtrl::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
+{
+ return kControlNoPart ;
+}
+
+void wxTextCtrl::MacControlUserPaneActivateProc(bool activating)
+{
+}
+
+wxInt16 wxTextCtrl::MacControlUserPaneFocusProc(wxInt16 action)
+{
+ return kControlNoPart ;
+}
+
+void wxTextCtrl::MacControlUserPaneBackgroundProc(void* info)
+{
+}
+
+// ----------------------------------------------------------------------------
+// implementation base class
+// ----------------------------------------------------------------------------
+
+wxMacTextControl::wxMacTextControl()
+{
+}
+
+wxMacTextControl::~wxMacTextControl()
+{
+}
+
+void wxMacTextControl::SetStyle(long start, long end, const wxTextAttr& style)
+{
+}
+
+void wxMacTextControl::Copy()
+{
+}
+
+void wxMacTextControl::Cut()
+{
+}
+
+void wxMacTextControl::Paste()
+{
+}
+
+bool wxMacTextControl::CanPaste() const
+{
+ return false ;
+}
+
+void wxMacTextControl::SetEditable(bool editable)
+{
+}
+
+wxTextPos wxMacTextControl::GetLastPosition() const
+{
+ return GetStringValue().Length() ;
+}
+
+void wxMacTextControl::Replace( long from , long to , const wxString str )
+{
+}
+
+void wxMacTextControl::Clear()
+{
+ SetStringValue( wxEmptyString ) ;
+}
+
+bool wxMacTextControl::CanUndo() const
+{
+ return false ;
+}
+
+void wxMacTextControl::Undo() { }
+
+bool wxMacTextControl::CanRedo() const
+{
+ return false ;
+}
+
+void wxMacTextControl::Redo()
+{
+}
+
+long wxMacTextControl::XYToPosition(long x, long y) const
+{
+ return 0 ;
+}
+
+bool wxMacTextControl::PositionToXY(long pos, long *x, long *y) const
+{
+ return false ;
+}
+
+void wxMacTextControl::ShowPosition( long WXUNUSED(pos) )
+{
+}
+
+int wxMacTextControl::GetNumberOfLines() const
+{
+ ItemCount lines = 0 ;
+ wxString content = GetStringValue() ;
+ lines = 1;
+ for (size_t i = 0; i < content.Length() ; i++)
+ {
+ if (content[i] == '\r') lines++;
+ }
+ return lines ;
+}
+
+wxString wxMacTextControl::GetLineText(long lineNo) const
+{
+ // TODO change this if possible to reflect real lines
+ wxString content = GetStringValue() ;
+
+ // Find line first
+ int count = 0;
+ for (size_t i = 0; i < content.Length() ; i++)
+ {
+ if (count == lineNo)
+ {
+ // Add chars in line then
+ wxString tmp;
+
+ for (size_t j = i; j < content.Length(); j++)
+ {
+ if (content[j] == '\n')
+ return tmp;
+
+ tmp += content[j];
+ }
+
+ return tmp;
+ }
+ if (content[i] == '\n') count++;
+ }
+ return wxEmptyString ;
+}
+
+int wxMacTextControl::GetLineLength(long lineNo) const
+{
+ // TODO change this if possible to reflect real lines
+ wxString content = GetStringValue() ;
+
+ // Find line first
+ int count = 0;
+ for (size_t i = 0; i < content.Length() ; i++)
+ {
+ if (count == lineNo)
+ {
+ // Count chars in line then
+ count = 0;
+ for (size_t j = i; j < content.Length(); j++)
+ {
+ count++;
+ if (content[j] == '\n') return count;
+ }
+
+ return count;
+ }
+ if (content[i] == '\n') count++;
+ }
+ return 0 ;
+}
+
+// ----------------------------------------------------------------------------
+// standard unicode control implementation
+// ----------------------------------------------------------------------------
+
+#if TARGET_API_MAC_OSX
+
+wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxWindow *wxPeer,
+ const wxString& str,
+ const wxPoint& pos,
+ const wxSize& size, long style )
+{
+ m_font = wxPeer->GetFont() ;
+ m_windowStyle = style ;
+ Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
+ wxString st = str ;
+ wxMacConvertNewlines10To13( &st ) ;
+ wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
+ CFStringRef cfr = cf ;
+ Boolean isPassword = ( m_windowStyle & wxTE_PASSWORD ) != 0 ;
+ m_valueTag = isPassword ? kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag ;
+ CreateEditUnicodeTextControl( MAC_WXHWND(wxPeer->MacGetTopLevelWindowRef()), &bounds , cfr , isPassword , NULL , &m_controlRef ) ;
+
+ if ( !(m_windowStyle & wxTE_MULTILINE) )
+ {
+ SetData<Boolean>( kControlEditTextPart , kControlEditTextSingleLineTag , true ) ;
+ }
+}
+
+wxMacUnicodeTextControl::~wxMacUnicodeTextControl()
+{
+}
+
+void wxMacUnicodeTextControl::VisibilityChanged(bool shown)
+{
+ if ( !(m_windowStyle & wxTE_MULTILINE) && shown )
+ {
+ // work around a refresh issue insofar as not always the entire content is shown even if this would be possible
+ ControlEditTextSelectionRec sel ;
+ CFStringRef value = NULL ;
+
+ verify_noerr( GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
+ verify_noerr( GetData<CFStringRef>( 0, m_valueTag , &value ) );
+ verify_noerr( SetData<CFStringRef>( 0, m_valueTag, &value ) );
+ verify_noerr( SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
+
+ CFRelease( value ) ;
+ }
+}
+wxString wxMacUnicodeTextControl::GetStringValue() const
+{
+ wxString result ;
+ CFStringRef value = GetData<CFStringRef>(0,m_valueTag) ;
+ if ( value )
+ {
+ wxMacCFStringHolder cf(value) ;
+ result = cf.AsString() ;
+ }
+#if '\n' == 10
+ wxMacConvertNewlines13To10( &result ) ;
+#else
+ wxMacConvertNewlines10To13( &result ) ;
+#endif
+ return result ;
+}
+void wxMacUnicodeTextControl::SetStringValue( const wxString &str)
+{
+ wxString st = str ;
+ wxMacConvertNewlines10To13( &st ) ;
+ wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
+ verify_noerr( SetData<CFStringRef>( 0, m_valueTag , cf ) ) ;
+}
+void wxMacUnicodeTextControl::Copy()
+{
+ SendHICommand( kHICommandCopy ) ;
+}
+void wxMacUnicodeTextControl::Cut()
+{
+ SendHICommand( kHICommandCut ) ;
+}
+void wxMacUnicodeTextControl::Paste()
+{
+ SendHICommand( kHICommandPaste ) ;
+}
+bool wxMacUnicodeTextControl::CanPaste() const
+{
+ return true ;
+}
+void wxMacUnicodeTextControl::SetEditable(bool editable)
+{
+ SetData<Boolean>( 0 , kControlEditTextLockedTag , (Boolean) !editable ) ;
+}
+void wxMacUnicodeTextControl::Remove( long from , long to )
+{
+}