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