From: Vadim Zeitlin Date: Sat, 17 Oct 2009 01:04:26 +0000 (+0000) Subject: Rewrite handling cell value changes in wxOSX/Cocoa wxDVC. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0599fe19d95bd73f11142bab6c5f90d66fc9b0b5 Rewrite handling cell value changes in wxOSX/Cocoa wxDVC. Instead of using a chain of dynamic_cast<>s to find the right type of the value, construct a wxVariant corresponding to the type of the object we receive in NSOutlineView:setObjectValue:forTableColumn:byItem and pass it to a wxDataViewRenderer virtual function. This fixes assert and allows to edit icon text items under OS X. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62436 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/osx/dataview.h b/include/wx/osx/dataview.h index a484880222..42df0c23c6 100644 --- a/include/wx/osx/dataview.h +++ b/include/wx/osx/dataview.h @@ -82,6 +82,14 @@ public: void SetNativeData(wxDataViewRendererNativeData* newNativeDataPtr); + +#if wxOSX_USE_COCOA + // called when a value was edited by user + virtual void OSXOnCellChanged(const wxVariant& value, + const wxDataViewItem& item, + unsigned col); +#endif // Cocoa + private: // // variables @@ -272,6 +280,13 @@ public: // virtual bool MacRender(); +#if wxOSX_USE_COCOA + // called when a value was edited by user + virtual void OSXOnCellChanged(const wxVariant& value, + const wxDataViewItem& item, + unsigned col); +#endif // Cocoa + protected: private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewIconTextRenderer) diff --git a/src/osx/cocoa/dataview.mm b/src/osx/cocoa/dataview.mm index c5b3635ad9..243ac2515c 100644 --- a/src/osx/cocoa/dataview.mm +++ b/src/osx/cocoa/dataview.mm @@ -516,47 +516,31 @@ outlineView:(NSOutlineView*)outlineView wxDataViewItem dataViewItem([((wxPointerObject*) item) pointer]); - - if (((dynamic_cast(col->GetRenderer()) != NULL) || (dynamic_cast(col->GetRenderer()) != NULL)) && - ([object isKindOfClass:[NSString class]] == YES)) - { - model->SetValue(wxVariant(wxCFStringRef([((NSString*) object) retain]).AsString()),dataViewItem,col->GetModelColumn()); // the string has to be retained before being passed to wxCFStringRef - model->ValueChanged(dataViewItem,col->GetModelColumn()); - } - else if (dynamic_cast(col->GetRenderer()) != NULL) - { - if ([object isKindOfClass:[NSNumber class]] == YES) - { - model->SetValue(wxVariant(dynamic_cast(col->GetRenderer())->GetChoice([((NSNumber*) object) intValue])), - dataViewItem,col->GetModelColumn()); - model->ValueChanged(dataViewItem,col->GetModelColumn()); - } - else if ([object isKindOfClass:[NSString class]] == YES) // do not know if this case can occur but initializing using strings works - { - model->SetValue(wxVariant(wxCFStringRef((NSString*) object).AsString()),dataViewItem,col->GetModelColumn()); - model->ValueChanged(dataViewItem,col->GetModelColumn()); - } - } - else if ((dynamic_cast(col->GetRenderer()) != NULL) && ([object isKindOfClass:[NSDate class]] == YES)) - { - wxDateTime wxDateTimeValue(1,wxDateTime::Jan,1970); - - wxLongLong seconds; - - seconds.Assign([((NSDate*) object) timeIntervalSince1970]); // get the number of seconds since 1970-01-01 UTC and this is - // the only way to convert a double to a wxLongLong - // the user has entered a date in the local timezone but seconds contains the number of seconds from date in the local timezone since 1970-01-01 UTC; - // therefore, the timezone information has to be transferred to wxWidgets, too: - wxDateTimeValue.Add(wxTimeSpan(0,0,seconds)); - wxDateTimeValue.MakeFromTimezone(wxDateTime::UTC); - model->SetValue(wxVariant(wxDateTimeValue),dataViewItem,col->GetModelColumn()); - model->ValueChanged(dataViewItem,col->GetModelColumn()); - } - else if ((dynamic_cast(col->GetRenderer()) != NULL) && ([object isKindOfClass:[NSNumber class]] == YES)) + wxVariant value; + if ( [object isKindOfClass:[NSString class]] ) + value = wxCFStringRef([((NSString*) object) retain]).AsString(); + else if ( [object isKindOfClass:[NSNumber class]] ) + value = (long)[((NSNumber *)object) intValue]; + else if ( [object isKindOfClass:[NSDate class]] ) { - model->SetValue(wxVariant((bool) [((NSNumber*) object) boolValue]),dataViewItem,col->GetModelColumn()); - model->ValueChanged(dataViewItem,col->GetModelColumn()); + // get the number of seconds since 1970-01-01 UTC and this is the only + // way to convert a double to a wxLongLong + const wxLongLong seconds = [((NSDate*) object) timeIntervalSince1970]; + + wxDateTime dt(1, wxDateTime::Jan, 1970); + dt.Add(wxTimeSpan(0,0,seconds)); + + // the user has entered a date in the local timezone but seconds + // contains the number of seconds from date in the local timezone + // since 1970-01-01 UTC; therefore, the timezone information has to be + // transferred to wxWidgets, too: + dt.MakeFromTimezone(wxDateTime::UTC); + + value = dt; } + + col->GetRenderer()-> + OSXOnCellChanged(value, dataViewItem, col->GetModelColumn()); } -(void) outlineView:(NSOutlineView*)outlineView sortDescriptorsDidChange:(NSArray*)oldDescriptors @@ -2196,8 +2180,14 @@ void wxDataViewRendererNativeData::ApplyLineBreakMode(NSCell *cell) // --------------------------------------------------------- // wxDataViewRenderer // --------------------------------------------------------- - wxDataViewRenderer::wxDataViewRenderer(const wxString& varianttype, wxDataViewCellMode mode, int align) -:wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode), m_NativeDataPtr(NULL) + +wxDataViewRenderer::wxDataViewRenderer(const wxString& varianttype, + wxDataViewCellMode mode, + int align) + : wxDataViewRendererBase(varianttype, mode, align), + m_alignment(align), + m_mode(mode), + m_NativeDataPtr(NULL) { } @@ -2241,6 +2231,15 @@ wxEllipsizeMode wxDataViewRenderer::GetEllipsizeMode() const return GetNativeData()->GetEllipsizeMode(); } +void wxDataViewRenderer::OSXOnCellChanged(const wxVariant& value, + const wxDataViewItem& item, + unsigned col) +{ + wxDataViewModel *model = GetOwner()->GetOwner()->GetModel(); + model->SetValue(value, item, col); + model->ValueChanged(item, col); +} + IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase) // --------------------------------------------------------- @@ -2477,6 +2476,20 @@ bool wxDataViewIconTextRenderer::MacRender() } } +void +wxDataViewIconTextRenderer::OSXOnCellChanged(const wxVariant& value, + const wxDataViewItem& item, + unsigned col) +{ + // we receive just the text (because it's the only component which can be + // edited by user) from the native control but we need wxDataViewIconText + // for the model, so construct it here + wxVariant valueIconText; + valueIconText << wxDataViewIconText(value.GetString()); + + wxDataViewRenderer::OSXOnCellChanged(valueIconText, item, col); +} + IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer) // ---------------------------------------------------------