+void wxWriter::FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler)
+{
+ wxList *dynamicEvents = evSource->GetDynamicEventTable() ;
+
+ if ( dynamicEvents )
+ {
+ wxList::compatibility_iterator node = dynamicEvents->GetFirst();
+ while (node)
+ {
+ wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
+
+ // find the match
+ if ( entry->m_fn &&
+ (dti->GetEventType() == entry->m_eventType) &&
+ (entry->m_id == -1 ) &&
+ (entry->m_eventSink != NULL ) )
+ {
+ sink = entry->m_eventSink ;
+ const wxClassInfo* sinkClassInfo = sink->GetClassInfo() ;
+ const wxHandlerInfo* sinkHandler = sinkClassInfo->GetFirstHandler() ;
+ while ( sinkHandler )
+ {
+ if ( sinkHandler->GetEventFunction() == entry->m_fn )
+ {
+ handler = sinkHandler ;
+ break ;
+ }
+ sinkHandler = sinkHandler->GetNext() ;
+ }
+ break ;
+ }
+ node = node->GetNext();
+ }
+ }
+}
+void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data )
+{
+ wxPropertyInfoMap map ;
+ ci->GetProperties( map ) ;
+ for ( int i = 0 ; i < ci->GetCreateParamCount() ; ++i )
+ {
+ wxString name = ci->GetCreateParamName(i) ;
+ const wxPropertyInfo* prop = map.find(name)->second ;
+ if ( prop )
+ {
+ WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+ }
+ else
+ {
+ wxLogError( _("Create Parameter not found in declared RTTI Parameters") ) ;
+ }
+ map.erase( name ) ;
+ }
+ { // Extra block for broken compilers
+ for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
+ {
+ const wxPropertyInfo* prop = iter->second ;
+ if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
+ {
+ WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+ }
+ }
+ }
+ { // Extra block for broken compilers
+ for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
+ {
+ const wxPropertyInfo* prop = iter->second ;
+ if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
+ {
+ WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+ }
+ }
+ }
+}
+
+void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *WXUNUSED(data) )
+{
+ if ( pi->GetFlags() & wxPROP_DONT_STREAM )
+ return ;
+
+ // make sure that we are picking the correct object for accessing the property
+ const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (obj ) ;
+ if ( dynobj && (dynamic_cast<const wxDynamicClassInfo*>(ci) == NULL) )
+ obj = dynobj->GetSuperClassInstance() ;
+
+ if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
+ {
+ wxxVariantArray data ;
+ pi->GetAccessor()->GetPropertyCollection(obj, data) ;
+ const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ;
+ for ( size_t i = 0 ; i < data.GetCount() ; ++i )
+ {
+ if ( i == 0 )
+ DoBeginWriteProperty( pi ) ;
+
+ DoBeginWriteElement() ;
+ wxxVariant value = data[i] ;
+ if ( persister->BeforeWriteProperty( this , obj, pi , value ) )
+ {
+ const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ;
+ if ( cti )
+ {
+ const wxClassInfo* pci = cti->GetClassInfo() ;
+ wxObject *vobj = pci->VariantToInstance( value ) ;
+ wxxVariantArray md ;
+ WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md ) ;
+ }
+ else
+ {
+ DoWriteSimpleType( value ) ;
+ }
+ }
+ DoEndWriteElement() ;
+ if ( i == data.GetCount() - 1 )
+ DoEndWriteProperty( pi ) ;
+ }
+ }
+ else
+ {
+ const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
+ if ( dti )
+ {
+ const wxObject* sink = NULL ;
+ const wxHandlerInfo *handler = NULL ;
+
+ const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ;
+ if ( evSource )
+ {
+ FindConnectEntry( evSource , dti , sink , handler ) ;
+ if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
+ {
+ if ( sink != NULL && handler != NULL )
+ {
+ DoBeginWriteProperty( pi ) ;
+ if ( IsObjectKnown( sink ) )
+ {
+ DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
+ DoEndWriteProperty( pi ) ;
+ }
+ else
+ {
+ wxLogError( _("Streaming delegates for not already streamed objects not yet supported") ) ;
+ }
+ }
+ }
+ }
+ else
+ {
+ wxLogError(_("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ;
+ }
+ }
+ else
+ {
+ wxxVariant value ;
+ pi->GetAccessor()->GetProperty(obj, value) ;
+
+ // avoid streaming out void objects
+ if( value.IsEmpty() )
+ return ;
+
+ if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
+ {
+ const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
+ if ( eti )
+ {
+ eti->ConvertFromLong( value.wxTEMPLATED_MEMBER_CALL(Get , long) , value ) ;
+ }
+ else
+ {
+ wxLogError( _("Type must have enum - long conversion") ) ;
+ }
+ }
+
+ // avoid streaming out default values
+ if ( pi->GetTypeInfo()->HasStringConverters() && !pi->GetDefaultValue().IsEmpty() )
+ {
+ if ( value.GetAsString() == pi->GetDefaultValue().GetAsString() )
+ return ;
+ }
+
+ // avoid streaming out null objects
+ const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
+
+ if ( cti && value.GetAsObject() == NULL )
+ return ;
+
+ if ( persister->BeforeWriteProperty( this , obj, pi , value ) )
+ {
+ DoBeginWriteProperty( pi ) ;
+ if ( cti )
+ {
+ const wxClassInfo* pci = cti->GetClassInfo() ;
+ wxObject *vobj = pci->VariantToInstance( value ) ;
+ if ( vobj && pi->GetTypeInfo()->HasStringConverters() )
+ {
+ wxString stringValue ;
+ cti->ConvertToString( value , stringValue ) ;
+ wxxVariant convertedValue(stringValue) ;
+ DoWriteSimpleType( convertedValue ) ;
+ }
+ else
+ {
+ wxxVariantArray md ;
+ WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
+ }
+ }
+ else
+ {
+ DoWriteSimpleType( value ) ;
+ }
+ DoEndWriteProperty( pi ) ;
+ }
+ }
+ }
+}
+
+int wxWriter::GetObjectID(const wxObject *obj)
+{
+ if ( !IsObjectKnown( obj ) )
+ return wxInvalidObjectID ;
+
+ return m_data->m_writtenObjects[obj] ;
+}
+
+bool wxWriter::IsObjectKnown( const wxObject *obj )
+{
+ return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ;
+}
+
+