]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/xtixml.cpp
added wxWS_EX_VALIDATE_RECURSIVELY
[wxWidgets.git] / src / common / xtixml.cpp
index 94dcc08ebee97e1aad517069fb31f4a3d09c4dcd..26fe3ac6cff03389c5e4ef733ef38308aa6d0257 100644 (file)
@@ -1,8 +1,8 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/common/xtistrm.cpp
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/common/xtistrm.cpp
-// Purpose:     streaming runtime metadata information 
+// Purpose:     streaming runtime metadata information
 // Author:      Stefan Csomor
 // Author:      Stefan Csomor
-// Modified by: 
+// Modified by:
 // Created:     27/07/03
 // RCS-ID:      $Id$
 // Copyright:   (c) 2003 Stefan Csomor
 // Created:     27/07/03
 // RCS-ID:      $Id$
 // Copyright:   (c) 2003 Stefan Csomor
 
 #include "wx/xml/xml.h"
 #include "wx/tokenzr.h"
 
 #include "wx/xml/xml.h"
 #include "wx/tokenzr.h"
-#include "wx/xtistrm.h"
-#include "wx/xtixml.h"
 #include "wx/txtstrm.h"
 #include "wx/event.h"
 
 #if wxUSE_EXTENDED_RTTI
 
 #include "wx/txtstrm.h"
 #include "wx/event.h"
 
 #if wxUSE_EXTENDED_RTTI
 
+#include "wx/xtistrm.h"
+#include "wx/xtixml.h"
+
 #include "wx/beforestd.h"
 #include <map>
 #include <vector>
 #include "wx/beforestd.h"
 #include <map>
 #include <vector>
@@ -44,13 +45,13 @@ using namespace std ;
 
 //
 // XML Streaming
 
 //
 // XML Streaming
-// 
+//
 
 // convenience functions
 
 void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
 {
 
 // convenience functions
 
 void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
 {
-    node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
+    node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxT("value"), data ) );
 }
 
 wxString wxXmlGetContentFromNode( wxXmlNode *node )
 }
 
 wxString wxXmlGetContentFromNode( wxXmlNode *node )
@@ -80,23 +81,23 @@ struct wxXmlWriter::wxXmlWriterInternal
     }
 } ;
 
     }
 } ;
 
-wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode ) 
+wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode )
 {
     m_data = new wxXmlWriterInternal() ;
     m_data->m_root = rootnode ;
     m_data->m_current = rootnode ;
 }
 
 {
     m_data = new wxXmlWriterInternal() ;
     m_data->m_root = rootnode ;
     m_data->m_current = rootnode ;
 }
 
-wxXmlWriter::~wxXmlWriter() 
+wxXmlWriter::~wxXmlWriter()
 {
     delete m_data ;
 }
 
 {
     delete m_data ;
 }
 
-void wxXmlWriter::DoBeginWriteTopLevelEntry( const wxString &name ) 
+void wxXmlWriter::DoBeginWriteTopLevelEntry( const wxString &name )
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("entry"));
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("entry"));
-    pnode->AddProperty(wxString("name"), name);
+    pnode->AddProperty(wxString(wxT("name")), name);
     m_data->m_current->AddChild(pnode) ;
     m_data->Push( pnode ) ;
 }
     m_data->m_current->AddChild(pnode) ;
     m_data->Push( pnode ) ;
 }
@@ -106,12 +107,12 @@ void wxXmlWriter::DoEndWriteTopLevelEntry( const wxString &WXUNUSED(name) )
     m_data->Pop() ;
 }
 
     m_data->Pop() ;
 }
 
-void wxXmlWriter::DoBeginWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *classInfo, int objectID , wxxVariantArray &metadata   ) 
+void wxXmlWriter::DoBeginWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *classInfo, int objectID , wxxVariantArray &metadata   )
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
     pnode->AddProperty(wxT("class"), wxString(classInfo->GetClassName()));
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
     pnode->AddProperty(wxT("class"), wxString(classInfo->GetClassName()));
