]> git.saurik.com Git - wxWidgets.git/commitdiff
redistribution of code for different library parts
authorStefan Csomor <csomor@advancedconcepts.ch>
Sat, 23 Aug 2003 19:40:04 +0000 (19:40 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Sat, 23 Aug 2003 19:40:04 +0000 (19:40 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23142 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/flags.h
include/wx/xti.h
include/wx/xtistrm.h
include/wx/xtixml.h [new file with mode: 0644]
src/common/xti.cpp
src/common/xtistrm.cpp
src/common/xtixml.cpp [new file with mode: 0644]

index ec14d2c2b936ad3b6e53f3a918b60400ccdf58ab..94c1e265d548b991366c450d4754adbfd74f490b 100644 (file)
 #pragma interface "flags.h"
 #endif
 
+#include <bitset>
+
 // wxFlags should be applied to an enum, then this can be used like
 // bitwise operators but keeps the type safety and information, the
 // enums must be in a sequence , their value determines the bit position
 // that they represent
+// The api is made as close as possible to <bitset> 
 
 template <class T> class wxFlags
 {
        friend class wxEnumData ;
 public:
-    wxFlags(long val) { m_data = val ; }
+    // creates a wxFlags<> object with all flags initialized to 0
     wxFlags() { m_data = 0; }
+
+    // created a wxFlags<> object initialized according to the bits of the 
+    // integral value val
+    wxFlags(unsigned long val) { m_data = val ; }
+
+    // copies the content in the new wxFlags<> object from another one
     wxFlags(const wxFlags &src) { m_data = src.m_data; }
+
+    // creates a wxFlags<> object that has the specific flag set
     wxFlags(const T el) { m_data |= 1 << el; }
 
-    operator long() const { return m_data ; }
+    // returns the integral value that the bits of this object represent
+    unsigned long to_ulong() const { return m_data ; }
 
+    // assignment
     wxFlags &operator =(const wxFlags &rhs)
     {
                m_data = rhs.m_data;
                return *this;
     }
-    wxFlags &operator +=(const wxFlags &rhs) // union
+
+    // bitwise or operator, sets all bits that are in rhs and leaves
+    // the rest unchanged
+    wxFlags &operator |=(const wxFlags &rhs) 
     {
                m_data |= rhs.m_data;
                return *this;
     }
-    wxFlags &operator -=(const wxFlags &rhs) // difference
+
+    // bitwsie exclusive-or operator, toggles the value of all bits
+    // that are set in bits and leaves all others unchanged
+    wxFlags &operator ^=(const wxFlags &rhs) // difference
     {
                m_data ^= rhs.m_data;
                return *this;
     }
 
-    wxFlags &operator *=(const wxFlags &rhs) // intersection
+    // bitwise and operator, resets all bits that are not in rhs and leaves
+    // all others unchanged
+    wxFlags &operator &=(const wxFlags &rhs) // intersection
     {
                m_data &= rhs.m_data;
                return *this;
     }
 
-    wxFlags operator +(const wxFlags &rhs) const // union
+    // bitwise or operator, returns a new bitset that has all bits set that set are in 
+    // bitset2 or in this bitset
+   wxFlags operator |(const wxFlags &bitset2) const // union
     {
                wxFlags<T> s;
-               s.m_data = m_data | rhs.m_data;
+               s.m_data = m_data | bitset2.m_data;
                return s;
     }
-    wxFlags operator -(const wxFlags &rhs) const // difference
+
+    // bitwise exclusive-or operator, returns a new bitset that has all bits set that are set either in 
+    // bitset2 or in this bitset but not in both
+    wxFlags operator ^(const wxFlags &bitset2) const // difference
     {
                wxFlags<T> s;
-               s.m_data = m_data ^ rhs.m_data;
+               s.m_data = m_data ^ bitset2.m_data;
                return s;
     }
-    wxFlags operator *(const wxFlags &rhs) const // intersection
+
+    // bitwise and operator, returns a new bitset that has all bits set that are set both in 
+    // bitset2 and in this bitset
+    wxFlags operator &(const wxFlags &bitset2) const // intersection
     {
                wxFlags<T> s;
-               s.m_data = m_data & rhs.m_data;
+               s.m_data = m_data & bitset2.m_data;
                return s;
     }
 
-    wxFlags& Set(const T el) //Add element
+    // sets appropriate the bit to true
+    wxFlags& set(const T el) //Add element
     {
                m_data |= 1 << el;
                return *this;
     }
-    wxFlags& Clear(const T el) //remove element
+    
+    // clears the appropriate flag to false
+    wxFlags& reset(const T el) //remove element
     {
                m_data &= ~(1 << el);
                return *this;
     }
 
-    bool Contains(const T el) const
+    // clear all flags
+    wxFlags& reset()
     {
-               return (m_data & (1 << el)) ? true : false;
+               m_data = 0;
+               return *this;
     }
 
-    wxFlags &Clear()
+    // true if this flag is set
+    bool test(const T el) const
     {
-               m_data = 0;
-               return *this;
+               return (m_data & (1 << el)) ? true : false;
     }
 
-    bool Empty() const
+    // true if no flag is set
+    bool none() const
     {
                return m_data == 0;
     }
 
+    // true if any flag is set
+    bool any() const
+    {
+               return m_data != 0;
+    }
+
+    // true if both have the same flags
     bool operator ==(const wxFlags &rhs) const
     {
                return m_data == rhs.m_data;
     }
 
+    // true if both differ in their flags set
     bool operator !=(const wxFlags &rhs) const
     {
                return !operator==(rhs);
     }
+
+    bool operator[] (const T el) const { return test(el) ; }
+
 private :
-       int m_data;
+       unsigned long m_data;
 };
 
 
index 558b77c389c55de41ff2c18eb5d17372ed3a021a..0477ea5f64df81b6c1e6aa25ef55692bc9e69291 100644 (file)
@@ -167,7 +167,7 @@ template<typename e>
 void wxSetFromString(const wxString &s , wxFlags<e> &data )
 {
     wxEnumData* edata = wxGetEnumData((e) 0) ;
-    data.Clear() ;
+    data.reset() ;
 
     wxArrayString array ;
     wxSetStringToArray( s , array ) ;
@@ -178,7 +178,7 @@ void wxSetFromString(const wxString &s , wxFlags<e> &data )
         int ivalue ;
         if ( edata->HasEnumMemberValue( flag , &ivalue ) )
         {
-            data.Set( (e) ivalue ) ;
+            data.set( (e) ivalue ) ;
         }
     }
 }
@@ -193,7 +193,7 @@ void wxSetToString( wxString &s , const wxFlags<e> &data )
     for ( i = 0 ; i < count ; i++ )
     {
         e value = (e) edata->GetEnumMemberValueByIndex(i) ;
-        if ( data.Contains( value ) )
+        if ( data.test( value ) )
         {
             // this could also be done by the templated calls
             if ( !s.IsEmpty() )
@@ -215,8 +215,8 @@ void wxSetToString( wxString &s , const wxFlags<e> &data )
 { \
     wxSetToString( s , data ) ; \
 } \
-    void FromLong##SetName( long data , wxxVariant& result ) { result = wxxVariant(SetName(data)) ;} \
-    void ToLong##SetName( const wxxVariant& data , long &result ) { result = (long) data.Get<SetName>() ;} \
+    void FromLong##SetName( long data , wxxVariant& result ) { result = wxxVariant(SetName((unsigned long)data)) ;} \
+    void ToLong##SetName( const wxxVariant& data , long &result ) { result = (long) data.Get<SetName>().to_ulong() ;} \
 template<> const wxTypeInfo* wxGetTypeInfo( SetName * ) \
 { \
     static wxEnumTypeInfo s_typeInfo(wxT_SET , &s_enumData##e , &wxToStringConverter<SetName> , &wxFromStringConverter<SetName> , &ToLong##SetName , &FromLong##SetName, #SetName ) ; return &s_typeInfo ; \
@@ -749,6 +749,8 @@ enum {
     wxPROP_OBJECT_GRAPH     = 0x00000002 ,
     // this will only be streamed out and in as enum/set, the internal representation is still a long
     wxPROP_ENUM_STORE_LONG  = 0x00000004 ,
+    // don't stream out this property, needed eg to avoid streaming out children that are always created by their parents
+    wxPROP_DONT_STREAM = 0x00000008 ,
 }  ;
 
 class WXDLLIMPEXP_BASE wxPropertyInfo
@@ -838,7 +840,8 @@ WX_DECLARE_EXPORTED_STRING_HASH_MAP( wxPropertyInfo* , wxPropertyInfoMap ) ;
 #define WX_END_PROPERTIES_TABLE() \
     return first ; }
 
-
+#define WX_HIDE_PROPERTY( name ) \
+    static wxPropertyInfo _propertyInfo##name( first , class_t::GetClassInfoStatic() , #name , wxGetTypeInfo( (void*) NULL ) ,NULL , wxxVariant() , wxPROP_DONT_STREAM , wxEmptyString , wxEmptyString ) ;
 
 #define WX_PROPERTY( name , type , setter , getter ,defaultValue , flags , help , group) \
     WX_SETTER( name , class_t , type , setter ) \
@@ -1192,6 +1195,9 @@ struct wxConstructorBridge_8 : public wxConstructorBridge
 typedef wxObject *(*wxObjectConstructorFn)(void);
 typedef wxObject* (*wxVariantToObjectConverter)( wxxVariant &data ) ;
 typedef wxxVariant (*wxObjectToVariantConverter)( wxObject* ) ;
+class wxWriter ;
+class wxPersister ;
+typedef bool (*wxObjectStreamingCallback) ( const wxObject *, wxWriter * , wxPersister * , wxxVariantArray & ) ;
 
 class WXDLLIMPEXP_BASE wxClassInfo
 {
@@ -1208,11 +1214,13 @@ public:
         const int _ConstructorPropertiesCount ,
         wxVariantToObjectConverter _PtrConverter1 ,
         wxVariantToObjectConverter _Converter2 ,
-        wxObjectToVariantConverter _Converter3
+        wxObjectToVariantConverter _Converter3 ,
+        wxObjectStreamingCallback _streamingCallback = NULL
         ) : m_parents(_Parents) , m_unitName(_UnitName) ,m_className(_ClassName),
         m_objectSize(size), m_objectConstructor(ctor) , m_firstProperty(_Props ) , m_firstHandler(_Handlers ) , m_constructor( _Constructor ) ,
         m_constructorProperties(_ConstructorProperties) , m_constructorPropertiesCount(_ConstructorPropertiesCount),
-        m_variantOfPtrToObjectConverter( _PtrConverter1 ) , m_variantToObjectConverter( _Converter2 ) , m_objectToVariantConverter( _Converter3 ) , m_next(sm_first)
+        m_variantOfPtrToObjectConverter( _PtrConverter1 ) , m_variantToObjectConverter( _Converter2 ) , m_objectToVariantConverter( _Converter3 ) , 
+        m_next(sm_first) , m_streamingCallback( _streamingCallback ) 
     {
         sm_first = this;
         Register() ;
@@ -1221,7 +1229,8 @@ public:
     wxClassInfo(const wxChar *_UnitName, const wxChar *_ClassName, const wxClassInfo **_Parents) : m_parents(_Parents) , m_unitName(_UnitName) ,m_className(_ClassName),
         m_objectSize(0), m_objectConstructor(NULL) , m_firstProperty(NULL ) , m_firstHandler(NULL ) , m_constructor( NULL ) ,
         m_constructorProperties(NULL) , m_constructorPropertiesCount(NULL),
-        m_variantOfPtrToObjectConverter( NULL ) , m_variantToObjectConverter( NULL ) , m_objectToVariantConverter( NULL ) , m_next(sm_first)
+        m_variantOfPtrToObjectConverter( NULL ) , m_variantToObjectConverter( NULL ) , m_objectToVariantConverter( NULL ) , m_next(sm_first) ,
+        m_streamingCallback( NULL )
     {
         sm_first = this;
         Register() ;
@@ -1237,6 +1246,7 @@ public:
     wxObject *CreateObject() const { return AllocateObject() ; }
 
     const wxChar       *GetClassName() const { return m_className; }
+    const wxChar       *GetIncludeName() const { return m_unitName ; }
     const wxClassInfo **GetParents() const { return m_parents; }
     int                 GetSize() const { return m_objectSize; }
 
@@ -1264,6 +1274,15 @@ public:
         return false ;
     }
 
+    // if there is a callback registered with that class it will be called before this
+    // object will be written to disk, it can veto streaming out this object by returning
+    // false, if this class has not registered a callback, the search will go up the inheritance tree
+    // if no callback has been registered true will be returned by default
+    bool BeforeWriteObject( const wxObject *obj, wxWriter *streamer , wxPersister *persister , wxxVariantArray &metadata) const  ;
+
+    // gets the streaming callback from this class or any superclass
+    wxObjectStreamingCallback GetStreamingCallback() const ;
+
 #ifdef WXWIN_COMPATIBILITY_2_4
     // Initializes parent pointers and hash table for fast searching.
     wxDEPRECATED( static void     InitializeClasses() );
@@ -1353,7 +1372,7 @@ private:
     wxVariantToObjectConverter m_variantOfPtrToObjectConverter ;
     wxVariantToObjectConverter m_variantToObjectConverter ;
     wxObjectToVariantConverter m_objectToVariantConverter ;
-
+    wxObjectStreamingCallback m_streamingCallback ;
     const wxPropertyAccessor *FindAccessor (const wxChar *propertyName) const ;
 
 
@@ -1441,7 +1460,7 @@ public :
 
 // Single inheritance with one base class
 
-#define _IMPLEMENT_DYNAMIC_CLASS(name, basename, unit)                 \
+#define _IMPLEMENT_DYNAMIC_CLASS(name, basename, unit , callback)                 \
     wxObject* wxConstructorFor##name()                             \
 { return new name; }                                          \
     const wxClassInfo* name::sm_classParents##name[] = { &basename::sm_class##basename ,NULL } ; \
@@ -1451,7 +1470,7 @@ public :
     (int) sizeof(name),                              \
     (wxObjectConstructorFn) wxConstructorFor##name   ,   \
     name::GetPropertiesStatic(),name::GetHandlersStatic(),name::sm_constructor##name , name::sm_constructorProperties##name ,     \
-    name::sm_constructorPropertiesCount##name , wxVariantOfPtrToObjectConverter##name , NULL , wxObjectToVariantConverter##name);    \
+    name::sm_constructorPropertiesCount##name , wxVariantOfPtrToObjectConverter##name , NULL , wxObjectToVariantConverter##name , callback);    \
     template<> void wxStringReadValue(const wxString & , name & ){wxASSERT_MSG( 0 , wxT("Illegal Spezialication Called") ) ;}\
     template<> void wxStringWriteValue(wxString & , name const & ){wxASSERT_MSG( 0 , wxT("Illegal Spezialication Called") );}\
     template<> void wxStringReadValue(const wxString & , name * & ){wxASSERT_MSG( 0 , wxT("Illegal Spezialication Called") ) ;}\
@@ -1462,7 +1481,7 @@ public :
     template<> const wxTypeInfo* wxGetTypeInfo( name * ){ static wxClassTypeInfo s_typeInfo(wxT_OBJECT , &name::sm_class##name) ; return &s_typeInfo ; } \
     template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(wxT_OBJECT_PTR , &name::sm_class##name) ; return &s_typeInfo ; }
 
-#define _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY(name, basename, unit)                 \
+#define _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY(name, basename, unit, callback )                 \
     wxObject* wxConstructorFor##name()                             \
 { return new name; }                                          \
     const wxClassInfo* name::sm_classParents##name[] = { &basename::sm_class##basename ,NULL } ; \
@@ -1473,7 +1492,7 @@ public :
     (int) sizeof(name),                              \
     (wxObjectConstructorFn) wxConstructorFor##name   ,   \
     name::GetPropertiesStatic(),name::GetHandlersStatic(),name::sm_constructor##name , name::sm_constructorProperties##name ,     \
-    name::sm_constructorPropertiesCount##name , wxVariantOfPtrToObjectConverter##name , wxVariantToObjectConverter##name , wxObjectToVariantConverter##name);    \
+    name::sm_constructorPropertiesCount##name , wxVariantOfPtrToObjectConverter##name , wxVariantToObjectConverter##name , wxObjectToVariantConverter##name, callback);    \
     template<> void wxStringReadValue(const wxString & , name & ){wxASSERT_MSG( 0 , wxT("Illegal Spezialication Called") ) ;}\
     template<> void wxStringWriteValue(wxString & , name const & ){wxASSERT_MSG( 0 , wxT("Illegal Spezialication Called") );}\
     template<> void wxStringReadValue(const wxString & , name * & ){wxASSERT_MSG( 0 , wxT("Illegal Spezialication Called") ) ;}\
@@ -1485,22 +1504,25 @@ public :
     template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(wxT_OBJECT_PTR , &name::sm_class##name) ; return &s_typeInfo ; }
 
 #define IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name , basename ) \
-    _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name , basename , "" ) \
+    _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name , basename , "" , NULL ) \
     const wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL ; } \
     const wxHandlerInfo *name::GetHandlersStatic() { return (wxHandlerInfo*) NULL ; } \
     WX_CONSTRUCTOR_DUMMY( name )
 
 #define IMPLEMENT_DYNAMIC_CLASS( name , basename ) \
-    _IMPLEMENT_DYNAMIC_CLASS( name , basename , "" ) \
+    _IMPLEMENT_DYNAMIC_CLASS( name , basename , "" , NULL ) \
     wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL ; } \
     wxHandlerInfo *name::GetHandlersStatic() { return (wxHandlerInfo*) NULL ; } \
     WX_CONSTRUCTOR_DUMMY( name )
 
 #define IMPLEMENT_DYNAMIC_CLASS_XTI( name , basename , unit ) \
-    _IMPLEMENT_DYNAMIC_CLASS( name , basename , unit )
+    _IMPLEMENT_DYNAMIC_CLASS( name , basename , unit , NULL )
+
+#define IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK( name , basename , unit , callback ) \
+    _IMPLEMENT_DYNAMIC_CLASS( name , basename , unit , &callback )
 
 #define IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI( name , basename , unit ) \
-    _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name , basename , unit )
+    _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name , basename , unit , NULL  )
 
 // this is for classes that do not derive from wxobject, there are no creators for these
 
index b2dd547658e6e6510614558a898982ba33e951e8..876f6ab0c4c384f5212ca980471d686f79e25c51 100644 (file)
@@ -144,64 +144,9 @@ private :
     void WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data ) ;
     void WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *data ) ;
     void WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , bool isEmbedded, wxxVariantArray &metadata ) ;
