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
This commit is contained in:
Vadim Zeitlin
2010-07-28 11:27:01 +00:00
parent f50d84586a
commit c072b9ec8a
5 changed files with 58 additions and 14 deletions

View File

@@ -20,7 +20,12 @@
class wxNSTextFieldControl : public wxWidgetCocoaImpl, public wxTextWidgetImpl class wxNSTextFieldControl : public wxWidgetCocoaImpl, public wxTextWidgetImpl
{ {
public : 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 ~wxNSTextFieldControl();
virtual wxString GetStringValue() const ; virtual wxString GetStringValue() const ;
@@ -36,10 +41,15 @@ public :
virtual bool HasOwnContextMenu() const { return true; } virtual bool HasOwnContextMenu() const { return true; }
virtual void controlAction(WXWidget slf, void* _cmd, void *sender); virtual void controlAction(WXWidget slf, void* _cmd, void *sender);
protected : protected :
NSTextField* m_textField; NSTextField* m_textField;
long m_selStart; long m_selStart;
long m_selEnd; long m_selEnd;
private:
// Common part of both ctors.
void Init(WXWidget w);
}; };
class wxNSTextViewControl : public wxWidgetCocoaImpl, public wxTextWidgetImpl class wxNSTextViewControl : public wxWidgetCocoaImpl, public wxTextWidgetImpl
@@ -78,7 +88,7 @@ protected:
class wxNSComboBoxControl : public wxNSTextFieldControl, public wxComboWidgetImpl class wxNSComboBoxControl : public wxNSTextFieldControl, public wxComboWidgetImpl
{ {
public : public :
wxNSComboBoxControl( wxWindow *wxPeer, WXWidget w ); wxNSComboBoxControl( wxComboBox *wxPeer, WXWidget w );
virtual ~wxNSComboBoxControl(); virtual ~wxNSComboBoxControl();
virtual int GetSelectedItem() const; virtual int GetSelectedItem() const;

View File

@@ -103,6 +103,7 @@ class wxNonOwnedWindow;
class wxMacControl; class wxMacControl;
class wxWidgetImpl; class wxWidgetImpl;
class wxComboBox;
class wxNotebook; class wxNotebook;
class wxTextCtrl; class wxTextCtrl;
@@ -480,7 +481,7 @@ public :
long extraStyle); long extraStyle);
#if wxOSX_USE_COCOA #if wxOSX_USE_COCOA
static wxWidgetImplType* CreateComboBox( wxWindowMac* wxpeer, static wxWidgetImplType* CreateComboBox( wxComboBox* wxpeer,
wxWindowMac* parent, wxWindowMac* parent,
wxWindowID id, wxWindowID id,
wxMenu* menu, wxMenu* menu,
@@ -572,16 +573,23 @@ public:
// //
class WXDLLIMPEXP_FWD_CORE wxTextAttr; class WXDLLIMPEXP_FWD_CORE wxTextAttr;
class WXDLLIMPEXP_FWD_CORE wxTextEntry;
// common interface for all implementations // common interface for all implementations
class WXDLLIMPEXP_CORE wxTextWidgetImpl class WXDLLIMPEXP_CORE wxTextWidgetImpl
{ {
public : 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() {} virtual ~wxTextWidgetImpl() {}
wxTextEntry *GetTextEntry() const { return m_entry; }
virtual bool CanFocus() const { return true; } virtual bool CanFocus() const { return true; }
virtual wxString GetStringValue() const = 0 ; virtual wxString GetStringValue() const = 0 ;
@@ -622,6 +630,11 @@ public :
virtual void CheckSpelling(bool WXUNUSED(check)) { } virtual void CheckSpelling(bool WXUNUSED(check)) { }
virtual wxSize GetBestSize() const { return wxDefaultSize; } virtual wxSize GetBestSize() const { return wxDefaultSize; }
private:
wxTextEntry * const m_entry;
wxDECLARE_NO_COPY_CLASS(wxTextWidgetImpl);
}; };
// common interface for all implementations // common interface for all implementations

View File

@@ -470,7 +470,9 @@ static pascal OSStatus wxMacUnicodeTextControlEventHandler( EventHandlerCallRef
DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacUnicodeTextControlEventHandler ) 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 wxString& str,
const wxPoint& pos, const wxPoint& pos,
const wxSize& size, long style ) const wxSize& size, long style )
: wxMacControl( wxPeer ) : wxMacControl( wxPeer ),
wxTextWidgetImpl( wxPeer )
{ {
m_font = wxPeer->GetFont() ; m_font = wxPeer->GetFont() ;
m_windowStyle = style ; m_windowStyle = style ;
@@ -707,7 +710,8 @@ protected :
} ; } ;
wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl *peer ) wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl *peer )
: wxMacControl( peer ) : wxMacControl( peer ),
wxTextWidgetImpl( peer )
{ {
SetNeedsFocusRect( true ) ; SetNeedsFocusRect( true ) ;
} }