-    pnode->AddProperty(wxT("id"), wxString::Format( "%d" , objectID ) );
+    pnode->AddProperty(wxT("id"), wxString::Format( wxT("%d") , objectID ) );
 
     for ( size_t i = 0 ; i < metadata.GetCount() ; ++i )
     {
 
     for ( size_t i = 0 ; i < metadata.GetCount() ; ++i )
     {
@@ -122,26 +123,26 @@ void wxXmlWriter::DoBeginWriteObject(const wxObject *WXUNUSED(object), const wxC
 }
 
 // end of writing the root object
 }
 
 // end of writing the root object
-void wxXmlWriter::DoEndWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *WXUNUSED(classInfo), int WXUNUSED(objectID) ) 
+void wxXmlWriter::DoEndWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *WXUNUSED(classInfo), int WXUNUSED(objectID) )
 {
     m_data->Pop() ;
 }
 
 // writes a property in the stream format
 {
     m_data->Pop() ;
 }
 
 // writes a property in the stream format
-void wxXmlWriter::DoWriteSimpleType( wxxVariant &value ) 
+void wxXmlWriter::DoWriteSimpleType( wxxVariant &value )
 {
     wxXmlAddContentToNode( m_data->m_current ,value.GetAsString() ) ;
 }
 
 {
     wxXmlAddContentToNode( m_data->m_current ,value.GetAsString() ) ;
 }
 
-void wxXmlWriter::DoBeginWriteElement() 
+void wxXmlWriter::DoBeginWriteElement()
 {
     wxXmlNode *pnode;
 {
     wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, "element" );
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("element") );
     m_data->m_current->AddChild(pnode) ;
     m_data->Push( pnode ) ;
 }
 
     m_data->m_current->AddChild(pnode) ;
     m_data->Push( pnode ) ;
 }
 
-void wxXmlWriter::DoEndWriteElement() 
+void wxXmlWriter::DoEndWriteElement()
 {
     m_data->Pop() ;
 }
 {
     m_data->Pop() ;
 }
@@ -149,7 +150,7 @@ void wxXmlWriter::DoEndWriteElement()
 void wxXmlWriter::DoBeginWriteProperty(const wxPropertyInfo *pi )
 {
     wxXmlNode *pnode;
 void wxXmlWriter::DoBeginWriteProperty(const wxPropertyInfo *pi )
 {
     wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, "prop" );
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("prop") );
     pnode->AddProperty(wxT("name"), pi->GetName() );
     m_data->m_current->AddChild(pnode) ;
     m_data->Push( pnode ) ;
     pnode->AddProperty(wxT("name"), pi->GetName() );
     m_data->m_current->AddChild(pnode) ;
     m_data->Push( pnode ) ;
@@ -163,16 +164,16 @@ void wxXmlWriter::DoEndWriteProperty(const wxPropertyInfo *WXUNUSED(propInfo) )
 
 
 // insert an object reference to an already written object
 
 
 // insert an object reference to an already written object
-void wxXmlWriter::DoWriteRepeatedObject( int objectID ) 
+void wxXmlWriter::DoWriteRepeatedObject( int objectID )
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
-    pnode->AddProperty(wxString("href"), wxString::Format( "%d" , objectID ) );
+    pnode->AddProperty(wxString(wxT("href")), wxString::Format( wxT("%d") , objectID ) );
     m_data->m_current->AddChild(pnode) ;
 }
 
 // insert a null reference
     m_data->m_current->AddChild(pnode) ;
 }
 
 // insert a null reference
-void wxXmlWriter::DoWriteNullObject() 
+void wxXmlWriter::DoWriteNullObject()
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
 {
     wxXmlNode *pnode;
     pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
@@ -180,26 +181,26 @@ void wxXmlWriter::DoWriteNullObject()
 }
 
 // writes a delegate in the stream format
 }
 
 // writes a delegate in the stream format