-    void FindConnectEntry(const wxWindow * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler) ;
+    void FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler) ;
 } ;
 
-class wxXmlWriter : public wxWriter
-{
-public :
-
-    wxXmlWriter( wxXmlNode * parent ) ;
-    ~wxXmlWriter() ;
-
-    //
-    // streaming callbacks
-    //
-    // these callbacks really write out the values in the stream format
-    //
-
-    //
-    // streaming callbacks
-    //
-    // these callbacks really write out the values in the stream format
-
-    // begins writing out a new toplevel entry which has the indicated unique name
-    virtual void DoBeginWriteTopLevelEntry( const wxString &name )  ;
-
-    // ends writing out a new toplevel entry which has the indicated unique name
-    virtual void DoEndWriteTopLevelEntry( const wxString &name )  ;
-
-    // start of writing an object having the passed in ID
-    virtual void DoBeginWriteObject(const wxObject *object, const wxClassInfo *classInfo, int objectID , wxxVariantArray &metadata ) ;
-
-    // end of writing an toplevel object name param is used for unique identification within the container
-    virtual void DoEndWriteObject(const wxObject *object, const wxClassInfo *classInfo, int objectID ) ;
-
-    // writes a simple property in the stream format
-    virtual void DoWriteSimpleType( wxxVariant &value )  ;
-
-    // start of writing a complex property into the stream (
-    virtual void DoBeginWriteProperty( const wxPropertyInfo *propInfo )  ;
-
-    // end of writing a complex property into the stream
-    virtual void DoEndWriteProperty( const wxPropertyInfo *propInfo ) ;
-
-    virtual void DoBeginWriteElement() ;
-    virtual void DoEndWriteElement() ;
-
-    // insert an object reference to an already written object 
-    virtual void DoWriteRepeatedObject( int objectID )  ;
-
-    // insert a null reference
-    virtual void DoWriteNullObject()  ;
-
-    // writes a delegate in the stream format
-    virtual void DoWriteDelegate( const wxObject *object,  const wxClassInfo* classInfo , const wxPropertyInfo *propInfo , 
-        const wxObject *eventSink , int sinkObjectID , const wxClassInfo* eventSinkClassInfo , const wxHandlerInfo* handlerIndo ) ;
-private :
-    struct wxXmlWriterInternal ;
-    wxXmlWriterInternal* m_data ;
-} ;
 
 /*
 Streaming callbacks for depersisting XML to code, or running objects
@@ -235,31 +180,6 @@ private :
     wxReaderInternal *m_data;
 } ;
 
-/*
-wxXmlReader handles streaming in a class from XML
-*/
-
-class wxXmlReader : public wxReader
-{
-public:
-    wxXmlReader(wxXmlNode *parent) { m_parent = parent ; }
-    ~wxXmlReader() {}
-
-    // Reads a component from XML.  The return value is the root object ID, which can
-    // then be used to ask the depersister about that object
-
-    virtual int ReadObject( const wxString &name , wxDepersister *depersist ) ;
-
-private :
-    int ReadComponent(wxXmlNode *parent, wxDepersister *callbacks);
-
-    // read the content of this node (simple type) and return the corresponding value
-    wxxVariant ReadValue(wxXmlNode *Node,
-        const wxTypeInfo *type );
-
-    wxXmlNode * m_parent ;
-};
-
 // This abstract class matches the allocate-init/create model of creation of objects.
 // At runtime, these will create actual instances, and manipulate them.
 // When generating code, these will just create statements of C++
