From c072b9ec8a5a9f65743ecbd16b0b0bb9dbc8b46b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 28 Jul 2010 11:27:01 +0000 Subject: [PATCH] Add association between wxOSX wxTextWidgetImpl and wxTextEntry. This allows to always find the correct wxTextEntry to use in the implementation of text-related widgets without using any casts. Notably, the wrong up-cast of wxWindow to wxTextCtrl in wxNSTextFieldControl::controlAction() which resulted in a crash when the window was actually a wxComboBox can now be fixed. Closes #12284. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65129 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/cocoa/private/textimpl.h | 14 ++++++++++++-- include/wx/osx/core/private.h | 17 +++++++++++++++-- src/osx/carbon/textctrl.cpp | 10 +++++++--- src/osx/cocoa/combobox.mm | 7 ++++--- src/osx/cocoa/textctrl.mm | 24 ++++++++++++++++++++---- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/include/wx/osx/cocoa/private/textimpl.h b/include/wx/osx/cocoa/private/textimpl.h index 21a60a40c9..e0284e661a 100644 --- a/include/wx/osx/cocoa/private/textimpl.h +++ b/include/wx/osx/cocoa/private/textimpl.h @@ -20,7 +20,12 @@ class wxNSTextFieldControl : public wxWidgetCocoaImpl, public wxTextWidgetImpl { public : - wxNSTextFieldControl( wxWindow *wxPeer, WXWidget w ); + // wxNSTextFieldControl must always be associated with a wxTextEntry. If + // it's associated with a wxTextCtrl then we can get the associated entry + // from it but otherwise the second ctor should be used to explicitly pass + // us the entry. + wxNSTextFieldControl( wxTextCtrl *text, WXWidget w ); + wxNSTextFieldControl( wxWindow *wxPeer, wxTextEntry *entry, WXWidget w ); virtual ~wxNSTextFieldControl(); virtual wxString GetStringValue() const ; @@ -36,10 +41,15 @@ public : virtual bool HasOwnContextMenu() const { return true; } virtual void controlAction(WXWidget slf, void* _cmd, void *sender); + protected : NSTextField* m_textField; long m_selStart; long m_selEnd; + +private: + // Common part of both ctors. + void Init(WXWidget w); }; class wxNSTextViewControl : public wxWidgetCocoaImpl, public wxTextWidgetImpl @@ -78,7 +88,7 @@ protected: class wxNSComboBoxControl : public wxNSTextFieldControl, public wxComboWidgetImpl { public : - wxNSComboBoxControl( wxWindow *wxPeer, WXWidget w ); + wxNSComboBoxControl( wxComboBox *wxPeer, WXWidget w ); virtual ~wxNSComboBoxControl(); virtual int GetSelectedItem() const; diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index d826881b42..7ffa154e10 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -103,6 +103,7 @@ class wxNonOwnedWindow; class wxMacControl; class wxWidgetImpl; +class wxComboBox; class wxNotebook; class wxTextCtrl; @@ -480,7 +481,7 @@ public : long extraStyle); #if wxOSX_USE_COCOA - static wxWidgetImplType* CreateComboBox( wxWindowMac* wxpeer, + static wxWidgetImplType* CreateComboBox( wxComboBox* wxpeer, wxWindowMac* parent, wxWindowID id, wxMenu* menu, @@ -572,16 +573,23 @@ public: // class WXDLLIMPEXP_FWD_CORE wxTextAttr; +class WXDLLIMPEXP_FWD_CORE wxTextEntry; // common interface for all implementations class WXDLLIMPEXP_CORE wxTextWidgetImpl { public : - wxTextWidgetImpl() {} + // Any widgets implementing this interface must be associated with a + // wxTextEntry so instead of requiring the derived classes to implement + // another (pure) virtual function, just take the pointer to this entry in + // our ctor and implement GetTextEntry() ourselves. + wxTextWidgetImpl(wxTextEntry *entry) : m_entry(entry) {} virtual ~wxTextWidgetImpl() {} + wxTextEntry *GetTextEntry() const { return m_entry; } + virtual bool CanFocus() const { return true; } virtual wxString GetStringValue() const = 0 ; @@ -622,6 +630,11 @@ public : virtual void CheckSpelling(bool WXUNUSED(check)) { } virtual wxSize GetBestSize() const { return wxDefaultSize; } + +private: + wxTextEntry * const m_entry; + + wxDECLARE_NO_COPY_CLASS(wxTextWidgetImpl); }; // common interface for all implementations diff --git a/src/osx/carbon/textctrl.cpp b/src/osx/carbon/textctrl.cpp index 549c81b172..17ba7c86d1 100644 --- a/src/osx/carbon/textctrl.cpp +++ b/src/osx/carbon/textctrl.cpp @@ -470,7 +470,9 @@ static pascal OSStatus wxMacUnicodeTextControlEventHandler( EventHandlerCallRef DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacUnicodeTextControlEventHandler ) -wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer ) : wxMacControl( wxPeer ) +wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer ) + : wxMacControl( wxPeer ), + wxTextWidgetImpl( wxPeer ) { } @@ -478,7 +480,8 @@ wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer, const wxString& str, const wxPoint& pos, const wxSize& size, long style ) - : wxMacControl( wxPeer ) + : wxMacControl( wxPeer ), + wxTextWidgetImpl( wxPeer ) { m_font = wxPeer->GetFont() ; m_windowStyle = style ; @@ -707,7 +710,8 @@ protected : } ; wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl *peer ) - : wxMacControl( peer ) + : wxMacControl( peer ), + wxTextWidgetImpl( peer ) { SetNeedsFocusRect( true ) ; } diff --git a/src/osx/cocoa/combobox.mm b/src/osx/cocoa/combobox.mm index 16876eef2e..1666c33b83 100644 --- a/src/osx/cocoa/combobox.mm +++ b/src/osx/cocoa/combobox.mm @@ -78,7 +78,8 @@ } @end -wxNSComboBoxControl::wxNSComboBoxControl( wxWindow *wxPeer, WXWidget w ) : wxNSTextFieldControl(wxPeer, w) +wxNSComboBoxControl::wxNSComboBoxControl( wxComboBox *wxPeer, WXWidget w ) + : wxNSTextFieldControl(wxPeer, wxPeer, w) { m_comboBox = (NSComboBox*)w; } @@ -137,7 +138,7 @@ int wxNSComboBoxControl::FindString(const wxString& text) const return result; } -wxWidgetImplType* wxWidgetImpl::CreateComboBox( wxWindowMac* wxpeer, +wxWidgetImplType* wxWidgetImpl::CreateComboBox( wxComboBox* wxpeer, wxWindowMac* WXUNUSED(parent), wxWindowID WXUNUSED(id), wxMenu* menu, @@ -183,4 +184,4 @@ wxSize wxComboBox::DoGetBestSize() const return wxSize( lbWidth, lbHeight ); } -#endif // wxUSE_COMBOBOX \ No newline at end of file +#endif // wxUSE_COMBOBOX diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index ced1a2369d..77416d2362 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -291,7 +291,9 @@ typedef BOOL (*wxOSX_insertNewlineHandlerPtr)(NSView* self, SEL _cmd, NSControl // wxNSTextViewControl -wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w) +wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) + : wxWidgetCocoaImpl(wxPeer, w), + wxTextWidgetImpl(wxPeer) { wxNSTextScrollView* sv = (wxNSTextScrollView*) w; m_scrollView = sv; @@ -511,7 +513,21 @@ wxSize wxNSTextViewControl::GetBestSize() const // wxNSTextFieldControl -wxNSTextFieldControl::wxNSTextFieldControl( wxWindow *wxPeer, WXWidget w ) : wxWidgetCocoaImpl(wxPeer, w) +wxNSTextFieldControl::wxNSTextFieldControl( wxTextCtrl *text, WXWidget w ) + : wxWidgetCocoaImpl(text, w), + wxTextWidgetImpl(text) +{ +} + +wxNSTextFieldControl::wxNSTextFieldControl(wxWindow *wxPeer, + wxTextEntry *entry, + WXWidget w) + : wxWidgetCocoaImpl(wxPeer, w), + wxTextWidgetImpl(entry) +{ +} + +void wxNSTextFieldControl::Init(WXWidget w) { NSTextField wxOSX_10_6_AND_LATER() *tf = (NSTextField*) w; m_textField = tf; @@ -650,7 +666,7 @@ void wxNSTextFieldControl::controlAction(WXWidget WXUNUSED(slf), { wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId()); event.SetEventObject( wxpeer ); - event.SetString( static_cast(wxpeer)->GetValue() ); + event.SetString( GetTextEntry()->GetValue() ); wxpeer->HandleWindowEvent( event ); } } @@ -694,7 +710,7 @@ wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer, [v setBezeled:NO]; [v setBordered:NO]; - c = new wxNSTextFieldControl( wxpeer, v ); + c = new wxNSTextFieldControl( wxpeer, wxpeer, v ); } return c; -- 2.45.2