+ pi = pi->GetNext();
+ }
+
+ const wxClassInfo** parents = GetParents();
+ for ( int i = 0; parents[i]; ++ i )
+ {
+ parents[i]->GetProperties( infomap );
+ }
+}
+
+wxObject* wxClassInfo::AnyToObjectPtr( const wxAny &data) const
+{
+ return m_variantOfPtrToObjectConverter(data);
+}
+
+void wxClassInfo::CallOnAny( const wxAny &data, wxObjectFunctor* functor ) const
+{
+ if ( data.GetTypeInfo()->GetKind() == wxT_OBJECT )
+ return m_variantToObjectConverter(data, functor);
+ else
+ return (*functor)(m_variantOfPtrToObjectConverter(data));
+}
+
+wxAny wxClassInfo::ObjectPtrToAny( wxObject* obj) const
+{
+ return m_objectToVariantConverter(obj);
+}
+
+bool wxClassInfo::NeedsDirectConstruction() const
+{
+ return wx_dynamic_cast(wxObjectAllocator*, m_constructor) != NULL;
+}
+
+// ----------------------------------------------------------------------------
+// wxDynamicObject support
+// ----------------------------------------------------------------------------
+
+// Dynamic Objects are objects that have a real superclass instance and carry their
+// own attributes in a hash map. Like this it is possible to create the objects and
+// stream them, as if their class information was already available from compiled data
+
+struct wxDynamicObject::wxDynamicObjectInternal
+{
+ wxDynamicObjectInternal() {}
+
+ wxStringToAnyHashMap m_properties;
+};
+
+typedef list< wxDynamicObject* > wxDynamicObjectList;
+
+struct wxDynamicClassInfo::wxDynamicClassInfoInternal
+{
+ wxDynamicObjectList m_dynamicObjects;
+};
+
+// instantiates this object with an instance of its superclass
+wxDynamicObject::wxDynamicObject(wxObject* superClassInstance, const wxDynamicClassInfo *info)
+{
+ m_superClassInstance = superClassInstance;
+ m_classInfo = info;
+ m_data = new wxDynamicObjectInternal;
+}
+
+wxDynamicObject::~wxDynamicObject()
+{
+ wx_dynamic_cast(const wxDynamicClassInfo*, m_classInfo)->
+ m_data->m_dynamicObjects.remove( this );
+ delete m_data;
+ delete m_superClassInstance;
+}
+
+void wxDynamicObject::SetProperty (const wxChar *propertyName, const wxAny &value)
+{
+ wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
+ wxT("Accessing Unknown Property in a Dynamic Object") );
+ m_data->m_properties[propertyName] = value;
+}
+
+wxAny wxDynamicObject::GetProperty (const wxChar *propertyName) const
+{
+ wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
+ wxT("Accessing Unknown Property in a Dynamic Object") );
+ return m_data->m_properties[propertyName];
+}
+
+void wxDynamicObject::RemoveProperty( const wxChar *propertyName )
+{
+ wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
+ wxT("Removing Unknown Property in a Dynamic Object") );
+ m_data->m_properties.erase( propertyName );
+}
+
+void wxDynamicObject::RenameProperty( const wxChar *oldPropertyName,
+ const wxChar *newPropertyName )
+{
+ wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(oldPropertyName),
+ wxT("Renaming Unknown Property in a Dynamic Object") );
+
+ wxAny value = m_data->m_properties[oldPropertyName];
+ m_data->m_properties.erase( oldPropertyName );
+ m_data->m_properties[newPropertyName] = value;
+}
+
+
+// ----------------------------------------------------------------------------
+// wxDynamicClassInfo
+// ----------------------------------------------------------------------------
+
+wxDynamicClassInfo::wxDynamicClassInfo( const wxChar *unitName,
+ const wxChar *className,
+ const wxClassInfo* superClass ) :
+ wxClassInfo( unitName, className, new const wxClassInfo*[2])
+{
+ GetParents()[0] = superClass;
+ GetParents()[1] = NULL;
+ m_data = new wxDynamicClassInfoInternal;
+}
+
+wxDynamicClassInfo::~wxDynamicClassInfo()
+{
+ delete[] GetParents();
+ delete m_data;
+}
+
+wxObject *wxDynamicClassInfo::AllocateObject() const
+{
+ wxObject* parent = GetParents()[0]->AllocateObject();
+ wxDynamicObject *obj = new wxDynamicObject( parent, this );
+ m_data->m_dynamicObjects.push_back( obj );
+ return obj;
+}
+
+bool wxDynamicClassInfo::Create (wxObject *object, int paramCount, wxAny *params) const
+{
+ wxDynamicObject *dynobj = wx_dynamic_cast( wxDynamicObject *, object );
+ wxASSERT_MSG( dynobj,
+ wxT("cannot call wxDynamicClassInfo::Create on ")
+ wxT("an object other than wxDynamicObject") );
+
+ return GetParents()[0]->Create( dynobj->GetSuperClassInstance(), paramCount, params );
+}
+
+// get number of parameters for constructor
+int wxDynamicClassInfo::GetCreateParamCount() const
+{
+ return GetParents()[0]->GetCreateParamCount();
+}
+
+// get i-th constructor parameter
+const wxChar* wxDynamicClassInfo::GetCreateParamName(int i) const
+{
+ return GetParents()[0]->GetCreateParamName( i );
+}
+
+void wxDynamicClassInfo::SetProperty(wxObject *object, const wxChar *propertyName, const wxAny &value) const
+{
+ wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
+ wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
+ if ( FindPropertyInfoInThisClass(propertyName) )
+ dynobj->SetProperty( propertyName, value );
+ else
+ GetParents()[0]->SetProperty( dynobj->GetSuperClassInstance(), propertyName, value );
+}
+
+wxAny wxDynamicClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const
+{
+ wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
+ wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
+ if ( FindPropertyInfoInThisClass(propertyName) )
+ return dynobj->GetProperty( propertyName );
+ else
+ return GetParents()[0]->GetProperty( dynobj->GetSuperClassInstance(), propertyName );
+}
+
+void wxDynamicClassInfo::AddProperty( const wxChar *propertyName, const wxTypeInfo* typeInfo )
+{
+ EnsureInfosInited();
+ new wxPropertyInfo( m_firstProperty, this, propertyName, typeInfo->GetTypeName(), new wxGenericPropertyAccessor( propertyName ), wxAny() );
+}
+
+void wxDynamicClassInfo::AddHandler( const wxChar *handlerName, wxObjectEventFunction address, const wxClassInfo* eventClassInfo )
+{
+ EnsureInfosInited();
+ new wxHandlerInfo( m_firstHandler, this, handlerName, address, eventClassInfo );
+}
+
+// removes an existing runtime-property
+void wxDynamicClassInfo::RemoveProperty( const wxChar *propertyName )
+{
+ for ( wxDynamicObjectList::iterator iter = m_data->m_dynamicObjects.begin(); iter != m_data->m_dynamicObjects.end(); ++iter )
+ (*iter)->RemoveProperty( propertyName );
+ delete FindPropertyInfoInThisClass(propertyName);
+}
+
+// removes an existing runtime-handler
+void wxDynamicClassInfo::RemoveHandler( const wxChar *handlerName )
+{
+ delete FindHandlerInfoInThisClass(handlerName);
+}
+
+// renames an existing runtime-property
+void wxDynamicClassInfo::RenameProperty( const wxChar *oldPropertyName, const wxChar *newPropertyName )
+{
+ wxPropertyInfo* pi = FindPropertyInfoInThisClass(oldPropertyName);
+ wxASSERT_MSG( pi,wxT("not existing property") );
+ pi->m_name = newPropertyName;
+ wx_dynamic_cast(wxGenericPropertyAccessor*, pi->GetAccessor())->RenameProperty( oldPropertyName, newPropertyName );
+ for ( wxDynamicObjectList::iterator iter = m_data->m_dynamicObjects.begin(); iter != m_data->m_dynamicObjects.end(); ++iter )
+ (*iter)->RenameProperty( oldPropertyName, newPropertyName );
+}
+
+// renames an existing runtime-handler
+void wxDynamicClassInfo::RenameHandler( const wxChar *oldHandlerName, const wxChar *newHandlerName )
+{
+ wxASSERT_MSG(FindHandlerInfoInThisClass(oldHandlerName),wxT("not existing handler") );
+ FindHandlerInfoInThisClass(oldHandlerName)->m_name = newHandlerName;
+}
+
+// ----------------------------------------------------------------------------
+// wxGenericPropertyAccessor
+// ----------------------------------------------------------------------------
+
+struct wxGenericPropertyAccessor::wxGenericPropertyAccessorInternal
+{
+ char filler;
+};
+
+wxGenericPropertyAccessor::wxGenericPropertyAccessor( const wxString& propertyName )
+: wxPropertyAccessor( NULL, NULL, NULL, NULL )
+{
+ m_data = new wxGenericPropertyAccessorInternal;
+ m_propertyName = propertyName;
+ m_getterName = wxT("Get")+propertyName;
+ m_setterName = wxT("Set")+propertyName;
+}
+
+wxGenericPropertyAccessor::~wxGenericPropertyAccessor()
+{
+ delete m_data;
+}
+
+void wxGenericPropertyAccessor::SetProperty(wxObject *object, const wxAny &value) const
+{
+ wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
+ wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
+ dynobj->SetProperty(m_propertyName, value );
+}
+
+void wxGenericPropertyAccessor::GetProperty(const wxObject *object, wxAny& value) const
+{
+ const wxDynamicObject* dynobj = wx_dynamic_cast( const wxDynamicObject * , object );
+ wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
+ value = dynobj->GetProperty( m_propertyName );
+}
+
+// ----------------------------------------------------------------------------
+// wxGenericPropertyAccessor
+// ----------------------------------------------------------------------------
+
+wxString wxAnyGetAsString( const wxAny& data)
+{
+ if ( data.IsNull() || data.GetTypeInfo()==NULL )
+ return wxEmptyString;
+
+ wxString s;
+ data.GetTypeInfo()->ConvertToString(data,s);
+ return s;
+}
+
+const wxObject* wxAnyGetAsObjectPtr( const wxAny& data)
+{
+ if ( !data.IsNull() )
+ {
+ const wxClassTypeInfo* ti = wx_dynamic_cast(const wxClassTypeInfo*, data.GetTypeInfo());
+ if( ti )
+ return ti->GetClassInfo()->AnyToObjectPtr(data);
+ }
+ return NULL;
+}
+
+wxObjectFunctor::~wxObjectFunctor()
+{};
+
+#endif // wxUSE_EXTENDED_RTTI