diff --git a/include/wx/xtixml.h b/include/wx/xtixml.h
new file mode 100644 (file)
index 0000000..a61129d
--- /dev/null
@@ -0,0 +1,110 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/xtixml.h
+// Purpose:     xml streaming runtime metadata information (extended class info)
+// Author:      Stefan Csomor
+// Modified by: 
+// Created:     27/07/03
+// RCS-ID:      $Id$
+// Copyright:   (c) 2003 Stefan Csomor
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_XTIXMLH__
+#define _WX_XTIXMLH__
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma interface "xtixml.h"
+#endif
+
+#include "wx/wx.h"
+
+#if wxUSE_EXTENDED_RTTI
+
+#include "wx/xtistrm.h"
+
+class wxXmlNode ;
+
+class wxXmlWriter : public wxWriter
+{
+public :
+
+    wxXmlWriter( wxXmlNode * parent ) ;
+    ~wxXmlWriter() ;
+
+    //
+    // streaming callbacks
+    //
+    // these callbacks really write out the values in the stream format
+    //
+
+    //
+    // streaming callbacks
+    //
+    // these callbacks really write out the values in the stream format
+
+    // begins writing out a new toplevel entry which has the indicated unique name
+    virtual void DoBeginWriteTopLevelEntry( const wxString &name )  ;
+
+    // ends writing out a new toplevel entry which has the indicated unique name
+    virtual void DoEndWriteTopLevelEntry( const wxString &name )  ;
+
+    // start of writing an object having the passed in ID
+    virtual void DoBeginWriteObject(const wxObject *object, const wxClassInfo *classInfo, int objectID , wxxVariantArray &metadata ) ;
+
+    // end of writing an toplevel object name param is used for unique identification within the container
+    virtual void DoEndWriteObject(const wxObject *object, const wxClassInfo *classInfo, int objectID ) ;
+
+    // writes a simple property in the stream format
+    virtual void DoWriteSimpleType( wxxVariant &value )  ;
+
+    // start of writing a complex property into the stream (
+    virtual void DoBeginWriteProperty( const wxPropertyInfo *propInfo )  ;
+
+    // end of writing a complex property into the stream
+    virtual void DoEndWriteProperty( const wxPropertyInfo *propInfo ) ;
+
+    virtual void DoBeginWriteElement() ;
+    virtual void DoEndWriteElement() ;
+
+    // insert an object reference to an already written object 
+    virtual void DoWriteRepeatedObject( int objectID )  ;
+
+    // insert a null reference
+    virtual void DoWriteNullObject()  ;
+
+    // writes a delegate in the stream format
+    virtual void DoWriteDelegate( const wxObject *object,  const wxClassInfo* classInfo , const wxPropertyInfo *propInfo , 
+        const wxObject *eventSink , int sinkObjectID , const wxClassInfo* eventSinkClassInfo , const wxHandlerInfo* handlerIndo ) ;
+private :
+    struct wxXmlWriterInternal ;
+    wxXmlWriterInternal* m_data ;
+} ;
+
+/*
+wxXmlReader handles streaming in a class from XML
+*/
+
+class wxXmlReader : public wxReader
+{
+public:
+    wxXmlReader(wxXmlNode *parent) { m_parent = parent ; }
+    ~wxXmlReader() {}
+
+    // Reads a component from XML.  The return value is the root object ID, which can
+    // then be used to ask the depersister about that object
+
+    virtual int ReadObject( const wxString &name , wxDepersister *depersist ) ;
+
+private :
+    int ReadComponent(wxXmlNode *parent, wxDepersister *callbacks);
+
+    // read the content of this node (simple type) and return the corresponding value
+    wxxVariant ReadValue(wxXmlNode *Node,
+        const wxTypeInfo *type );
+
+    wxXmlNode * m_parent ;
+};
+
+#endif // wxUSE_EXTENDED_RTTI
+
+#endif
index 0b188a042e227e9cb14e274a495fb289fc74fb18..aacc0dbb35f94321b7751e98f4b5d585543f12db 100644 (file)
@@ -316,10 +316,6 @@ WX_ILLEGAL_TYPE_SPECIALIZATION( bool * )
 WX_ILLEGAL_TYPE_SPECIALIZATION( long * )
 WX_ILLEGAL_TYPE_SPECIALIZATION( wxString * )
 
