]> git.saurik.com Git - wxWidgets.git/commitdiff
Rewrite handling cell value changes in wxOSX/Cocoa wxDVC.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 17 Oct 2009 01:04:26 +0000 (01:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 17 Oct 2009 01:04:26 +0000 (01:04 +0000)
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

include/wx/osx/dataview.h
src/osx/cocoa/dataview.mm

index a48488022293442a66f429eecf7f7d03cb19d432..42df0c23c6704ae25a6277d9580d85fb15d279f7 100644 (file)
@@ -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)
index c5b3635ad9d0c936f6767eea23b9263209227fd0..243ac2515ccc8b12a73395cd20ccd0b9ddc6bc68 100644 (file)
@@ -516,47 +516,31 @@ outlineView:(NSOutlineView*)outlineView
 
     wxDataViewItem dataViewItem([((wxPointerObject*) item) pointer]);
 
-
-    if (((dynamic_cast<wxDataViewTextRenderer*>(col->GetRenderer()) != NULL) || (dynamic_cast<wxDataViewIconTextRenderer*>(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<wxDataViewChoiceRenderer*>(col->GetRenderer()) != NULL)
-    {
-        if ([object isKindOfClass:[NSNumber class]] == YES)
-        {
-            model->SetValue(wxVariant(dynamic_cast<wxDataViewChoiceRenderer*>(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<wxDataViewDateRenderer*>(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<wxDataViewToggleRenderer*>(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)
 
 // ---------------------------------------------------------