#include "wx/xml/xml.h"
#include "wx/tokenzr.h"
#include "wx/list.h"
-#include "wx/datetime.h"
#include <string.h>
#if wxUSE_EXTENDED_RTTI
s = data ;
}
-/*
- Custom Data Streaming / Type Infos
- we will have to add this for all wx non object types, but it is also an example
- for custom data structures
-*/
-
-// wxPoint
-
-template<> void wxStringReadValue(const wxString &s , wxPoint &data )
-{
- wxSscanf(s, _T("%d,%d"), &data.x , &data.y ) ;
-}
-
-template<> void wxStringWriteValue(wxString &s , const wxPoint &data )
-{
- s = wxString::Format("%d,%d", data.x , data.y ) ;
-}
-
-template<> void wxStringReadValue(const wxString & , wxPoint* & )
-{
- assert(0) ;
-}
-
-template<> void wxStringWriteValue(wxString & , wxPoint* const & )
-{
- assert(0) ;
-}
-
-WX_CUSTOM_TYPE_INFO(wxPoint)
-
-template<> void wxStringReadValue(const wxString &s , wxSize &data )
-{
- wxSscanf(s, _T("%d,%d"), &data.x , &data.y ) ;
-}
-
-template<> void wxStringWriteValue(wxString &s , const wxSize &data )
-{
- s = wxString::Format("%d,%d", data.x , data.y ) ;
-}
-
-template<> void wxStringReadValue(const wxString & , wxSize* & )
-{
- assert(0) ;
-}
-
-template<> void wxStringWriteValue(wxString & , wxSize * const & )
-{
- assert(0) ;
-}
-
-WX_CUSTOM_TYPE_INFO(wxSize)
-
-template<> void wxStringReadValue(const wxString &s , wxDateTime &data )
-{
- data.ParseFormat(s,wxT("%Y-%m-%d %H:%M:%S")) ;
-}
-
-template<> void wxStringWriteValue(wxString &s , const wxDateTime &data )
-{
- s = data.Format(wxT("%Y-%m-%d %H:%M:%S")) ;
-}
-
-WX_CUSTOM_TYPE_INFO(wxDateTime)
-
-//
// built-ins
//
// make wxWindowList known
-template<> const wxTypeInfo* wxGetTypeInfo( wxArrayString * )
-{
- static wxCollectionTypeInfo s_typeInfo( (wxTypeInfo*) wxGetTypeInfo( (wxString *) NULL) ) ;
- return &s_typeInfo ;
-}
+WX_COLLECTION_TYPE_INFO( wxString , wxArrayString ) ;
template<> void wxCollectionToVariantArray( wxArrayString const &theArray, wxxVariantArray &value)
{
wxArrayCollectionToVariantArray( theArray , value ) ;
}
+wxTypeInfoMap *wxTypeInfo::sm_typeTable = NULL ;
+wxTypeInfo *wxTypeInfo::FindType(const wxChar *typeName)
+{
+ return (wxTypeInfo *)sm_typeTable->find(typeName)->second;
+}
-/*
+wxClassTypeInfo::wxClassTypeInfo( wxTypeKind kind , wxClassInfo* classInfo , converterToString_t to , converterFromString_t from ) :
+wxTypeInfo( kind , to , from , classInfo->GetClassName() )
+{ wxASSERT_MSG( kind == wxT_OBJECT_PTR || kind == wxT_OBJECT , wxT("Illegal Kind for Enum Type")) ; m_classInfo = classInfo ;}
-template<> void wxStringReadValue(const wxString &s , wxColour &data )
-{
- // copied from VS xrc
- unsigned long tmp = 0;
+wxDelegateTypeInfo::wxDelegateTypeInfo( int eventType , wxClassInfo* eventClass , converterToString_t to , converterFromString_t from ) :
+ wxTypeInfo ( wxT_DELEGATE , to , from , wxEmptyString )
+ { m_eventClass = eventClass ; m_eventType = eventType ;}
- if (s.Length() != 7 || s[0u] != wxT('#') ||
- wxSscanf(s.c_str(), wxT("#%lX"), &tmp) != 1)
- {
- wxLogError(_("String To Colour : Incorrect colour specification : %s"),
- s.c_str() );
- data = wxNullColour;
- }
- else
- {
- data = wxColour((unsigned char) ((tmp & 0xFF0000) >> 16) ,
- (unsigned char) ((tmp & 0x00FF00) >> 8),
- (unsigned char) ((tmp & 0x0000FF)));
- }
-}
+void wxTypeInfo::Register()
+{
+ if ( sm_typeTable == NULL )
+ sm_typeTable = new wxTypeInfoMap() ;
-template<> void wxStringWriteValue(wxString &s , const wxColour &data )
-{
- s = wxString::Format("#%2X%2X%2X", data.Red() , data.Green() , data.Blue() ) ;
+ if( !m_name.IsEmpty() )
+ (*sm_typeTable)[m_name] = this ;
}
-WX_CUSTOM_TYPE_INFO(wxColour)
-
-*/
+void wxTypeInfo::Unregister()
+{
+ if( !m_name.IsEmpty() )
+ sm_typeTable->erase(m_name);
+ }
// removing header dependancy on string tokenizer
accessor->AddToPropertyCollection( object , value ) ;
}
+void wxClassInfo::GetProperties( wxPropertyInfoMap &map ) const
+{
+ const wxPropertyInfo *pi = GetFirstProperty() ;
+ while( pi )
+ {
+ if ( map.find( pi->GetName() ) == map.end() )
+ map[pi->GetName()] = (wxPropertyInfo*) pi ;
+
+ pi = pi->GetNext() ;
+ }
+
+ const wxClassInfo** parents = GetParents() ;
+ for ( int i = 0 ; parents[i] ; ++ i )
+ {
+ parents[i]->GetProperties( map ) ;
+ }
+}
+
/*
VARIANT TO OBJECT
*/
void wxDynamicClassInfo::AddProperty( const wxChar *propertyName , const wxTypeInfo* typeInfo )
{
- new wxPropertyInfo( m_firstProperty , propertyName , typeInfo , new wxGenericPropertyAccessor( propertyName ) , wxxVariant() ) ;
+ new wxPropertyInfo( m_firstProperty , this , propertyName , typeInfo , new wxGenericPropertyAccessor( propertyName ) , wxxVariant() ) ;
}
void wxDynamicClassInfo::AddHandler( const wxChar *handlerName , wxObjectEventFunction address , const wxClassInfo* eventClassInfo )
struct wxWriter::wxWriterInternalPropertiesData
{
- map< string , int > m_writtenProperties ;
+ char nothing ;
} ;
void wxWriter::ClearObjectContext()
}
void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data )
{
- // in case this object is wxDynamic object we have to hand over the streaming
- // of the properties of the superclasses to the real super class instance
+ wxPropertyInfoMap map ;
+ ci->GetProperties( map ) ;
+ for ( int i = 0 ; i < ci->GetCreateParamCount() ; ++i )
{
- const wxObject *iterobj = obj ;
- const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (iterobj ) ;
- if ( dynobj )
- iterobj = dynobj->GetSuperClassInstance() ;
- const wxClassInfo** parents = ci->GetParents() ;
- for ( int i = 0 ; parents[i] ; ++ i )
+ wxString name = ci->GetCreateParamName(i) ;
+ const wxPropertyInfo* prop = map.find(name)->second ;
+ wxASSERT_MSG( prop , wxT("Create Parameter not found in declared RTTI Parameters") ) ;
+ WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+ map.erase( name ) ;
+ }
+
+ for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
+ {
+ const wxPropertyInfo* prop = iter->second ;
+ if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
+ {
+ WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+ }
+ }
+
+ for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
+ {
+ const wxPropertyInfo* prop = iter->second ;
+ if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
{
- WriteAllProperties( iterobj , parents[i] , persister , data ) ;
+ WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
}
}
+}
- const wxPropertyInfo *pi = ci->GetFirstProperty() ;
- while( pi )
+void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *data )
+{
+ // make sure that we are picking the correct object for accessing the property
+ const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (obj ) ;
+ if ( dynobj && (dynamic_cast<const wxDynamicClassInfo*>(ci) == NULL) )
+ obj = dynobj->GetSuperClassInstance() ;
+
+ DoBeginWriteProperty( pi ) ;
+ if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
{
- // this property was not written yet in this object and we don't get a veto
- // if ( data->m_writtenProperties.find( pi->GetName() ) == data->m_writtenProperties.end() )
- // we will have to handle property overrides differently
+ wxxVariantArray data ;
+ pi->GetAccessor()->GetPropertyCollection(obj, data) ;
+ const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ;
+ for ( size_t i = 0 ; i < data.GetCount() ; ++i )
{
- data->m_writtenProperties[ pi->GetName() ] = 1 ;
- DoBeginWriteProperty( pi ) ;
- if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
+ DoBeginWriteElement() ;
+ wxxVariant value = data[i] ;
+ if ( persister->BeforeWriteProperty( this , pi , value ) )
{
- wxxVariantArray data ;
- pi->GetAccessor()->GetPropertyCollection(obj, data) ;
- const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ;
- for ( size_t i = 0 ; i < data.GetCount() ; ++i )
+ const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ;
+ if ( cti )
{
- DoBeginWriteElement() ;
- wxxVariant value = data[i] ;
- if ( persister->BeforeWriteProperty( this , pi , value ) )
- {
- const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ;
- if ( cti )
- {
- const wxClassInfo* pci = cti->GetClassInfo() ;
- wxObject *vobj = pci->VariantToInstance( value ) ;
- wxxVariantArray md ;
- WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md ) ;
- }
- else
- {
- DoWriteSimpleType( value ) ;
- }
- }
- DoEndWriteElement() ;
+ const wxClassInfo* pci = cti->GetClassInfo() ;
+ wxObject *vobj = pci->VariantToInstance( value ) ;
+ wxxVariantArray md ;
+ WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md ) ;
}
- }
- else
- {
- const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
- if ( dti )
+ else
{
- const wxObject* sink = NULL ;
- const wxHandlerInfo *handler = NULL ;
+ DoWriteSimpleType( value ) ;
+ }
+ }
+ DoEndWriteElement() ;
+ }
+ }
+ else
+ {
+ const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
+ if ( dti )
+ {
+ 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 wxWindow * evSource = dynamic_cast<const wxWindow *>(obj) ;
+ wxASSERT_MSG( evSource , wxT("Illegal Object Class (Non-Window) as Event Source") ) ;
- FindConnectEntry( evSource , dti , sink , handler ) ;
- if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
- {
- if ( sink != NULL && handler != NULL )
- {
- wxASSERT_MSG( IsObjectKnown( sink ) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
- DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
- }
- }
+ FindConnectEntry( evSource , dti , sink , handler ) ;
+ if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
+ {
+ if ( sink != NULL && handler != NULL )
+ {
+ wxASSERT_MSG( IsObjectKnown( sink ) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
+ DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
}
- else
+ }
+ }
+ else
+ {
+ wxxVariant value ;
+ pi->GetAccessor()->GetProperty(obj, value) ;
+ if ( persister->BeforeWriteProperty( this , pi , value ) )
+ {
+ const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
+ if ( cti )
{
- wxxVariant value ;
- pi->GetAccessor()->GetProperty(obj, value) ;
- if ( persister->BeforeWriteProperty( this , pi , value ) )
+ const wxClassInfo* pci = cti->GetClassInfo() ;
+ wxObject *vobj = pci->VariantToInstance( value ) ;
+ wxxVariantArray md ;
+ WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
+ }
+ else
+ {
+ if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
{
- const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
- if ( cti )
- {
- const wxClassInfo* pci = cti->GetClassInfo() ;
- wxObject *vobj = pci->VariantToInstance( value ) ;
- wxxVariantArray md ;
- WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
- }
- else
- {
- DoWriteSimpleType( value ) ;
- }
+ const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
+ wxASSERT_MSG( eti , wxT("Type must have enum - long conversion") ) ;
+ eti->ConvertFromLong( value.Get<long>() , value ) ;
}
+ DoWriteSimpleType( value ) ;
}
}
- DoEndWriteProperty( pi ) ;
}
- pi = pi->GetNext() ;
}
+ DoEndWriteProperty( pi ) ;
}
int wxWriter::GetObjectID(const wxObject *obj)
{
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 ;
}