-//
-
-// make wxWindowList known
-
 WX_COLLECTION_TYPE_INFO( wxString , wxArrayString ) ;
 
 template<> void wxCollectionToVariantArray( wxArrayString const &theArray, wxxVariantArray &value)
@@ -445,6 +441,28 @@ const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const char *PropertyName) con
     return 0;
 }
 
+wxObjectStreamingCallback wxClassInfo::GetStreamingCallback() const
+{
+    if ( m_streamingCallback )
+        return m_streamingCallback ;
+
+    wxObjectStreamingCallback retval = NULL ;
+       const wxClassInfo** parents = GetParents() ;
+    for ( int i = 0 ; parents[i] && retval == NULL ; ++ i )
+       {
+        retval = parents[i]->GetStreamingCallback() ;
+       }
+    return retval ;
+}
+
+bool wxClassInfo::BeforeWriteObject( const wxObject *obj, wxWriter *streamer , wxPersister *persister , wxxVariantArray &metadata) const  
+{
+    wxObjectStreamingCallback sb = GetStreamingCallback() ;
+    if ( sb )
+        return (*sb)(obj , streamer , persister , metadata ) ;
+
+    return true ;
+}
 
 void wxClassInfo::SetProperty(wxObject *object, const char *propertyName, const wxxVariant &value) const
 {
index 372602c3760db7218b9bcbd24ee719bebf550ec1..bdd76724bd2831109fcd199dc7b97404a11b404e 100644 (file)
 #include "wx/object.h"
 #endif
 
-#include "wx/xml/xml.h"
 #include "wx/tokenzr.h"
 #include "wx/xtistrm.h"
 #include "wx/txtstrm.h"
+#include "wx/event.h"
 
 #if wxUSE_EXTENDED_RTTI
 
@@ -78,11 +78,7 @@ void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo
 
 void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , bool isEmbedded, wxxVariantArray &metadata )
 {
-    // hack to avoid writing out embedded windows, these are windows that are constructed as part of other windows, they would
-    // doubly constructed afterwards
-
-    const wxWindow * win = dynamic_cast<const wxWindow*>(object) ;
-    if ( win && win->GetId() < 0 )
+    if ( !classInfo->BeforeWriteObject( object , this , persister , metadata) )
         return ;
 
     if ( persister->BeforeWriteObject( this , object , classInfo , metadata) )
@@ -112,7 +108,7 @@ void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo
     }
 }
 