-void wxXmlWriter::DoWriteDelegate( const wxObject *WXUNUSED(object),  const wxClassInfo* WXUNUSED(classInfo) , const wxPropertyInfo *WXUNUSED(pi) , 
-                                  const wxObject *eventSink, int sinkObjectID , const wxClassInfo* WXUNUSED(eventSinkClassInfo) , const wxHandlerInfo* handlerInfo ) 
+void wxXmlWriter::DoWriteDelegate( const wxObject *WXUNUSED(object),  const wxClassInfo* WXUNUSED(classInfo) , const wxPropertyInfo *WXUNUSED(pi) ,
+                                  const wxObject *eventSink, int sinkObjectID , const wxClassInfo* WXUNUSED(eventSinkClassInfo) , const wxHandlerInfo* handlerInfo )
 {
     if ( eventSink != NULL && handlerInfo != NULL )
     {
 {
     if ( eventSink != NULL && handlerInfo != NULL )
     {
-        wxXmlAddContentToNode( m_data->m_current ,wxString::Format(wxT("%d.%s"), sinkObjectID , handlerInfo->GetName()) ) ;
+        wxXmlAddContentToNode( m_data->m_current ,wxString::Format(wxT("%d.%s"), sinkObjectID , handlerInfo->GetName().c_str()) ) ;
     }
 }
 
 // ----------------------------------------------------------------------------
     }
 }
 
 // ----------------------------------------------------------------------------
-// reading objects in 
+// reading objects in
 // ----------------------------------------------------------------------------
 
 
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 
 
 
 // ----------------------------------------------------------------------------