View File

@@ -78,7 +78,8 @@
} }
@end @end
wxNSComboBoxControl::wxNSComboBoxControl( wxWindow *wxPeer, WXWidget w ) : wxNSTextFieldControl(wxPeer, w) wxNSComboBoxControl::wxNSComboBoxControl( wxComboBox *wxPeer, WXWidget w )
: wxNSTextFieldControl(wxPeer, wxPeer, w)
{ {
m_comboBox = (NSComboBox*)w; m_comboBox = (NSComboBox*)w;
} }
@@ -137,7 +138,7 @@ int wxNSComboBoxControl::FindString(const wxString& text) const
return result; return result;
} }
wxWidgetImplType* wxWidgetImpl::CreateComboBox( wxWindowMac* wxpeer, wxWidgetImplType* wxWidgetImpl::CreateComboBox( wxComboBox* wxpeer,
wxWindowMac* WXUNUSED(parent), wxWindowMac* WXUNUSED(parent),
wxWindowID WXUNUSED(id), wxWindowID WXUNUSED(id),
wxMenu* menu, wxMenu* menu,
@@ -183,4 +184,4 @@ wxSize wxComboBox::DoGetBestSize() const
return wxSize( lbWidth, lbHeight ); return wxSize( lbWidth, lbHeight );
} }
#endif // wxUSE_COMBOBOX #endif // wxUSE_COMBOBOX

View File

@@ -291,7 +291,9 @@ typedef BOOL (*wxOSX_insertNewlineHandlerPtr)(NSView* self, SEL _cmd, NSControl
// wxNSTextViewControl // 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; wxNSTextScrollView* sv = (wxNSTextScrollView*) w;
m_scrollView = sv; m_scrollView = sv;
@@ -511,7 +513,21 @@ wxSize wxNSTextViewControl::GetBestSize() const
// wxNSTextFieldControl // 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(<NSTextFieldDelegate>) *tf = (NSTextField*) w; NSTextField wxOSX_10_6_AND_LATER(<NSTextFieldDelegate>) *tf = (NSTextField*) w;
m_textField = tf; m_textField = tf;
@@ -650,7 +666,7 @@ void wxNSTextFieldControl::controlAction(WXWidget WXUNUSED(slf),
{ {
wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId()); wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
event.SetEventObject( wxpeer ); event.SetEventObject( wxpeer );
event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() ); event.SetString( GetTextEntry()->GetValue() );
wxpeer->HandleWindowEvent( event ); wxpeer->HandleWindowEvent( event );
} }
} }
@@ -694,7 +710,7 @@ wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
[v setBezeled:NO]; [v setBezeled:NO];
[v setBordered:NO]; [v setBordered:NO];
c = new wxNSTextFieldControl( wxpeer, v ); c = new wxNSTextFieldControl( wxpeer, wxpeer, v );
} }
return c; return c;