-void wxWriter::FindConnectEntry(const wxWindow * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler)
+void wxWriter::FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler)
 {
     wxList *dynamicEvents = evSource->GetDynamicEventTable() ;
 
@@ -124,13 +120,10 @@ void wxWriter::FindConnectEntry(const wxWindow * evSource,const wxDelegateTypeIn
             wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
 
             // find the match
-            if ( entry->m_fn && (dti->GetEventType() == entry->m_eventType) &&
-                (entry->m_id == -1 ||
-                (entry->m_lastId == -1 && evSource->GetId() == entry->m_id) ||
-                (entry->m_lastId != -1 &&
-                (evSource->GetId()  >= entry->m_id && evSource->GetId() <= entry->m_lastId) ) ) &&
-                entry->m_eventSink
-                )
+            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() ;
@@ -182,8 +175,11 @@ void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci
     }
 }
 
-void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *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) )
@@ -225,8 +221,8 @@ void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , c
             const wxObject* sink = NULL ;
             const wxHandlerInfo *handler = NULL ;
 
-            const wxWindow * evSource = dynamic_cast<const wxWindow *>(obj) ;
-            wxASSERT_MSG( evSource , wxT("Illegal Object Class (Non-Window) as Event Source") ) ;
+            const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ;
+            wxASSERT_MSG( evSource , wxT("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ;
 
             FindConnectEntry( evSource , dti , sink , handler ) ;
             if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
@@ -281,152 +277,6 @@ bool wxWriter::IsObjectKnown( const wxObject *obj )
     return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ;
 }
 
-//
-// XML Streaming
-// 
-
-// convenience functions
-
-void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
-{
-    node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
-}
-
-wxString wxXmlGetContentFromNode( wxXmlNode *node )
-{
-    if ( node->GetChildren() )
-        return node->GetChildren()->GetContent() ;
-    else
-        return wxEmptyString ;
-}
-
-struct wxXmlWriter::wxXmlWriterInternal
-{
-    wxXmlNode *m_root ;
-    wxXmlNode *m_current ;
-    vector< wxXmlNode * > m_objectStack ;
-
-    void Push( wxXmlNode *newCurrent )
-    {
-        m_objectStack.push_back( m_current ) ;
-        m_current = newCurrent ;
-    }
-
-    void Pop()
-    {
-        m_current = m_objectStack.back() ;
-        m_objectStack.pop_back() ;
-    }
-} ;
-
-wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode ) 
-{
-    m_data = new wxXmlWriterInternal() ;
-    m_data->m_root = rootnode ;
-    m_data->m_current = rootnode ;
-}
-
-wxXmlWriter::~wxXmlWriter() 
-{
-    delete m_data ;
-}
-
-void wxXmlWriter::DoBeginWriteTopLevelEntry( const wxString &name ) 
-{
-    wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("entry"));
-    pnode->AddProperty(wxString("name"), name);
-    m_data->m_current->AddChild(pnode) ;
-    m_data->Push( pnode ) ;
-}
-
-void wxXmlWriter::DoEndWriteTopLevelEntry( const wxString &WXUNUSED(name) )
-{
-    m_data->Pop() ;
-}
-
-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()));
-    pnode->AddProperty(wxT("id"), wxString::Format( "%d" , objectID ) );
-
-    for ( size_t i = 0 ; i < metadata.GetCount() ; ++i )
-    {
-        pnode->AddProperty( metadata[i].GetName() , metadata[i].GetAsString() ) ;
-    }
-    m_data->m_current->AddChild(pnode) ;
-    m_data->Push( pnode ) ;
-}
-
-// end of writing the root object
-void wxXmlWriter::DoEndWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *WXUNUSED(classInfo), int WXUNUSED(objectID) ) 
-{
-    m_data->Pop() ;
-}
-
-// writes a property in the stream format
-void wxXmlWriter::DoWriteSimpleType( wxxVariant &value ) 
-{
-    wxXmlAddContentToNode( m_data->m_current ,value.GetAsString() ) ;
-}
-
-void wxXmlWriter::DoBeginWriteElement() 
-{
-    wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, "element" );
-    m_data->m_current->AddChild(pnode) ;
-    m_data->Push( pnode ) ;
-}
-
-void wxXmlWriter::DoEndWriteElement() 
-{
-    m_data->Pop() ;
-}
-
-void wxXmlWriter::DoBeginWriteProperty(const wxPropertyInfo *pi )
-{
-    wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, "prop" );
-    pnode->AddProperty(wxT("name"), pi->GetName() );
-    m_data->m_current->AddChild(pnode) ;
-    m_data->Push( pnode ) ;
-}
-
-void wxXmlWriter::DoEndWriteProperty(const wxPropertyInfo *WXUNUSED(propInfo) )
-{
-    m_data->Pop() ;
-}
-
-
-
-// insert an object reference to an already written object
-void wxXmlWriter::DoWriteRepeatedObject( int objectID ) 
-{
-    wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
-    pnode->AddProperty(wxString("href"), wxString::Format( "%d" , objectID ) );
-    m_data->m_current->AddChild(pnode) ;
-}
-
-// insert a null reference
-void wxXmlWriter::DoWriteNullObject() 
-{
-    wxXmlNode *pnode;
-    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
-    m_data->m_current->AddChild(pnode) ;
-}
-
-// 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 ) 
-{
-    if ( eventSink != NULL && handlerInfo != NULL )
-    {
-        wxXmlAddContentToNode( m_data->m_current ,wxString::Format(wxT("%d.%s"), sinkObjectID , handlerInfo->GetName()) ) ;
-    }
-}
 
 // ----------------------------------------------------------------------------
 // reading objects in 
@@ -475,252 +325,6 @@ as properties are always sought by typeinfo over all levels
 and create params are always toplevel class only
 */
 
