#if wxOSX_USE_COCOA
// called when a value was edited by user
- virtual void OSXOnCellChanged(const wxVariant& value,
+ virtual void OSXOnCellChanged(NSObject *value,
const wxDataViewItem& item,
unsigned col);
#endif // Cocoa
//
virtual bool MacRender();
-protected:
+#if wxOSX_USE_COCOA
+ virtual void OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col);
+#endif // Cocoa
+
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer)
};
virtual bool MacRender();
#if wxOSX_USE_COCOA
- // called when a value was edited by user
- virtual void OSXOnCellChanged(const wxVariant& value,
+ virtual void OSXOnCellChanged(NSObject *value,
const wxDataViewItem& item,
unsigned col);
#endif // Cocoa
//
virtual bool MacRender();
-protected:
+#if wxOSX_USE_COCOA
+ virtual void OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col);
+#endif // Cocoa
+
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewToggleRenderer)
};
//
virtual bool MacRender();
-protected:
+#if wxOSX_USE_COCOA
+ virtual void OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col);
+#endif // Cocoa
+
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewProgressRenderer)
};
//
virtual bool MacRender();
-protected:
+#if wxOSX_USE_COCOA
+ virtual void OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col);
+#endif // Cocoa
+
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewDateRenderer)
};
namespace
{
+// convert from NSObject to different C++ types: all these functions check
+// that the conversion really makes sense and assert if it doesn't
+wxString ObjectToString(NSObject *object)
+{
+ wxCHECK_MSG( [object isKindOfClass:[NSString class]], "",
+ wxString::Format
+ (
+ "string expected but got %s",
+ wxCFStringRef::AsString([object className])
+ ));
+
+ return wxCFStringRef([((NSString*) object) retain]).AsString();
+}
+
+bool ObjectToBool(NSObject *object)
+{
+ // actually the value must be of NSCFBoolean class but it's private so we
+ // can't check for it directly
+ wxCHECK_MSG( [object isKindOfClass:[NSNumber class]], false,
+ wxString::Format
+ (
+ "number expected but got %s",
+ wxCFStringRef::AsString([object className])
+ ));
+
+ return [(NSNumber *)object boolValue];
+}
+
+long ObjectToLong(NSObject *object)
+{
+ wxCHECK_MSG( [object isKindOfClass:[NSNumber class]], -1,
+ wxString::Format
+ (
+ "number expected but got %s",
+ wxCFStringRef::AsString([object className])
+ ));
+
+ return [(NSNumber *)object longValue];
+}
+
+wxDateTime ObjectToDate(NSObject *object)
+{
+ wxCHECK_MSG( [object isKindOfClass:[NSDate class]], wxInvalidDateTime,
+ wxString::Format
+ (
+ "date expected but got %s",
+ wxCFStringRef::AsString([object className])
+ ));
+
+ // 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);
+
+ return dt;
+}
+
NSInteger CompareItems(id item1, id item2, void* context)
{
NSArray* const sortDescriptors = (NSArray*) context;
wxDataViewItem dataViewItem([((wxPointerObject*) item) pointer]);
- 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]] )
- {
- // 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());
+ OSXOnCellChanged(object, dataViewItem, col->GetModelColumn());
}
-(void) outlineView:(NSOutlineView*)outlineView sortDescriptorsDidChange:(NSArray*)oldDescriptors
return GetNativeData()->GetEllipsizeMode();
}
-void wxDataViewRenderer::OSXOnCellChanged(const wxVariant& value,
- const wxDataViewItem& item,
- unsigned col)
+void
+wxDataViewRenderer::OSXOnCellChanged(NSObject *object,
+ const wxDataViewItem& item,
+ unsigned col)
{
+ // TODO: we probably should get rid of this code entirely and make this
+ // function pure virtual, but currently we still have some native
+ // renderers (wxDataViewChoiceRenderer) which don't override it and
+ // there is also wxDataViewCustomRenderer for which it's not obvious
+ // how it should be implemented so keep this "auto-deduction" of
+ // variant type from NSObject for now
+
+ wxVariant value;
+ if ( [object isKindOfClass:[NSString class]] )
+ value = ObjectToString(object);
+ else if ( [object isKindOfClass:[NSNumber class]] )
+ value = ObjectToLong(object);
+ else if ( [object isKindOfClass:[NSDate class]] )
+ value = ObjectToDate(object);
+ else
+ {
+ wxFAIL_MSG( wxString::Format
+ (
+ "unknown value type %s",
+ wxCFStringRef::AsString([object className])
+ ));
+ return;
+ }
+
wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
model->ChangeValue(value, item, col);
}
}
}
+void
+wxDataViewTextRenderer::OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col)
+{
+ wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+ model->ChangeValue(ObjectToString(value), item, col);
+}
+
IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer)
// ---------------------------------------------------------
}
}
+void
+wxDataViewDateRenderer::OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col)
+{
+ wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+ model->ChangeValue(ObjectToDate(value), item, col);
+}
+
IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
// ---------------------------------------------------------
}
void
-wxDataViewIconTextRenderer::OSXOnCellChanged(const wxVariant& value,
+wxDataViewIconTextRenderer::OSXOnCellChanged(NSObject *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());
+ valueIconText << wxDataViewIconText(ObjectToString(value));
- wxDataViewRenderer::OSXOnCellChanged(valueIconText, item, col);
+ wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+ model->ChangeValue(valueIconText, item, col);
}
IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
}
}
+void
+wxDataViewToggleRenderer::OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col)
+{
+ wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+ model->ChangeValue(ObjectToBool(value), item, col);
+}
+
IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
// ---------------------------------------------------------
}
}
+void
+wxDataViewProgressRenderer::OSXOnCellChanged(NSObject *value,
+ const wxDataViewItem& item,
+ unsigned col)
+{
+ wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+ model->ChangeValue(ObjectToLong(value), item, col);
+}
+
IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
// ---------------------------------------------------------