-// reading xml in 
+// reading xml in
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 
-/* 
+/*
 Reading components has not to be extended for components
 as properties are always sought by typeinfo over all levels
 and create params are always toplevel class only
 Reading components has not to be extended for components
 as properties are always sought by typeinfo over all levels
 and create params are always toplevel class only
@@ -222,34 +223,54 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
     if (!children)
     {
         // check for a null object or href
     if (!children)
     {
         // check for a null object or href
-        if (node->GetPropVal("href" , &ObjectIdString ) )
+        if (node->GetPropVal(wxT("href") , &ObjectIdString ) )
         {
         {
-            objectID = atoi( ObjectIdString.c_str() ) ;
-            wxASSERT_MSG( HasObjectClassInfo( objectID ) , wxT("Forward hrefs are not supported") ) ;
-            return objectID ;
+            objectID = atoi( ObjectIdString.ToAscii() ) ;
+            if ( HasObjectClassInfo( objectID ) )
+            {
+                return objectID ;
+            }
+            else
+            {
+                wxLogError( _("Forward hrefs are not supported") ) ;
+                return wxInvalidObjectID ;
+            }
         }
         }
-        if ( !node->GetPropVal("id" , &ObjectIdString ) )
+        if ( !node->GetPropVal(wxT("id") , &ObjectIdString ) )
         {
             return wxNullObjectID;
         }
     }
         {
             return wxNullObjectID;
         }
     }
-    if (!node->GetPropVal("class", &className))
+    if (!node->GetPropVal(wxT("class"), &className))
     {
         // No class name.  Eek. FIXME: error handling
         return wxInvalidObjectID;
     }
     classInfo = wxClassInfo::FindClass(className);
     {
         // No class name.  Eek. FIXME: error handling
         return wxInvalidObjectID;
     }
     classInfo = wxClassInfo::FindClass(className);
-    wxASSERT_MSG( classInfo , wxString::Format(wxT("unknown class %s"),className ) ) ;
-    wxASSERT_MSG( !children || children->GetType() != wxXML_TEXT_NODE , wxT("objects cannot have XML Text Nodes") ) ;
-    if (!node->GetPropVal("id", &ObjectIdString))
+    if ( classInfo == NULL )
+    {
+        wxLogError( wxString::Format(_("unknown class %s"),className ) ) ;
+        return wxInvalidObjectID ;
+    }
+
+    if ( children != NULL && children->GetType() == wxXML_TEXT_NODE )
     {
     {
-        wxASSERT_MSG(0,wxT("Objects must have an id attribute") ) ;
+        wxLogError(_("objects cannot have XML Text Nodes") ) ;
+        return wxInvalidObjectID;
+    }
+    if (!node->GetPropVal(wxT("id"), &ObjectIdString))
+    {
+        wxLogError(_("Objects must have an id attribute") ) ;
         // No object id.  Eek. FIXME: error handling
         return wxInvalidObjectID;
     }
         // No object id.  Eek. FIXME: error handling
         return wxInvalidObjectID;
     }
-    objectID = atoi( ObjectIdString.c_str() ) ;
+    objectID = atoi( ObjectIdString.ToAscii() ) ;
     // is this object already has been streamed in, return it here
     // is this object already has been streamed in, return it here
-    wxASSERT_MSG( !HasObjectClassInfo( objectID ) , wxString::Format(wxT("Doubly used id : %d"), objectID ) ) ;
+    if ( HasObjectClassInfo( objectID ) )
+    {
+        wxLogError ( wxString::Format(_("Doubly used id : %d"), objectID ) ) ;
+        return wxInvalidObjectID ;
+    }
 
     // new object, start with allocation
     // first make the object know to our internal registry
 
     // new object, start with allocation
     // first make the object know to our internal registry
@@ -259,23 +280,28 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
     wxXmlProperty *xp = node->GetProperties() ;
     while ( xp )
     {
     wxXmlProperty *xp = node->GetProperties() ;
     while ( xp )
     {
-        if ( xp->GetName() != wxString("class") && xp->GetName() != wxString("id") )
+        if ( xp->GetName() != wxString(wxT("class")) && xp->GetName() != wxString(wxT("id")) )
         {
             metadata.Add( new wxxVariant( xp->GetValue() , xp->GetName() ) ) ;
         }
         xp = xp->GetNext() ;
     }
         {
             metadata.Add( new wxxVariant( xp->GetValue() , xp->GetName() ) ) ;
         }
         xp = xp->GetNext() ;
     }
-    callbacks->AllocateObject(objectID, classInfo, metadata);
+    if ( !classInfo->NeedsDirectConstruction() )
+        callbacks->AllocateObject(objectID, classInfo, metadata);
 
 
-    // 
+    //
     // stream back the Create parameters first
     createParams = new wxxVariant[ classInfo->GetCreateParamCount() ] ;
     createParamOids = new int[classInfo->GetCreateParamCount() ] ;
     createClassInfos = new const wxClassInfo*[classInfo->GetCreateParamCount() ] ;
 
     // stream back the Create parameters first
     createParams = new wxxVariant[ classInfo->GetCreateParamCount() ] ;
     createParamOids = new int[classInfo->GetCreateParamCount() ] ;
     createClassInfos = new const wxClassInfo*[classInfo->GetCreateParamCount() ] ;
 
+#if wxUSE_UNICODE
+    typedef map<wstring, wxXmlNode *> PropertyNodes ;
+    typedef vector<wstring> PropertyNames ;
+#else
     typedef map<string, wxXmlNode *> PropertyNodes ;
     typedef vector<string> PropertyNames ;
     typedef map<string, wxXmlNode *> PropertyNodes ;
     typedef vector<string> PropertyNames ;
-
+#endif
     PropertyNodes propertyNodes ;
     PropertyNames propertyNames ;
 
     PropertyNodes propertyNodes ;
     PropertyNames propertyNames ;
 
@@ -293,7 +319,10 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
         const wxChar* paramName = classInfo->GetCreateParamName(i) ;
         PropertyNodes::iterator propiter = propertyNodes.find( paramName ) ;
         const wxPropertyInfo* pi = classInfo->FindPropertyInfo( paramName ) ;
         const wxChar* paramName = classInfo->GetCreateParamName(i) ;
         PropertyNodes::iterator propiter = propertyNodes.find( paramName ) ;
         const wxPropertyInfo* pi = classInfo->FindPropertyInfo( paramName ) ;
-        wxASSERT_MSG(pi,wxString::Format("Unkown Property %s",paramName) ) ;
+        if ( pi == 0 )
+        {
+            wxLogError( wxString::Format(_("Unkown Property %s"),paramName) ) ;
+        }
         // if we don't have the value of a create param set in the xml
         // we use the default value
         if ( propiter != propertyNodes.end() )
         // if we don't have the value of a create param set in the xml
         // we use the default value
         if ( propiter != propertyNodes.end() )
@@ -311,11 +340,16 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
                 if( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
                 {
                     const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
                 if( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
                 {
                     const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
-                    wxASSERT_MSG( eti , wxT("Type must have enum - long conversion") ) ;
-
-                    long realval ;
-                    eti->ConvertToLong( createParams[i]  , realval ) ;
-                    createParams[i] = wxxVariant( realval ) ;
+                    if ( eti )
+                    {
+                        long realval ;
+                        eti->ConvertToLong( createParams[i]  , realval ) ;
+                        createParams[i] = wxxVariant( realval ) ;
+                    }
+                    else
+                    {
+                        wxLogError( _("Type must have enum - long conversion") ) ;
+                    }
                 }
                 createClassInfos[i] = NULL ;
             }
                 }
                 createClassInfos[i] = NULL ;
             }
@@ -324,21 +358,35 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
             {
                 if ( propertyNames[j] == paramName )
                 {
             {
                 if ( propertyNames[j] == paramName )
                 {
-                    propertyNames[j] = "" ;
+                    propertyNames[j] = wxEmptyString ;
                     break ;
                 }
             }
         }
         else
         {
                     break ;
                 }
             }
         }
         else
         {
-            createParams[i] = pi->GetDefaultValue() ;
+            if ( pi->GetTypeInfo()->IsObjectType() )
+            {
+                createParamOids[i] = wxNullObjectID ;
+                createClassInfos[i] = dynamic_cast<const wxClassTypeInfo*>(pi->GetTypeInfo())->GetClassInfo() ;
+            }
+            else
+            {
+                createParams[i] = pi->GetDefaultValue() ;
+                createParamOids[i] = wxInvalidObjectID ;
+            }
         }
     }
 
     // got the parameters.  Call the Create method
         }
     }
 
     // got the parameters.  Call the Create method
-    callbacks->CreateObject(objectID, classInfo,
-        classInfo->GetCreateParamCount(),
-        createParams, createParamOids, createClassInfos, metadata );
+    if ( classInfo->NeedsDirectConstruction() )
+        callbacks->ConstructObject(objectID, classInfo,
+            classInfo->GetCreateParamCount(),
+            createParams, createParamOids, createClassInfos, metadata );
+    else
+        callbacks->CreateObject(objectID, classInfo,
+            classInfo->GetCreateParamCount(),
+            createParams, createParamOids, createClassInfos, metadata );
 
     // now stream in the rest of the properties, in the sequence their properties were written in the xml
     for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
 
     // now stream in the rest of the properties, in the sequence their properties were written in the xml
     for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
@@ -356,7 +404,11 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
                     const wxTypeInfo * elementType = collType->GetElementType() ;
                     while( prop )
                     {
                     const wxTypeInfo * elementType = collType->GetElementType() ;
                     while( prop )
                     {
-                        wxASSERT_MSG(prop->GetName() == wxT("element") , wxT("A non empty collection must consist of 'element' nodes")) ;
+                        if ( prop->GetName() != wxT("element") )
+                        {
+                            wxLogError( _("A non empty collection must consist of 'element' nodes" ) ) ;
+                            break ;
+                        }
                         wxXmlNode* elementContent = prop->GetChildren() ;
                         if ( elementContent )
                         {
                         wxXmlNode* elementContent = prop->GetChildren() ;
                         if ( elementContent )
                         {
@@ -368,7 +420,7 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
                                 {
                                     if ( pi->GetAccessor()->HasAdder() )
                                         callbacks->AddToPropertyCollectionAsObject( objectID , classInfo , pi , valueId ) ;
                                 {
                                     if ( pi->GetAccessor()->HasAdder() )
                                         callbacks->AddToPropertyCollectionAsObject( objectID , classInfo , pi , valueId ) ;
-                                    // TODO for collections we must have a notation on taking over ownership or not 
+                                    // TODO for collections we must have a notation on taking over ownership or not
                                     if ( elementType->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
                                         callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
                                 }
                                     if ( elementType->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
                                         callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
                                 }
@@ -385,12 +437,26 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
                 }
                 else if ( pi->GetTypeInfo()->IsObjectType() )
                 {
                 }
                 else if ( pi->GetTypeInfo()->IsObjectType() )
                 {
-                    int valueId = ReadComponent( prop , callbacks ) ;
-                    if ( valueId != wxInvalidObjectID )
+                    // and object can either be streamed out a string or as an object
+                    // in case we have no node, then the object's streaming out has been vetoed
+                    if ( prop )
                     {
                     {
-                        callbacks->SetPropertyAsObject( objectID , classInfo , pi , valueId ) ;
-                        if ( pi->GetTypeInfo()->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
-                            callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
+                        if ( prop->GetName() == wxT("object") )
+                        {
+                            int valueId = ReadComponent( prop , callbacks ) ;
+                            if ( valueId != wxInvalidObjectID )
+                            {
+                                callbacks->SetPropertyAsObject( objectID , classInfo , pi , valueId ) ;
+                                if ( pi->GetTypeInfo()->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
+                                    callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
+                            }
+                        }
+                        else
+                        {
+                            wxASSERT( pi->GetTypeInfo()->HasStringConverters() ) ;
+                            wxxVariant nodeval = ReadValue( prop , pi->GetTypeInfo() ) ;
+                            callbacks->SetProperty( objectID, classInfo ,pi , nodeval ) ;
+                        }
                     }
                 }
                 else if ( pi->GetTypeInfo()->IsDelegateType() )
                     }
                 }
                 else if ( pi->GetTypeInfo()->IsDelegateType() )
@@ -399,20 +465,40 @@ int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
                     {
                         wxString resstring = prop->GetContent() ;
                         wxInt32 pos = resstring.Find('.') ;
                     {
                         wxString resstring = prop->GetContent() ;
                         wxInt32 pos = resstring.Find('.') ;
-                        assert( pos != wxNOT_FOUND ) ;
-                        int sinkOid = atol(resstring.Left(pos)) ;
-                        wxString handlerName = resstring.Mid(pos+1) ;
-                        wxClassInfo* sinkClassInfo = GetObjectClassInfo( sinkOid ) ;
+                        if ( pos != wxNOT_FOUND )
+                        {
+                            int sinkOid = atol(resstring.Left(pos).ToAscii()) ;
+                            wxString handlerName = resstring.Mid(pos+1) ;
+                            wxClassInfo* sinkClassInfo = GetObjectClassInfo( sinkOid ) ;
 
 
-                        callbacks->SetConnect( objectID , classInfo , dynamic_cast<const wxDelegateTypeInfo*>(pi->GetTypeInfo()) , sinkClassInfo ,
-                            sinkClassInfo->FindHandlerInfo(handlerName) ,  sinkOid ) ;
+                            callbacks->SetConnect( objectID , classInfo , pi , sinkClassInfo ,
+                                sinkClassInfo->FindHandlerInfo(handlerName) ,  sinkOid ) ;
+                        }
+                        else
+                        {
+                            wxLogError( _("incorrect event handler string, missing dot") ) ;
+                        }
                     }
 
                 }
                 else
                 {
                     }
 
                 }
                 else
                 {
-                    wxxVariant nodeval ;
-                    callbacks->SetProperty( objectID, classInfo ,pi , ReadValue( prop , pi->GetTypeInfo() ) ) ;
+                    wxxVariant nodeval = ReadValue( prop , pi->GetTypeInfo() ) ;
+                    if( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
+                    {
+                        const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
+                        if ( eti )
+                        {
+                            long realval ;
+                            eti->ConvertToLong( nodeval , realval ) ;
+                            nodeval = wxxVariant( realval ) ;
+                        }
+                        else
+                        {
+                            wxLogError( _("Type must have enum - long conversion") ) ;
+                        }
+                    }
+                    callbacks->SetProperty( objectID, classInfo ,pi , nodeval ) ;
                 }
             }
         }
                 }
             }
         }
@@ -442,7 +528,7 @@ int wxXmlReader::ReadObject( const wxString &name , wxDepersister *callbacks)
     while ( iter )
     {
         wxString entryName ;
     while ( iter )
     {
         wxString entryName ;
-        if ( iter->GetPropVal("name", &entryName) )
+        if ( iter->GetPropVal(wxT("name"), &entryName) )
         {
             if ( entryName == name )
                 return ReadComponent( iter->GetChildren() , callbacks ) ;
         {
             if ( entryName == name )
                 return ReadComponent( iter->GetChildren() , callbacks ) ;