-int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
-{
-    wxASSERT_MSG( callbacks , wxT("Does not support reading without a Depersistor") ) ;
-    wxString className;
-    wxClassInfo *classInfo;
-
-    wxxVariant *createParams ;
-    int *createParamOids ;
-    const wxClassInfo** createClassInfos ;
-    wxXmlNode *children;
-    int objectID;
-    wxString ObjectIdString ;
-
-    children = node->GetChildren();
-    if (!children)
-    {
-        // check for a null object or href
-        if (node->GetPropVal("href" , &ObjectIdString ) )
-        {
-            objectID = atoi( ObjectIdString.c_str() ) ;
-            wxASSERT_MSG( HasObjectClassInfo( objectID ) , wxT("Forward hrefs are not supported") ) ;
-            return objectID ;
-        }
-        if ( !node->GetPropVal("id" , &ObjectIdString ) )
-        {
-            return wxNullObjectID;
-        }
-    }
-    if (!node->GetPropVal("class", &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))
-    {
-        wxASSERT_MSG(0,wxT("Objects must have an id attribute") ) ;
-        // No object id.  Eek. FIXME: error handling
-        return wxInvalidObjectID;
-    }
-    objectID = atoi( ObjectIdString.c_str() ) ;
-    // is this object already has been streamed in, return it here
-    wxASSERT_MSG( !HasObjectClassInfo( objectID ) , wxString::Format(wxT("Doubly used id : %d"), objectID ) ) ;
-
-    // new object, start with allocation
-    // first make the object know to our internal registry
-    SetObjectClassInfo( objectID , classInfo ) ;
-
-    wxxVariantArray metadata ;
-    wxXmlProperty *xp = node->GetProperties() ;
-    while ( xp )
-    {
-        if ( xp->GetName() != wxString("class") && xp->GetName() != wxString("id") )
-        {
-            metadata.Add( new wxxVariant( xp->GetValue() , xp->GetName() ) ) ;
-        }
-        xp = xp->GetNext() ;
-    }
-    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() ] ;
-
-    typedef map<string, wxXmlNode *> PropertyNodes ;
-    typedef vector<string> PropertyNames ;
-
-    PropertyNodes propertyNodes ;
-    PropertyNames propertyNames ;
-
-    while( children )
-    {
-        wxString name ;
-        children->GetPropVal( wxT("name") , &name ) ;
-        propertyNames.push_back( name.c_str() ) ;
-        propertyNodes[name.c_str()] = children->GetChildren() ;
-        children = children->GetNext() ;
-    }
-
-    for ( int i = 0 ; i <classInfo->GetCreateParamCount() ; ++i )
-    {
-        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 we don't have the value of a create param set in the xml
-        // we use the default value
-        if ( propiter != propertyNodes.end() )
-        {
-            wxXmlNode* prop = propiter->second ;
-            if ( pi->GetTypeInfo()->IsObjectType() )
-            {
-                createParamOids[i] = ReadComponent( prop , callbacks ) ;
-                createClassInfos[i] = dynamic_cast<const wxClassTypeInfo*>(pi->GetTypeInfo())->GetClassInfo() ;
-            }
-            else
-            {
-                createParamOids[i] = wxInvalidObjectID ;
-                createParams[i] = ReadValue( prop , 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 ) ;
-                }
-                createClassInfos[i] = NULL ;
-            }
-
-            for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
-            {
-                if ( propertyNames[j] == paramName )
-                {
-                    propertyNames[j] = "" ;
-                    break ;
-                }
-            }
-        }
-        else
-        {
-            createParams[i] = pi->GetDefaultValue() ;
-        }
-    }
-
-    // got the parameters.  Call the Create method
-    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 )
-    {
-        if ( propertyNames[j].length() )
-        {
-            PropertyNodes::iterator propiter = propertyNodes.find( propertyNames[j] ) ;
-            if ( propiter != propertyNodes.end() )
-            {
-                wxXmlNode* prop = propiter->second ;
-                const wxPropertyInfo* pi = classInfo->FindPropertyInfo( propertyNames[j].c_str() ) ;
-                if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
-                {
-                    const wxCollectionTypeInfo* collType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() ) ;
-                    const wxTypeInfo * elementType = collType->GetElementType() ;
-                    while( prop )
-                    {
-                        wxASSERT_MSG(prop->GetName() == wxT("element") , wxT("A non empty collection must consist of 'element' nodes")) ;
-                        wxXmlNode* elementContent = prop->GetChildren() ;
-                        if ( elementContent )
-                        {
-                            // we skip empty elements
-                            if ( elementType->IsObjectType() )
-                            {
-                                int valueId = ReadComponent( elementContent , callbacks ) ;
-                                if ( valueId != wxInvalidObjectID )
-                                {
-                                    if ( pi->GetAccessor()->HasAdder() )
-                                        callbacks->AddToPropertyCollectionAsObject( objectID , classInfo , pi , valueId ) ;
-                                    // 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 ) ) ;
-                                }
-                            }
-                            else
-                            {
-                                wxxVariant elementValue = ReadValue( elementContent , elementType ) ;
-                                if ( pi->GetAccessor()->HasAdder() )
-                                    callbacks->AddToPropertyCollection( objectID , classInfo ,pi , elementValue ) ;
-                            }
-                        }
-                        prop = prop->GetNext() ;
-                    }
-                }
-                else if ( pi->GetTypeInfo()->IsObjectType() )
-                {
-                    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 if ( pi->GetTypeInfo()->IsDelegateType() )
-                {
-                    if ( prop )
-                    {
-                        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 ) ;
-
-                        callbacks->SetConnect( objectID , classInfo , dynamic_cast<const wxDelegateTypeInfo*>(pi->GetTypeInfo()) , sinkClassInfo ,
-                            sinkClassInfo->FindHandlerInfo(handlerName) ,  sinkOid ) ;
-                    }
-
-                }
-                else
-                {
-                    wxxVariant nodeval ;
-                    callbacks->SetProperty( objectID, classInfo ,pi , ReadValue( prop , pi->GetTypeInfo() ) ) ;
-                }
-            }
-        }
-    }
-
-    delete[] createParams ;
-    delete[] createParamOids ;
-    delete[] createClassInfos ;
-
-    return objectID;
-}
-
-wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
-                                  const wxTypeInfo *type )
-{
-    wxString content ;
-    if ( node )
-        content = node->GetContent() ;
-    wxxVariant result ;
-    type->ConvertFromString( content , result ) ;
-    return result ;
-}
-
-int wxXmlReader::ReadObject( const wxString &name , wxDepersister *callbacks)
-{
-    wxXmlNode *iter = m_parent->GetChildren() ;
-    while ( iter )
-    {
-        wxString entryName ;
-        if ( iter->GetPropVal("name", &entryName) )
-        {
-            if ( entryName == name )
-                return ReadComponent( iter->GetChildren() , callbacks ) ;
-        }
-        iter = iter->GetNext() ;
-    }
-    return wxInvalidObjectID ;
-}
 
 // ----------------------------------------------------------------------------
 // depersisting to memory 
@@ -756,7 +360,7 @@ wxRuntimeDepersister::~wxRuntimeDepersister()
 }
 
 void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
