don't use wxScopedPtr<> in wxDocTemplate::CreateDocument() as the document is implici...
[wxWidgets.git] / src / common / xtistrm.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/xtistrm.cpp
3 // Purpose: streaming runtime metadata information
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 27/07/03
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_EXTENDED_RTTI
20
21 #include "wx/xtistrm.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/object.h"
25 #include "wx/hash.h"
26 #include "wx/event.h"
27 #endif
28
29 #include "wx/tokenzr.h"
30 #include "wx/txtstrm.h"
31
32 #include "wx/beforestd.h"
33 #include <map>
34 #include <vector>
35 #include <string>
36 #include "wx/afterstd.h"
37
38 using namespace std ;
39
40 struct wxWriter::wxWriterInternal
41 {
42 map< const wxObject* , int > m_writtenObjects ;
43 int m_nextId ;
44 } ;
45
46 wxWriter::wxWriter()
47 {
48 m_data = new wxWriterInternal ;
49 m_data->m_nextId = 0 ;
50 }
51
52 wxWriter::~wxWriter()
53 {
54 delete m_data ;
55 }
56
57 struct wxWriter::wxWriterInternalPropertiesData
58 {
59 char nothing ;
60 } ;
61
62 void wxWriter::ClearObjectContext()
63 {
64 delete m_data ;
65 m_data = new wxWriterInternal() ;
66 m_data->m_nextId = 0 ;
67 }
68
69 void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , const wxString &name , wxxVariantArray &metadata )
70 {
71 DoBeginWriteTopLevelEntry( name ) ;
72 WriteObject( object , classInfo , persister , false , metadata) ;
73 DoEndWriteTopLevelEntry( name ) ;
74 }
75
76 void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , bool isEmbedded, wxxVariantArray &metadata )
77 {
78 if ( !classInfo->BeforeWriteObject( object , this , persister , metadata) )
79 return ;
80
81 if ( persister->BeforeWriteObject( this , object , classInfo , metadata) )
82 {
83 if ( object == NULL )
84 DoWriteNullObject() ;
85 else if ( IsObjectKnown( object ) )
86 DoWriteRepeatedObject( GetObjectID(object) ) ;
87 else
88 {
89 int oid = m_data->m_nextId++ ;
90 if ( !isEmbedded )
91 m_data->m_writtenObjects[object] = oid ;
92
93 // in case this object is a wxDynamicObject we also have to insert is superclass
94 // instance with the same id, so that object relations are streamed out correctly
95 const wxDynamicObject* dynobj = dynamic_cast<const wxDynamicObject *>( object ) ;
96 if ( !isEmbedded && dynobj )
97 m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid ;
98
99 DoBeginWriteObject( object , classInfo , oid , metadata ) ;
100 wxWriterInternalPropertiesData data ;
101 WriteAllProperties( object , classInfo , persister , &data ) ;
102 DoEndWriteObject( object , classInfo , oid ) ;
103 }
104 persister->AfterWriteObject( this ,object , classInfo ) ;
105 }
106 }
107
108 void wxWriter::FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler)
109 {
110 wxList *dynamicEvents = evSource->GetDynamicEventTable() ;
111
112 if ( dynamicEvents )
113 {
114 wxList::compatibility_iterator node = dynamicEvents->GetFirst();
115 while (node)
116 {
117 wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
118
119 // find the match
120 if ( entry->m_fn &&
121 (dti->GetEventType() == entry->m_eventType) &&
122 (entry->m_id == -1 ) &&
123 (entry->m_eventSink != NULL ) )
124 {
125 sink = entry->m_eventSink ;
126 const wxClassInfo* sinkClassInfo = sink->GetClassInfo() ;
127 const wxHandlerInfo* sinkHandler = sinkClassInfo->GetFirstHandler() ;
128 while ( sinkHandler )
129 {
130 if ( sinkHandler->GetEventFunction() == entry->m_fn )
131 {
132 handler = sinkHandler ;
133 break ;
134 }
135 sinkHandler = sinkHandler->GetNext() ;
136 }
137 break ;
138 }
139 node = node->GetNext();
140 }
141 }
142 }
143 void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data )
144 {
145 wxPropertyInfoMap map ;
146 ci->GetProperties( map ) ;
147 for ( int i = 0 ; i < ci->GetCreateParamCount() ; ++i )
148 {
149 wxString name = ci->GetCreateParamName(i) ;
150 const wxPropertyInfo* prop = map.find(name)->second ;
151 if ( prop )
152 {
153 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
154 }
155 else
156 {
157 wxLogError( _("Create Parameter not found in declared RTTI Parameters") ) ;
158 }
159 map.erase( name ) ;
160 }
161 { // Extra block for broken compilers
162 for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
163 {
164 const wxPropertyInfo* prop = iter->second ;
165 if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
166 {
167 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
168 }
169 }
170 }
171 { // Extra block for broken compilers
172 for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
173 {
174 const wxPropertyInfo* prop = iter->second ;
175 if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
176 {
177 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
178 }
179 }
180 }
181 }
182
183 void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *WXUNUSED(data) )
184 {
185 if ( pi->GetFlags() & wxPROP_DONT_STREAM )
186 return ;
187
188 // make sure that we are picking the correct object for accessing the property
189 const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (obj ) ;
190 if ( dynobj && (dynamic_cast<const wxDynamicClassInfo*>(ci) == NULL) )
191 obj = dynobj->GetSuperClassInstance() ;
192
193 if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
194 {
195 wxxVariantArray data ;
196 pi->GetAccessor()->GetPropertyCollection(obj, data) ;
197 const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ;
198 for ( size_t i = 0 ; i < data.GetCount() ; ++i )
199 {
200 if ( i == 0 )
201 DoBeginWriteProperty( pi ) ;
202
203 DoBeginWriteElement() ;
204 wxxVariant value = data[i] ;
205 if ( persister->BeforeWriteProperty( this , obj, pi , value ) )
206 {
207 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ;
208 if ( cti )
209 {
210 const wxClassInfo* pci = cti->GetClassInfo() ;
211 wxObject *vobj = pci->VariantToInstance( value ) ;
212 wxxVariantArray md ;
213 WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md ) ;
214 }
215 else
216 {
217 DoWriteSimpleType( value ) ;
218 }
219 }
220 DoEndWriteElement() ;
221 if ( i == data.GetCount() - 1 )
222 DoEndWriteProperty( pi ) ;
223 }
224 }
225 else
226 {
227 const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
228 if ( dti )
229 {
230 const wxObject* sink = NULL ;
231 const wxHandlerInfo *handler = NULL ;
232
233 const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ;
234 if ( evSource )
235 {
236 FindConnectEntry( evSource , dti , sink , handler ) ;
237 if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
238 {
239 if ( sink != NULL && handler != NULL )
240 {
241 DoBeginWriteProperty( pi ) ;
242 if ( IsObjectKnown( sink ) )
243 {
244 DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
245 DoEndWriteProperty( pi ) ;
246 }
247 else
248 {
249 wxLogError( _("Streaming delegates for not already streamed objects not yet supported") ) ;
250 }
251 }
252 }
253 }
254 else
255 {
256 wxLogError(_("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ;
257 }
258 }
259 else
260 {
261 wxxVariant value ;
262 pi->GetAccessor()->GetProperty(obj, value) ;
263
264 // avoid streaming out void objects
265 if( value.IsEmpty() )
266 return ;
267
268 if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
269 {
270 const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
271 if ( eti )
272 {
273 eti->ConvertFromLong( value.wxTEMPLATED_MEMBER_CALL(Get , long) , value ) ;
274 }
275 else
276 {
277 wxLogError( _("Type must have enum - long conversion") ) ;
278 }
279 }
280
281 // avoid streaming out default values
282 if ( pi->GetTypeInfo()->HasStringConverters() && !pi->GetDefaultValue().IsEmpty() )
283 {
284 if ( value.GetAsString() == pi->GetDefaultValue().GetAsString() )
285 return ;
286 }
287
288 // avoid streaming out null objects
289 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
290
291 if ( cti && value.GetAsObject() == NULL )
292 return ;
293
294 if ( persister->BeforeWriteProperty( this , obj, pi , value ) )
295 {
296 DoBeginWriteProperty( pi ) ;
297 if ( cti )
298 {
299 const wxClassInfo* pci = cti->GetClassInfo() ;
300 wxObject *vobj = pci->VariantToInstance( value ) ;
301 if ( vobj && pi->GetTypeInfo()->HasStringConverters() )
302 {
303 wxString stringValue ;
304 cti->ConvertToString( value , stringValue ) ;
305 wxxVariant convertedValue(stringValue) ;
306 DoWriteSimpleType( convertedValue ) ;
307 }
308 else
309 {
310 wxxVariantArray md ;
311 WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
312 }
313 }
314 else
315 {
316 DoWriteSimpleType( value ) ;
317 }
318 DoEndWriteProperty( pi ) ;
319 }
320 }
321 }
322 }
323
324 int wxWriter::GetObjectID(const wxObject *obj)
325 {
326 if ( !IsObjectKnown( obj ) )
327 return wxInvalidObjectID ;
328
329 return m_data->m_writtenObjects[obj] ;
330 }
331
332 bool wxWriter::IsObjectKnown( const wxObject *obj )
333 {
334 return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ;
335 }
336
337
338 // ----------------------------------------------------------------------------
339 // reading objects in
340 // ----------------------------------------------------------------------------
341
342 struct wxReader::wxReaderInternal
343 {
344 map<int,wxClassInfo*> m_classInfos;
345 };
346
347 wxReader::wxReader()
348 {
349 m_data = new wxReaderInternal;
350 }
351
352 wxReader::~wxReader()
353 {
354 delete m_data;
355 }
356
357 wxClassInfo* wxReader::GetObjectClassInfo(int objectID)
358 {
359 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
360 {
361 wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) ) ;
362 return NULL ;
363 }
364 if ( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() )
365 {
366 wxLogError( _("Unknown Object passed to GetObjectClassInfo" ) ) ;
367 return NULL ;
368 }
369 return m_data->m_classInfos[objectID] ;
370 }
371
372 void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo )
373 {
374 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
375 {
376 wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) ) ;
377 return ;
378 }
379 if ( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() )
380 {
381 wxLogError( _("Already Registered Object passed to SetObjectClassInfo" ) ) ;
382 return ;
383 }
384 m_data->m_classInfos[objectID] = classInfo ;
385 }
386
387 bool wxReader::HasObjectClassInfo( int objectID )
388 {
389 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
390 {
391 wxLogError( _("Invalid or Null Object ID passed to HasObjectClassInfo" ) ) ;
392 return false ;
393 }
394 return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ;
395 }
396
397
398 // ----------------------------------------------------------------------------
399 // reading xml in
400 // ----------------------------------------------------------------------------
401
402 /*
403 Reading components has not to be extended for components
404 as properties are always sought by typeinfo over all levels
405 and create params are always toplevel class only
406 */
407
408
409 // ----------------------------------------------------------------------------
410 // depersisting to memory
411 // ----------------------------------------------------------------------------
412
413 struct wxRuntimeDepersister::wxRuntimeDepersisterInternal
414 {
415 map<int,wxObject *> m_objects;
416
417 void SetObject(int objectID, wxObject *obj )
418 {
419 if ( m_objects.find(objectID) != m_objects.end() )
420 {
421 wxLogError( _("Passing a already registered object to SetObject") ) ;
422 return ;
423 }
424 m_objects[objectID] = obj ;
425 }
426 wxObject* GetObject( int objectID )
427 {
428 if ( objectID == wxNullObjectID )
429 return NULL ;
430 if ( m_objects.find(objectID) == m_objects.end() )
431 {
432 wxLogError( _("Passing an unknown object to GetObject") ) ;
433 return NULL ;
434 }
435
436 return m_objects[objectID] ;
437 }
438 } ;
439
440 wxRuntimeDepersister::wxRuntimeDepersister()
441 {
442 m_data = new wxRuntimeDepersisterInternal() ;
443 }
444
445 wxRuntimeDepersister::~wxRuntimeDepersister()
446 {
447 delete m_data ;
448 }
449
450 void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
451 wxxVariantArray &WXUNUSED(metadata))
452 {
453 wxObject *O;
454 O = classInfo->CreateObject();
455 m_data->SetObject(objectID, O);
456 }
457
458 void wxRuntimeDepersister::CreateObject(int objectID,
459 const wxClassInfo *classInfo,
460 int paramCount,
461 wxxVariant *params,
462 int *objectIdValues,
463 const wxClassInfo **objectClassInfos ,
464 wxxVariantArray &WXUNUSED(metadata))
465 {
466 wxObject *o;
467 o = m_data->GetObject(objectID);
468 for ( int i = 0 ; i < paramCount ; ++i )
469 {
470 if ( objectIdValues[i] != wxInvalidObjectID )
471 {
472 wxObject *o;
473 o = m_data->GetObject(objectIdValues[i]);
474 // if this is a dynamic object and we are asked for another class
475 // than wxDynamicObject we cast it down manually.
476 wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ;
477 if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
478 {
479 o = dyno->GetSuperClassInstance() ;
480 }
481 params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
482 }
483 }
484 classInfo->Create(o, paramCount, params);
485 }
486
487 void wxRuntimeDepersister::ConstructObject(int objectID,
488 const wxClassInfo *classInfo,
489 int paramCount,
490 wxxVariant *params,
491 int *objectIdValues,
492 const wxClassInfo **objectClassInfos ,
493 wxxVariantArray &WXUNUSED(metadata))
494 {
495 wxObject *o;
496 for ( int i = 0 ; i < paramCount ; ++i )
497 {
498 if ( objectIdValues[i] != wxInvalidObjectID )
499 {
500 wxObject *o;
501 o = m_data->GetObject(objectIdValues[i]);
502 // if this is a dynamic object and we are asked for another class
503 // than wxDynamicObject we cast it down manually.
504 wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ;
505 if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
506 {
507 o = dyno->GetSuperClassInstance() ;
508 }
509 params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
510 }
511 }
512 o = classInfo->ConstructObject(paramCount, params);
513 m_data->SetObject(objectID, o);
514 }
515
516
517 void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
518 {
519 wxObject *o;
520 o = m_data->GetObject(objectID);
521 delete o ;
522 }
523
524 void wxRuntimeDepersister::SetProperty(int objectID,
525 const wxClassInfo *classInfo,
526 const wxPropertyInfo* propertyInfo,
527 const wxxVariant &value)
528 {
529 wxObject *o;
530 o = m_data->GetObject(objectID);
531 classInfo->SetProperty( o , propertyInfo->GetName() , value ) ;
532 }
533
534 void wxRuntimeDepersister::SetPropertyAsObject(int objectID,
535 const wxClassInfo *classInfo,
536 const wxPropertyInfo* propertyInfo,
537 int valueObjectId)
538 {
539 wxObject *o, *valo;
540 o = m_data->GetObject(objectID);
541 valo = m_data->GetObject(valueObjectId);
542 const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo() ;
543 // if this is a dynamic object and we are asked for another class
544 // than wxDynamicObject we cast it down manually.
545 wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ;
546 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
547 {
548 valo = dynvalo->GetSuperClassInstance() ;
549 }
550
551 classInfo->SetProperty( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ;
552 }
553
554 void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
555 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
556 const wxPropertyInfo *delegateInfo ,
557 const wxClassInfo *WXUNUSED(eventSinkClassInfo) ,
558 const wxHandlerInfo* handlerInfo ,
559 int eventSinkObjectID )
560 {
561 wxEvtHandler *ehsource = dynamic_cast< wxEvtHandler* >( m_data->GetObject( eventSourceObjectID ) ) ;
562 wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ;
563
564 if ( ehsource && ehsink )
565 {
566 const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo());
567 if( delegateTypeInfo && delegateTypeInfo->GetLastEventType() == -1 )
568 {
569 ehsource->Connect( -1 , delegateTypeInfo->GetEventType() ,
570 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
571 ehsink ) ;
572 }
573 else
574 {
575 for ( wxEventType iter = delegateTypeInfo->GetEventType() ; iter <= delegateTypeInfo->GetLastEventType() ; ++iter )
576 {
577 ehsource->Connect( -1 , iter ,
578 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
579 ehsink ) ;
580 }
581 }
582 }
583 }
584
585 wxObject *wxRuntimeDepersister::GetObject(int objectID)
586 {
587 return m_data->GetObject( objectID ) ;
588 }
589
590 // adds an element to a property collection
591 void wxRuntimeDepersister::AddToPropertyCollection( int objectID ,
592 const wxClassInfo *classInfo,
593 const wxPropertyInfo* propertyInfo ,
594 const wxxVariant &value)
595 {
596 wxObject *o;
597 o = m_data->GetObject(objectID);
598 classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , value ) ;
599 }
600
601 // sets the corresponding property (value is an object)
602 void wxRuntimeDepersister::AddToPropertyCollectionAsObject(int objectID,
603 const wxClassInfo *classInfo,
604 const wxPropertyInfo* propertyInfo ,
605 int valueObjectId)
606 {
607 wxObject *o, *valo;
608 o = m_data->GetObject(objectID);
609 valo = m_data->GetObject(valueObjectId);
610 const wxCollectionTypeInfo * collectionTypeInfo = dynamic_cast< const wxCollectionTypeInfo * >(propertyInfo->GetTypeInfo() ) ;
611 const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(collectionTypeInfo->GetElementType()))->GetClassInfo() ;
612 // if this is a dynamic object and we are asked for another class
613 // than wxDynamicObject we cast it down manually.
614 wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ;
615 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
616 {
617 valo = dynvalo->GetSuperClassInstance() ;
618 }
619
620 classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ;
621 }
622
623 // ----------------------------------------------------------------------------
624 // depersisting to code
625 // ----------------------------------------------------------------------------
626
627 struct wxCodeDepersister::wxCodeDepersisterInternal
628 {
629 #if wxUSE_UNICODE
630 map<int,wstring> m_objectNames ;
631 #else
632 map<int,string> m_objectNames ;
633 #endif
634
635 void SetObjectName(int objectID, const wxString &name )
636 {
637 if ( m_objectNames.find(objectID) != m_objectNames.end() )
638 {
639 wxLogError( _("Passing a already registered object to SetObjectName") ) ;
640 return ;
641 }
642 m_objectNames[objectID] = (const wxChar *)name;
643 }
644
645 wxString GetObjectName( int objectID )
646 {
647 if ( objectID == wxNullObjectID )
648 return wxT("NULL") ;
649
650 if ( m_objectNames.find(objectID) == m_objectNames.end() )
651 {
652 wxLogError( _("Passing an unkown object to GetObject") ) ;
653 return wxEmptyString ;
654 }
655 return wxString( m_objectNames[objectID].c_str() ) ;
656 }
657 } ;
658
659 wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
660 : m_fp(out)
661 {
662 m_data = new wxCodeDepersisterInternal ;
663 }
664
665 wxCodeDepersister::~wxCodeDepersister()
666 {
667 delete m_data ;
668 }
669
670 void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
671 wxxVariantArray &WXUNUSED(metadata))
672 {
673 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
674 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s;\n"),
675 classInfo->GetClassName(),
676 objectName.c_str(),
677 classInfo->GetClassName()) );
678 m_data->SetObjectName( objectID , objectName ) ;
679 }
680
681 void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
682 {
683 m_fp->WriteString( wxString::Format( wxT("\tdelete %s;\n"),
684 m_data->GetObjectName( objectID).c_str() ) );
685 }
686
687 wxString wxCodeDepersister::ValueAsCode( const wxxVariant &param )
688 {
689 wxString value ;
690 const wxTypeInfo* type = param.GetTypeInfo() ;
691 if ( type->GetKind() == wxT_CUSTOM )
692 {
693 const wxCustomTypeInfo* cti = dynamic_cast<const wxCustomTypeInfo*>(type) ;
694 if ( cti )
695 {
696 value.Printf( wxT("%s(%s)"), cti->GetTypeName().c_str(),param.GetAsString().c_str() );
697 }
698 else
699 {
700 wxLogError ( _("Internal error, illegal wxCustomTypeInfo") ) ;
701 }
702 }
703 else if ( type->GetKind() == wxT_STRING )
704 {
705 value.Printf( wxT("\"%s\""),param.GetAsString().c_str() );
706 }
707 else
708 {
709 value.Printf( wxT("%s"), param.GetAsString().c_str() );
710 }
711 return value ;
712 }
713
714 void wxCodeDepersister::CreateObject(int objectID,
715 const wxClassInfo *WXUNUSED(classInfo),
716 int paramCount,
717 wxxVariant *params,
718 int *objectIDValues,
719 const wxClassInfo **WXUNUSED(objectClassInfos) ,
720 wxxVariantArray &WXUNUSED(metadata)
721 )
722 {
723 int i;
724 m_fp->WriteString( wxString::Format( wxT("\t%s->Create("), m_data->GetObjectName(objectID).c_str() ) );
725 for (i = 0; i < paramCount; i++)
726 {
727 if ( objectIDValues[i] != wxInvalidObjectID )
728 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
729 else
730 {
731 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
732 }
733 if (i < paramCount - 1)
734 m_fp->WriteString( wxT(", "));
735 }
736 m_fp->WriteString( wxT(");\n") );
737 }
738
739 void wxCodeDepersister::ConstructObject(int objectID,
740 const wxClassInfo *classInfo,
741 int paramCount,
742 wxxVariant *params,
743 int *objectIDValues,
744 const wxClassInfo **WXUNUSED(objectClassInfos) ,
745 wxxVariantArray &WXUNUSED(metadata)
746 )
747 {
748 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
749 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s("),
750 classInfo->GetClassName(),
751 objectName.c_str(),
752 classInfo->GetClassName()) );
753 m_data->SetObjectName( objectID , objectName ) ;
754
755 int i;
756 for (i = 0; i < paramCount; i++)
757 {
758 if ( objectIDValues[i] != wxInvalidObjectID )
759 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
760 else
761 {
762 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
763 }
764 if (i < paramCount - 1)
765 m_fp->WriteString( wxT(", ") );
766 }
767 m_fp->WriteString( wxT(");\n") );
768 }
769
770 void wxCodeDepersister::SetProperty(int objectID,
771 const wxClassInfo *WXUNUSED(classInfo),
772 const wxPropertyInfo* propertyInfo,
773 const wxxVariant &value)
774 {
775 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
776 m_data->GetObjectName(objectID).c_str(),
777 propertyInfo->GetAccessor()->GetSetterName().c_str(),
778 ValueAsCode(value).c_str()) );
779 }
780
781 void wxCodeDepersister::SetPropertyAsObject(int objectID,
782 const wxClassInfo *WXUNUSED(classInfo),
783 const wxPropertyInfo* propertyInfo,
784 int valueObjectId)
785 {
786 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
787 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(*%s);\n"),
788 m_data->GetObjectName(objectID).c_str(),
789 propertyInfo->GetAccessor()->GetSetterName().c_str(),
790 m_data->GetObjectName( valueObjectId).c_str() ) );
791 else
792 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
793 m_data->GetObjectName(objectID).c_str(),
794 propertyInfo->GetAccessor()->GetSetterName().c_str(),
795 m_data->GetObjectName( valueObjectId).c_str() ) );
796 }
797
798 void wxCodeDepersister::AddToPropertyCollection( int objectID ,
799 const wxClassInfo *WXUNUSED(classInfo),
800 const wxPropertyInfo* propertyInfo ,
801 const wxxVariant &value)
802 {
803 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
804 m_data->GetObjectName(objectID).c_str(),
805 propertyInfo->GetAccessor()->GetAdderName().c_str(),
806 ValueAsCode(value).c_str()) );
807 }
808
809 // sets the corresponding property (value is an object)
810 void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID),
811 const wxClassInfo *WXUNUSED(classInfo),
812 const wxPropertyInfo* WXUNUSED(propertyInfo) ,
813 int WXUNUSED(valueObjectId))
814 {
815 // TODO
816 }
817
818 void wxCodeDepersister::SetConnect(int eventSourceObjectID,
819 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
820 const wxPropertyInfo *delegateInfo ,
821 const wxClassInfo *eventSinkClassInfo ,
822 const wxHandlerInfo* handlerInfo ,
823 int eventSinkObjectID )
824 {
825 wxString ehsource = m_data->GetObjectName( eventSourceObjectID ) ;
826 wxString ehsink = m_data->GetObjectName(eventSinkObjectID) ;
827 wxString ehsinkClass = eventSinkClassInfo->GetClassName() ;
828 const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo());
829 if ( delegateTypeInfo )
830 {
831 int eventType = delegateTypeInfo->GetEventType() ;
832 wxString handlerName = handlerInfo->GetName() ;
833
834 m_fp->WriteString( wxString::Format( wxT("\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;") ,
835 ehsource.c_str() , ehsource.c_str() , eventType , ehsinkClass.c_str() , handlerName.c_str() , ehsink.c_str() ) );
836 }
837 else
838 {
839 wxLogError(_("delegate has no type info"));
840 }
841 }
842
843 #include "wx/arrimpl.cpp"
844
845 WX_DEFINE_OBJARRAY(wxxVariantArray)
846
847 #endif // wxUSE_EXTENDED_RTTI