-                                          wxxVariantArray &metadata)
+                                          wxxVariantArray &WXUNUSED(metadata))
 {
     wxObject *O;
     O = classInfo->CreateObject();
@@ -769,7 +373,7 @@ void wxRuntimeDepersister::CreateObject(int objectID,
                                         wxxVariant *params,
                                         int *objectIdValues,
                                         const wxClassInfo **objectClassInfos ,
-                                        wxxVariantArray &metadata)
+                                        wxxVariantArray &WXUNUSED(metadata))
 {
     wxObject *o;
     o = m_data->GetObject(objectID);
@@ -836,12 +440,12 @@ void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
                                       const wxHandlerInfo* handlerInfo ,
                                       int eventSinkObjectID )
 {
-    wxWindow *ehsource = dynamic_cast< wxWindow* >( m_data->GetObject( eventSourceObjectID ) ) ;
+    wxEvtHandler *ehsource = dynamic_cast< wxEvtHandler* >( m_data->GetObject( eventSourceObjectID ) ) ;
     wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ;
 
     if ( ehsource && ehsink )
     {
-        ehsource->Connect( ehsource->GetId() , delegateInfo->GetEventType() , 
+        ehsource->Connect( -1 , delegateInfo->GetEventType() , 
             handlerInfo->GetEventFunction() , NULL /*user data*/ , 
             ehsink ) ;
     }
@@ -920,7 +524,7 @@ wxCodeDepersister::~wxCodeDepersister()
 }
 
 void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
-                                       wxxVariantArray &metadata)
+                                       wxxVariantArray &WXUNUSED(metadata))
 {
     wxString objectName = wxString::Format( "LocalObject_%d" , objectID ) ;
     m_fp->WriteString( wxString::Format( "\t%s *%s = new %s;\n",
@@ -963,7 +567,7 @@ void wxCodeDepersister::CreateObject(int objectID,
                                      wxxVariant *params,
                                      int *objectIDValues,
                                      const wxClassInfo **WXUNUSED(objectClassInfos) ,
-                                     wxxVariantArray &metadata
+                                     wxxVariantArray &WXUNUSED(metadata)
                                      )
 {
     int i;
@@ -1011,7 +615,7 @@ void wxCodeDepersister::SetPropertyAsObject(int objectID,
 }
 
 void wxCodeDepersister::AddToPropertyCollection( int objectID ,
-                                                const wxClassInfo *classInfo,
+                                                const wxClassInfo *WXUNUSED(classInfo),
                                                 const wxPropertyInfo* propertyInfo ,
                                                 const wxxVariant &value) 
 {
@@ -1022,10 +626,10 @@ void wxCodeDepersister::AddToPropertyCollection( int objectID ,
 }
 
 // sets the corresponding property (value is an object)
-void wxCodeDepersister::AddToPropertyCollectionAsObject(int objectID,
-                                                        const wxClassInfo *classInfo,
-                                                        const wxPropertyInfo* propertyInfo ,
-                                                        int valueObjectId
+void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID),
+                                                        const wxClassInfo *WXUNUSED(classInfo),
+                                                        const wxPropertyInfo* WXUNUSED(propertyInfo) ,
+                                                        int WXUNUSED(valueObjectId)
 {
     // TODO
 }
diff --git a/src/common/xtixml.cpp b/src/common/xtixml.cpp
new file mode 100644 (file)
index 0000000..94dcc08
--- /dev/null
@@ -0,0 +1,455 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        src/common/xtistrm.cpp
+// Purpose:     streaming runtime metadata information 
+// Author:      Stefan Csomor
+// Modified by: 
+// Created:     27/07/03
+// RCS-ID:      $Id$
+// Copyright:   (c) 2003 Stefan Csomor
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma implementation "xtistrm.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/hash.h"
+#include "wx/object.h"
+#endif
+
+#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/beforestd.h"
+#include <map>
+#include <vector>
+#include <string>
+#include "wx/afterstd.h"
+
+using namespace std ;
+
+//
+// XML Streaming
+// 
+
+// convenience functions
+
+void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
+{
+    node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
+}
+
+wxString wxXmlGetContentFromNode( wxXmlNode *node )
+{
+    if ( node->GetChildren() )
+        return node->GetChildren()->GetContent() ;
+    else
+        return wxEmptyString ;
+}
+
+struct wxXmlWriter::wxXmlWriterInternal
+{
+    wxXmlNode *m_root ;
+    wxXmlNode *m_current ;
+    vector< wxXmlNode * > m_objectStack ;
+
+    void Push( wxXmlNode *newCurrent )
+    {
+        m_objectStack.push_back( m_current ) ;
+        m_current = newCurrent ;
+    }
+
+    void Pop()
+    {
+        m_current = m_objectStack.back() ;
+        m_objectStack.pop_back() ;
+    }
+} ;
+
+wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode ) 
+{
+    m_data = new wxXmlWriterInternal() ;
+    m_data->m_root = rootnode ;
+    m_data->m_current = rootnode ;
+}
+
+wxXmlWriter::~wxXmlWriter() 
+{
+    delete m_data ;
+}
+
+void wxXmlWriter::DoBeginWriteTopLevelEntry( const wxString &name ) 
+{
+    wxXmlNode *pnode;
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("entry"));
+    pnode->AddProperty(wxString("name"), name);
+    m_data->m_current->AddChild(pnode) ;
+    m_data->Push( pnode ) ;
+}
+
+void wxXmlWriter::DoEndWriteTopLevelEntry( const wxString &WXUNUSED(name) )
+{
+    m_data->Pop() ;
+}
+
+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()));
+    pnode->AddProperty(wxT("id"), wxString::Format( "%d" , objectID ) );
+
+    for ( size_t i = 0 ; i < metadata.GetCount() ; ++i )
+    {
+        pnode->AddProperty( metadata[i].GetName() , metadata[i].GetAsString() ) ;
+    }
+    m_data->m_current->AddChild(pnode) ;
+    m_data->Push( pnode ) ;
+}
+
+// end of writing the root object
+void wxXmlWriter::DoEndWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *WXUNUSED(classInfo), int WXUNUSED(objectID) ) 
+{
+    m_data->Pop() ;
+}
+
+// writes a property in the stream format
+void wxXmlWriter::DoWriteSimpleType( wxxVariant &value ) 
+{
+    wxXmlAddContentToNode( m_data->m_current ,value.GetAsString() ) ;
+}
+
+void wxXmlWriter::DoBeginWriteElement() 
+{
+    wxXmlNode *pnode;
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, "element" );
+    m_data->m_current->AddChild(pnode) ;
+    m_data->Push( pnode ) ;
+}
+
+void wxXmlWriter::DoEndWriteElement() 
+{
+    m_data->Pop() ;
+}
+
+void wxXmlWriter::DoBeginWriteProperty(const wxPropertyInfo *pi )
+{
+    wxXmlNode *pnode;
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, "prop" );
+    pnode->AddProperty(wxT("name"), pi->GetName() );
+    m_data->m_current->AddChild(pnode) ;
+    m_data->Push( pnode ) ;
+}
+
+void wxXmlWriter::DoEndWriteProperty(const wxPropertyInfo *WXUNUSED(propInfo) )
+{
+    m_data->Pop() ;
+}
+
+
+
+// insert an object reference to an already written object
+void wxXmlWriter::DoWriteRepeatedObject( int objectID ) 
+{
+    wxXmlNode *pnode;
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
+    pnode->AddProperty(wxString("href"), wxString::Format( "%d" , objectID ) );
+    m_data->m_current->AddChild(pnode) ;
+}
+
+// insert a null reference
+void wxXmlWriter::DoWriteNullObject() 
+{
+    wxXmlNode *pnode;
+    pnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("object"));
+    m_data->m_current->AddChild(pnode) ;
+}
+
+// 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 ) 
+{
+    if ( eventSink != NULL && handlerInfo != NULL )
+    {
+        wxXmlAddContentToNode( m_data->m_current ,wxString::Format(wxT("%d.%s"), sinkObjectID , handlerInfo->GetName()) ) ;
+    }
+}
+
+// ----------------------------------------------------------------------------
+// reading objects 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
+*/
+
+int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
+{
+    wxASSERT_MSG( callbacks , wxT("Does not support reading without a Depersistor") ) ;
+    wxString className;
+    wxClassInfo *classInfo;
+
+    wxxVariant *createParams ;
+    int *createParamOids ;
+    const wxClassInfo** createClassInfos ;
+    wxXmlNode *children;
+    int objectID;
+    wxString ObjectIdString ;
+
+    children = node->GetChildren();
+    if (!children)
+    {
+        // check for a null object or href
+        if (node->GetPropVal("href" , &ObjectIdString ) )
+        {
+            objectID = atoi( ObjectIdString.c_str() ) ;
+            wxASSERT_MSG( HasObjectClassInfo( objectID ) , wxT("Forward hrefs are not supported") ) ;
+            return objectID ;
+        }
+        if ( !node->GetPropVal("id" , &ObjectIdString ) )
+        {
+            return wxNullObjectID;
+        }
+    }
+    if (!node->GetPropVal("class", &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))
+    {
+        wxASSERT_MSG(0,wxT("Objects must have an id attribute") ) ;
+        // No object id.  Eek. FIXME: error handling
+        return wxInvalidObjectID;
+    }
+    objectID = atoi( ObjectIdString.c_str() ) ;
+    // is this object already has been streamed in, return it here
+    wxASSERT_MSG( !HasObjectClassInfo( objectID ) , wxString::Format(wxT("Doubly used id : %d"), objectID ) ) ;
+
+    // new object, start with allocation
+    // first make the object know to our internal registry
+    SetObjectClassInfo( objectID , classInfo ) ;
+
+    wxxVariantArray metadata ;
+    wxXmlProperty *xp = node->GetProperties() ;
+    while ( xp )
+    {
+        if ( xp->GetName() != wxString("class") && xp->GetName() != wxString("id") )
+        {
+            metadata.Add( new wxxVariant( xp->GetValue() , xp->GetName() ) ) ;
+        }
+        xp = xp->GetNext() ;
+    }
+    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() ] ;
+
+    typedef map<string, wxXmlNode *> PropertyNodes ;
+    typedef vector<string> PropertyNames ;
+
+    PropertyNodes propertyNodes ;
+    PropertyNames propertyNames ;
+
+    while( children )
+    {
+        wxString name ;
+        children->GetPropVal( wxT("name") , &name ) ;
+        propertyNames.push_back( name.c_str() ) ;
+        propertyNodes[name.c_str()] = children->GetChildren() ;
+        children = children->GetNext() ;
+    }
+
+    for ( int i = 0 ; i <classInfo->GetCreateParamCount() ; ++i )
+    {
+        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 we don't have the value of a create param set in the xml
+        // we use the default value
+        if ( propiter != propertyNodes.end() )
+        {
+            wxXmlNode* prop = propiter->second ;
+            if ( pi->GetTypeInfo()->IsObjectType() )
+            {
+                createParamOids[i] = ReadComponent( prop , callbacks ) ;
+                createClassInfos[i] = dynamic_cast<const wxClassTypeInfo*>(pi->GetTypeInfo())->GetClassInfo() ;
+            }
+            else
+            {
+                createParamOids[i] = wxInvalidObjectID ;
+                createParams[i] = ReadValue( prop , 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 ) ;
+                }
+                createClassInfos[i] = NULL ;
+            }
+
+            for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
+            {
+                if ( propertyNames[j] == paramName )
+                {
+                    propertyNames[j] = "" ;
+                    break ;
+                }
+            }
+        }
+        else
+        {
+            createParams[i] = pi->GetDefaultValue() ;
+        }
+    }
+
+    // got the parameters.  Call the Create method
+    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 )
+    {
+        if ( propertyNames[j].length() )
+        {
+            PropertyNodes::iterator propiter = propertyNodes.find( propertyNames[j] ) ;
+            if ( propiter != propertyNodes.end() )
+            {
+                wxXmlNode* prop = propiter->second ;
+                const wxPropertyInfo* pi = classInfo->FindPropertyInfo( propertyNames[j].c_str() ) ;
+                if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
+                {
+                    const wxCollectionTypeInfo* collType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() ) ;
+                    const wxTypeInfo * elementType = collType->GetElementType() ;
+                    while( prop )
+                    {
+                        wxASSERT_MSG(prop->GetName() == wxT("element") , wxT("A non empty collection must consist of 'element' nodes")) ;
+                        wxXmlNode* elementContent = prop->GetChildren() ;
+                        if ( elementContent )
+                        {
+                            // we skip empty elements
+                            if ( elementType->IsObjectType() )
+                            {
+                                int valueId = ReadComponent( elementContent , callbacks ) ;
+                                if ( valueId != wxInvalidObjectID )
+                                {
+                                    if ( pi->GetAccessor()->HasAdder() )
+                                        callbacks->AddToPropertyCollectionAsObject( objectID , classInfo , pi , valueId ) ;
+                                    // 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 ) ) ;
+                                }
+                            }
+                            else
+                            {
+                                wxxVariant elementValue = ReadValue( elementContent , elementType ) ;
+                                if ( pi->GetAccessor()->HasAdder() )
+                                    callbacks->AddToPropertyCollection( objectID , classInfo ,pi , elementValue ) ;
+                            }
+                        }
+                        prop = prop->GetNext() ;
+                    }
+                }
+                else if ( pi->GetTypeInfo()->IsObjectType() )
+                {
+                    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 if ( pi->GetTypeInfo()->IsDelegateType() )
+                {
+                    if ( prop )
+                    {
+                        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 ) ;
+
+                        callbacks->SetConnect( objectID , classInfo , dynamic_cast<const wxDelegateTypeInfo*>(pi->GetTypeInfo()) , sinkClassInfo ,
+                            sinkClassInfo->FindHandlerInfo(handlerName) ,  sinkOid ) ;
+                    }
+
+                }
+                else
+                {
+                    wxxVariant nodeval ;
+                    callbacks->SetProperty( objectID, classInfo ,pi , ReadValue( prop , pi->GetTypeInfo() ) ) ;
+                }
+            }
+        }
+    }
+
+    delete[] createParams ;
+    delete[] createParamOids ;
+    delete[] createClassInfos ;
+
+    return objectID;
+}
+
+wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
+                                  const wxTypeInfo *type )
+{
+    wxString content ;
+    if ( node )
+        content = node->GetContent() ;
+    wxxVariant result ;
+    type->ConvertFromString( content , result ) ;
+    return result ;
+}
+
+int wxXmlReader::ReadObject( const wxString &name , wxDepersister *callbacks)
+{
+    wxXmlNode *iter = m_parent->GetChildren() ;
+    while ( iter )
+    {
+        wxString entryName ;
+        if ( iter->GetPropVal("name", &entryName) )
+        {
+            if ( entryName == name )
+                return ReadComponent( iter->GetChildren() , callbacks ) ;
+        }
+        iter = iter->GetNext() ;
+    }
+    return wxInvalidObjectID ;
+}
+
+#endif