]> git.saurik.com Git - wxWidgets.git/blame - src/common/xti.cpp
Mention wxGTK wxAnimation implementation limitations in the docs.
[wxWidgets.git] / src / common / xti.cpp
CommitLineData
a095505c
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/xti.cpp
13830d6f 3// Purpose: runtime metadata information (extended class info)
a095505c 4// Author: Stefan Csomor
30fd71e6 5// Modified by:
a095505c
SC
6// Created: 27/07/03
7// RCS-ID: $Id$
8// Copyright: (c) 1997 Julian Smart
9// (c) 2003 Stefan Csomor
65571936 10// Licence: wxWindows licence
a095505c
SC
11/////////////////////////////////////////////////////////////////////////////
12
a095505c
SC
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
8e3f3880 17 #pragma hdrstop
a095505c
SC
18#endif
19
8e3f3880
WS
20#if wxUSE_EXTENDED_RTTI
21
a095505c 22#ifndef WX_PRECOMP
8e3f3880 23 #include "wx/object.h"
8ecff181 24 #include "wx/list.h"
8e3f3880 25 #include "wx/hash.h"
a095505c
SC
26#endif
27
53b74313 28#include "wx/xti.h"
a095505c
SC
29#include "wx/xml/xml.h"
30#include "wx/tokenzr.h"
e765d7ee
SC
31#include "wx/range.h"
32
a095505c
SC
33#include <string.h>
34
ab6e4913 35#include "wx/beforestd.h"
2d51f067
SC
36#include <map>
37#include <string>
8f2b1cfd 38#include <list>
ab6e4913 39#include "wx/afterstd.h"
2d51f067 40
13830d6f 41using namespace std;
2d51f067 42
a095505c 43// ----------------------------------------------------------------------------
13830d6f 44// wxEnumData
a095505c
SC
45// ----------------------------------------------------------------------------
46
30fd71e6 47wxEnumData::wxEnumData( wxEnumMemberData* data )
a095505c 48{
13830d6f
SC
49 m_members = data;
50 for ( m_count = 0; m_members[m_count].m_name; m_count++)
51 {};
a095505c
SC
52}
53
9a75ecf6 54bool wxEnumData::HasEnumMemberValue(const wxChar *name, int *value) const
a095505c
SC
55{
56 int i;
13830d6f 57 for (i = 0; m_members[i].m_name; i++ )
2abce515 58 {
9dc6871e 59 if (!wxStrcmp(name, m_members[i].m_name))
2abce515
SC
60 {
61 if ( value )
62 *value = m_members[i].m_value;
13830d6f 63 return true;
2abce515
SC
64 }
65 }
13830d6f 66 return false;
a095505c
SC
67}
68
9a75ecf6 69int wxEnumData::GetEnumMemberValue(const wxChar *name) const
a095505c
SC
70{
71 int i;
13830d6f 72 for (i = 0; m_members[i].m_name; i++ )
2abce515 73 {
9dc6871e 74 if (!wxStrcmp(name, m_members[i].m_name))
2abce515
SC
75 {
76 return m_members[i].m_value;
77 }
78 }
13830d6f 79 return 0;
a095505c
SC
80}
81
9a75ecf6 82const wxChar *wxEnumData::GetEnumMemberName(int value) const
a095505c
SC
83{
84 int i;
13830d6f 85 for (i = 0; m_members[i].m_name; i++)
2abce515
SC
86 if (value == m_members[i].m_value)
87 return m_members[i].m_name;
a095505c 88
13830d6f 89 return wxEmptyString;
a095505c
SC
90}
91
9a75ecf6 92int wxEnumData::GetEnumMemberValueByIndex( int idx ) const
a095505c 93{
2abce515 94 // we should cache the count in order to avoid out-of-bounds errors
13830d6f 95 return m_members[idx].m_value;
a095505c
SC
96}
97
9a75ecf6 98const wxChar * wxEnumData::GetEnumMemberNameByIndex( int idx ) const
a095505c 99{
2abce515 100 // we should cache the count in order to avoid out-of-bounds errors
13830d6f 101 return m_members[idx].m_name;
a095505c
SC
102}
103
104// ----------------------------------------------------------------------------
105// Type Information
106// ----------------------------------------------------------------------------
13830d6f 107
a095505c 108// ----------------------------------------------------------------------------
30fd71e6 109// value streaming
a095505c
SC
110// ----------------------------------------------------------------------------
111
a095505c 112// streamer specializations
45212047 113// for all built-in types
a095505c 114
45212047 115// bool
a095505c 116
13830d6f 117template<> void wxStringReadValue(const wxString &s, bool &data )
45212047 118{
13830d6f
SC
119 int intdata;
120 wxSscanf(s, _T("%d"), &intdata );
121 data = (bool)(intdata != 0);
45212047 122}
a095505c 123
13830d6f 124template<> void wxStringWriteValue(wxString &s, const bool &data )
a095505c 125{
13830d6f 126 s = wxString::Format(_T("%d"), data );
a095505c
SC
127}
128
45212047
SC
129// char
130
13830d6f 131template<> void wxStringReadValue(const wxString &s, char &data )
a095505c 132{
13830d6f
SC
133 int intdata;
134 wxSscanf(s, _T("%d"), &intdata );
135 data = char(intdata);
45212047
SC
136}
137
13830d6f 138template<> void wxStringWriteValue(wxString &s, const char &data )
45212047 139{
13830d6f 140 s = wxString::Format(_T("%d"), data );
45212047
SC
141}
142
143// unsigned char
144
13830d6f 145template<> void wxStringReadValue(const wxString &s, unsigned char &data )
45212047 146{
13830d6f
SC
147 int intdata;
148 wxSscanf(s, _T("%d"), &intdata );
149 data = (unsigned char)(intdata);
45212047
SC
150}
151
13830d6f 152template<> void wxStringWriteValue(wxString &s, const unsigned char &data )
45212047 153{
13830d6f 154 s = wxString::Format(_T("%d"), data );
a095505c
SC
155}
156
30fd71e6 157// int
a095505c 158
13830d6f 159template<> void wxStringReadValue(const wxString &s, int &data )
a095505c 160{
13830d6f 161 wxSscanf(s, _T("%d"), &data );
a095505c
SC
162}
163
13830d6f 164template<> void wxStringWriteValue(wxString &s, const int &data )
a095505c 165{
13830d6f 166 s = wxString::Format(_T("%d"), data );
a095505c
SC
167}
168
45212047
SC
169// unsigned int
170
13830d6f 171template<> void wxStringReadValue(const wxString &s, unsigned int &data )
45212047 172{
13830d6f 173 wxSscanf(s, _T("%d"), &data );
45212047
SC
174}
175
13830d6f 176template<> void wxStringWriteValue(wxString &s, const unsigned int &data )
45212047 177{
13830d6f 178 s = wxString::Format(_T("%d"), data );
45212047
SC
179}
180
181// long
182
13830d6f 183template<> void wxStringReadValue(const wxString &s, long &data )
45212047 184{
13830d6f 185 wxSscanf(s, _T("%ld"), &data );
45212047
SC
186}
187
13830d6f 188template<> void wxStringWriteValue(wxString &s, const long &data )
45212047 189{
13830d6f 190 s = wxString::Format(_T("%ld"), data );
45212047
SC
191}
192
193// unsigned long
194
13830d6f 195template<> void wxStringReadValue(const wxString &s, unsigned long &data )
45212047 196{
13830d6f 197 wxSscanf(s, _T("%ld"), &data );
45212047
SC
198}
199
13830d6f 200template<> void wxStringWriteValue(wxString &s, const unsigned long &data )
45212047 201{
13830d6f 202 s = wxString::Format(_T("%ld"), data );
45212047
SC
203}
204
e765d7ee
SC
205#ifdef wxLongLong_t
206template<> void wxStringReadValue(const wxString &s, wxLongLong_t &data )
207{
208 wxSscanf(s, _T("%lld"), &data );
209}
210
211template<> void wxStringWriteValue(wxString &s, const wxLongLong_t &data )
212{
213 s = wxString::Format(_T("%lld"), data );
214}
215
216template<> void wxStringReadValue(const wxString &s, wxULongLong_t &data )
217{
218 wxSscanf(s, _T("%lld"), &data );
219}
220
221template<> void wxStringWriteValue(wxString &s, const wxULongLong_t &data )
222{
223 s = wxString::Format(_T("%lld"), data );
224}
225#endif
45212047
SC
226// float
227
13830d6f 228template<> void wxStringReadValue(const wxString &s, float &data )
45212047 229{
13830d6f 230 wxSscanf(s, _T("%f"), &data );
45212047
SC
231}
232
13830d6f 233template<> void wxStringWriteValue(wxString &s, const float &data )
45212047 234{
13830d6f 235 s = wxString::Format(_T("%f"), data );
45212047
SC
236}
237
238// double
239
13830d6f 240template<> void wxStringReadValue(const wxString &s, double &data )
45212047 241{
13830d6f 242 wxSscanf(s, _T("%lf"), &data );
45212047
SC
243}
244
13830d6f 245template<> void wxStringWriteValue(wxString &s, const double &data )
45212047 246{
13830d6f 247 s = wxString::Format(_T("%lf"), data );
45212047
SC
248}
249
a095505c
SC
250// wxString
251
13830d6f 252template<> void wxStringReadValue(const wxString &s, wxString &data )
a095505c 253{
13830d6f 254 data = s;
a095505c
SC
255}
256
13830d6f 257template<> void wxStringWriteValue(wxString &s, const wxString &data )
a095505c 258{
13830d6f 259 s = data;
a095505c
SC
260}
261
13830d6f 262
c1d6d0f9
SC
263// built-ins
264//
b8d5be01 265
af498247 266#if wxUSE_FUNC_TEMPLATE_POINTER
13830d6f
SC
267 #define wxBUILTIN_TYPE_INFO( element, type ) \
268 wxBuiltInTypeInfo \
269 s_typeInfo##type(element, &wxToStringConverter<type>, \
270 &wxFromStringConverter<type>, typeid(type).name());
af498247 271#else
13830d6f 272 #define wxBUILTIN_TYPE_INFO( element, type ) \
e765d7ee 273 void _toString##element( const wxAny& data, wxString &result ) \
13830d6f 274 { wxToStringConverter<type, data, result); } \
e765d7ee 275 void _fromString##element( const wxString& data, wxAny &result ) \
13830d6f
SC
276 { wxFromStringConverter<type, data, result); } \
277 wxBuiltInTypeInfo s_typeInfo##type(element, &_toString##element, \
278 &_fromString##element, typeid(type).name());
af498247
VZ
279#endif
280
281typedef unsigned char unsigned_char;
282typedef unsigned int unsigned_int;
283typedef unsigned long unsigned_long;
284
13830d6f
SC
285wxBuiltInTypeInfo s_typeInfovoid( wxT_VOID, NULL, NULL, typeid(void).name());
286wxBUILTIN_TYPE_INFO( wxT_BOOL, bool);
287wxBUILTIN_TYPE_INFO( wxT_CHAR, char);
288wxBUILTIN_TYPE_INFO( wxT_UCHAR, unsigned_char);
289wxBUILTIN_TYPE_INFO( wxT_INT, int);
290wxBUILTIN_TYPE_INFO( wxT_UINT, unsigned_int);
291wxBUILTIN_TYPE_INFO( wxT_LONG, long);
292wxBUILTIN_TYPE_INFO( wxT_ULONG, unsigned_long);
293wxBUILTIN_TYPE_INFO( wxT_FLOAT, float);
294wxBUILTIN_TYPE_INFO( wxT_DOUBLE, double);
295wxBUILTIN_TYPE_INFO( wxT_STRING, wxString);
af498247 296
e765d7ee
SC
297#ifdef wxLongLong_t
298wxBUILTIN_TYPE_INFO(wxT_LONGLONG, wxLongLong_t)
299wxBUILTIN_TYPE_INFO(wxT_ULONGLONG, wxULongLong_t)
300#endif
b8d5be01
SC
301
302// this are compiler induced specialization which are never used anywhere
303
8805dbab
SC
304wxILLEGAL_TYPE_SPECIALIZATION( char const * )
305wxILLEGAL_TYPE_SPECIALIZATION( char * )
306wxILLEGAL_TYPE_SPECIALIZATION( unsigned char * )
307wxILLEGAL_TYPE_SPECIALIZATION( int * )
308wxILLEGAL_TYPE_SPECIALIZATION( bool * )
309wxILLEGAL_TYPE_SPECIALIZATION( long * )
310wxILLEGAL_TYPE_SPECIALIZATION( wxString * )
b8d5be01 311
e765d7ee
SC
312// wxRange
313
314template<> void wxStringReadValue(const wxString &s , wxRange &data)
315{
316 int minValue, maxValue;
317 wxSscanf(s, wxT("%d,%d"), &minValue , &maxValue);
318 data = wxRange(minValue, maxValue);
319}
320
321template<> void wxStringWriteValue(wxString &s , const wxRange &data)
322{
323 s = wxString::Format(wxT("%d,%d"), data.GetMin() , data.GetMax());
324}
325
326wxCUSTOM_TYPE_INFO(wxRange, wxToStringConverter<wxRange> , wxFromStringConverter<wxRange>)
327
328// other types
329
13830d6f 330wxCOLLECTION_TYPE_INFO( wxString, wxArrayString );
b8d5be01 331
13830d6f 332template<> void wxCollectionToVariantArray( wxArrayString const &theArray,
e765d7ee 333 wxAnyList &value)
b8d5be01 334{
13830d6f 335 wxArrayCollectionToVariantArray( theArray, value );
b8d5be01
SC
336}
337
13830d6f 338wxTypeInfoMap *wxTypeInfo::ms_typeTable = NULL;
b8d5be01 339
e765d7ee 340wxTypeInfo *wxTypeInfo::FindType(const wxString& typeName)
cb73e600 341{
13830d6f
SC
342 wxTypeInfoMap::iterator iter = ms_typeTable->find(typeName);
343
13830d6f
SC
344 if (iter == ms_typeTable->end())
345 return NULL;
346
499a9a62 347 return (wxTypeInfo *)iter->second;
cb73e600 348}
b8d5be01 349
13830d6f
SC
350wxClassTypeInfo::wxClassTypeInfo( wxTypeKind kind, wxClassInfo* classInfo,
351 wxVariant2StringFnc to,
352 wxString2VariantFnc from,
353 const wxString &name) :
354 wxTypeInfo( kind, to, from, name)
355{
356 wxASSERT_MSG( kind == wxT_OBJECT_PTR || kind == wxT_OBJECT,
357 wxT("Illegal Kind for Enum Type")); m_classInfo = classInfo;
358}
359
360wxEventSourceTypeInfo::wxEventSourceTypeInfo( int eventType, wxClassInfo* eventClass,
361 wxVariant2StringFnc to,
362 wxString2VariantFnc from ) :
363 wxTypeInfo ( wxT_DELEGATE, to, from, wxEmptyString )
364{
365 m_eventClass = eventClass;
366 m_eventType = eventType;
367 m_lastEventType = -1;
368}
369
370wxEventSourceTypeInfo::wxEventSourceTypeInfo( int eventType, int lastEventType,
371 wxClassInfo* eventClass,
372 wxVariant2StringFnc to,
373 wxString2VariantFnc from ) :
374 wxTypeInfo ( wxT_DELEGATE, to, from, wxEmptyString )
375{
376 m_eventClass = eventClass;
377 m_eventType = eventType;
378 m_lastEventType = lastEventType;
379}
45212047 380
cb73e600 381void wxTypeInfo::Register()
cab1a605 382{
05fa251a 383 if ( ms_typeTable == NULL )
13830d6f 384 ms_typeTable = new wxTypeInfoMap();
45212047 385
525d8583 386 if( !m_name.empty() )
13830d6f 387 (*ms_typeTable)[m_name] = this;
45212047
SC
388}
389
cb73e600
SC
390void wxTypeInfo::Unregister()
391{
525d8583 392 if( !m_name.empty() )
05fa251a 393 ms_typeTable->erase(m_name);
2abce515 394}
45212047 395
a095505c
SC
396// removing header dependancy on string tokenizer
397
13830d6f 398void wxSetStringToArray( const wxString &s, wxArrayString &array )
a095505c
SC
399{
400 wxStringTokenizer tokenizer(s, wxT("| \t\n"), wxTOKEN_STRTOK);
401 wxString flag;
13830d6f 402 array.Clear();
a095505c
SC
403 while (tokenizer.HasMoreTokens())
404 {
13830d6f 405 array.Add(tokenizer.GetNextToken());
2abce515 406 }
a095505c
SC
407}
408
409// ----------------------------------------------------------------------------
13830d6f 410// wxPropertyInfo
a095505c
SC
411// ----------------------------------------------------------------------------
412
13830d6f
SC
413void wxPropertyInfo::Insert(wxPropertyInfo* &iter)
414{
415 m_next = NULL;
416 if ( iter == NULL )
417 iter = this;
418 else
419 {
420 wxPropertyInfo* i = iter;
421 while( i->m_next )
422 i = i->m_next;
423
424 i->m_next = this;
425 }
426}
427
428void wxPropertyInfo::Remove()
499a9a62
SC
429{
430 if ( this == m_itsClass->m_firstProperty )
431 {
432 m_itsClass->m_firstProperty = m_next;
433 }
434 else
435 {
436 wxPropertyInfo *info = m_itsClass->m_firstProperty;
437 while (info)
438 {
439 if ( info->m_next == this )
440 {
441 info->m_next = m_next;
442 break;
443 }
444
445 info = info->m_next;
446 }
447 }
e765d7ee 448
499a9a62
SC
449}
450
13830d6f
SC
451// ----------------------------------------------------------------------------
452// wxHandlerInfo
453// ----------------------------------------------------------------------------
454
455void wxHandlerInfo::Insert(wxHandlerInfo* &iter)
456{
457 m_next = NULL;
458 if ( iter == NULL )
459 iter = this;
460 else
461 {
462 wxHandlerInfo* i = iter;
463 while( i->m_next )
464 i = i->m_next;
465
466 i->m_next = this;
467 }
468}
469
470void wxHandlerInfo::Remove()
499a9a62
SC
471{
472 if ( this == m_itsClass->m_firstHandler )
473 {
474 m_itsClass->m_firstHandler = m_next;
475 }
476 else
477 {
478 wxHandlerInfo *info = m_itsClass->m_firstHandler;
479 while (info)
480 {
481 if ( info->m_next == this )
482 {
483 info->m_next = m_next;
484 break;
485 }
486
487 info = info->m_next;
488 }
489 }
490}
491
13830d6f
SC
492
493// ----------------------------------------------------------------------------
494// wxClassInfo
495// ----------------------------------------------------------------------------
496
e765d7ee 497bool wxClassInfo::Create(wxObject *object, int ParamCount, wxAny *Params) const
13830d6f
SC
498{
499 if ( ParamCount != m_constructorPropertiesCount )
500 {
501 // FIXME: shouldn't we just return false and let the caller handle it?
502 wxLogError( _("Illegal Parameter Count for Create Method") );
503 return false;
504 }
505
506 return m_constructor->Create( object, Params );
507}
508
e765d7ee 509wxObject *wxClassInfo::ConstructObject(int ParamCount, wxAny *Params) const
13830d6f
SC
510{
511 if ( ParamCount != m_constructorPropertiesCount )
512 {
513 // FIXME: shouldn't we just return NULL and let the caller handle this case?
514 wxLogError( _("Illegal Parameter Count for ConstructObject Method") );
515 return NULL;
516 }
517
518 wxObject *object = NULL;
519 if (!m_constructor->Create( object, Params ))
520 return NULL;
521 return object;
522}
523
524bool wxClassInfo::IsKindOf(const wxClassInfo *info) const
525{
526 if ( info != 0 )
527 {
528 if ( info == this )
529 return true;
530
531 for ( int i = 0; m_parents[i]; ++ i )
532 {
533 if ( m_parents[i]->IsKindOf( info ) )
534 return true;
535 }
536 }
537 return false;
538}
539
9dc6871e 540const wxPropertyAccessor *wxClassInfo::FindAccessor(const wxChar *PropertyName) const
a095505c 541{
13830d6f 542 const wxPropertyInfo* info = FindPropertyInfo( PropertyName );
30fd71e6 543
2abce515 544 if ( info )
13830d6f 545 return info->GetAccessor();
a095505c 546
13830d6f 547 return NULL;
a095505c
SC
548}
549
9dc6871e 550wxPropertyInfo *wxClassInfo::FindPropertyInfoInThisClass (const wxChar *PropertyName) const
a095505c 551{
e765d7ee 552 wxPropertyInfo* info = GetFirstProperty();
a095505c 553
2abce515
SC
554 while( info )
555 {
13830d6f
SC
556 if ( wxStrcmp( info->GetName(), PropertyName ) == 0 )
557 return info;
558 info = info->GetNext();
2abce515 559 }
a095505c 560
2d51f067
SC
561 return 0;
562}
563
9dc6871e 564const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const wxChar *PropertyName) const
2d51f067 565{
13830d6f 566 const wxPropertyInfo* info = FindPropertyInfoInThisClass( PropertyName );
2d51f067 567 if ( info )
13830d6f 568 return info;
2d51f067 569
13830d6f
SC
570 const wxClassInfo** parents = GetParents();
571 for ( int i = 0; parents[i]; ++ i )
2abce515
SC
572 {
573 if ( ( info = parents[i]->FindPropertyInfo( PropertyName ) ) != NULL )
13830d6f 574 return info;
2abce515 575 }
a095505c
SC
576
577 return 0;
578}
579
9dc6871e 580wxHandlerInfo *wxClassInfo::FindHandlerInfoInThisClass (const wxChar *PropertyName) const
fbbdc52c 581{
e765d7ee 582 wxHandlerInfo* info = GetFirstHandler();
fbbdc52c 583
2abce515
SC
584 while( info )
585 {
13830d6f
SC
586 if ( wxStrcmp( info->GetName(), PropertyName ) == 0 )
587 return info;
588 info = info->GetNext();
2abce515 589 }
fbbdc52c 590
2d51f067
SC
591 return 0;
592}
593
9dc6871e 594const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const wxChar *PropertyName) const
2d51f067 595{
13830d6f 596 const wxHandlerInfo* info = FindHandlerInfoInThisClass( PropertyName );
2d51f067
SC
597
598 if ( info )
13830d6f 599 return info;
2d51f067 600
13830d6f
SC
601 const wxClassInfo** parents = GetParents();
602 for ( int i = 0; parents[i]; ++ i )
2abce515
SC
603 {
604 if ( ( info = parents[i]->FindHandlerInfo( PropertyName ) ) != NULL )
13830d6f 605 return info;
2abce515 606 }
fbbdc52c
SC
607
608 return 0;
609}
610
9c8046dd
SC
611wxObjectStreamingCallback wxClassInfo::GetStreamingCallback() const
612{
613 if ( m_streamingCallback )
13830d6f 614 return m_streamingCallback;
9c8046dd 615
13830d6f
SC
616 wxObjectStreamingCallback retval = NULL;
617 const wxClassInfo** parents = GetParents();
618 for ( int i = 0; parents[i] && retval == NULL; ++ i )
2abce515 619 {
13830d6f 620 retval = parents[i]->GetStreamingCallback();
2abce515 621 }
13830d6f 622 return retval;
9c8046dd
SC
623}
624
13830d6f 625bool wxClassInfo::BeforeWriteObject( const wxObject *obj, wxObjectWriter *streamer,
e765d7ee 626 wxObjectWriterCallback *writercallback, const wxStringToAnyHashMap &metadata) const
9c8046dd 627{
13830d6f 628 wxObjectStreamingCallback sb = GetStreamingCallback();
9c8046dd 629 if ( sb )
e765d7ee 630 return (*sb)(obj, streamer, writercallback, metadata );
9c8046dd 631
13830d6f 632 return true;
9c8046dd 633}
fbbdc52c 634
13830d6f 635void wxClassInfo::SetProperty(wxObject *object, const wxChar *propertyName,
e765d7ee 636 const wxAny &value) const
a095505c
SC
637{
638 const wxPropertyAccessor *accessor;
639
640 accessor = FindAccessor(propertyName);
641 wxASSERT(accessor->HasSetter());
13830d6f 642 accessor->SetProperty( object, value );
a095505c
SC
643}
644
e765d7ee 645wxAny wxClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const
a095505c
SC
646{
647 const wxPropertyAccessor *accessor;
648
649 accessor = FindAccessor(propertyName);
650 wxASSERT(accessor->HasGetter());
e765d7ee 651 wxAny result;
b8d5be01 652 accessor->GetProperty(object,result);
13830d6f 653 return result;
a095505c
SC
654}
655
e765d7ee 656wxAnyList wxClassInfo::GetPropertyCollection(wxObject *object,
13830d6f 657 const wxChar *propertyName) const
ab6e4913
SC
658{
659 const wxPropertyAccessor *accessor;
660
661 accessor = FindAccessor(propertyName);
662 wxASSERT(accessor->HasGetter());
e765d7ee 663 wxAnyList result;
b8d5be01 664 accessor->GetPropertyCollection(object,result);
13830d6f 665 return result;
ab6e4913
SC
666}
667
13830d6f 668void wxClassInfo::AddToPropertyCollection(wxObject *object, const wxChar *propertyName,
e765d7ee 669 const wxAny& value) const
ab6e4913
SC
670{
671 const wxPropertyAccessor *accessor;
672
673 accessor = FindAccessor(propertyName);
674 wxASSERT(accessor->HasAdder());
13830d6f 675 accessor->AddToPropertyCollection( object, value );
ab6e4913
SC
676}
677
cab1a605 678// void wxClassInfo::GetProperties( wxPropertyInfoMap &map ) const
af498247
VZ
679// The map parameter (the name map that is) seems something special
680// to MSVC and so we use a other name.
cab1a605 681void wxClassInfo::GetProperties( wxPropertyInfoMap &infomap ) const
cb73e600 682{
13830d6f 683 const wxPropertyInfo *pi = GetFirstProperty();
cab1a605 684 while( pi )
cb73e600 685 {
af498247 686 if ( infomap.find( pi->GetName() ) == infomap.end() )
13830d6f 687 infomap[pi->GetName()] = (wxPropertyInfo*) pi;
cb73e600 688
13830d6f 689 pi = pi->GetNext();
cb73e600
SC
690 }
691
13830d6f
SC
692 const wxClassInfo** parents = GetParents();
693 for ( int i = 0; parents[i]; ++ i )
cb73e600 694 {
13830d6f 695 parents[i]->GetProperties( infomap );
cb73e600
SC
696 }
697}
698
e765d7ee
SC
699wxObject* wxClassInfo::AnyToObjectPtr( const wxAny &data) const
700{
701 return m_variantOfPtrToObjectConverter(data);
702}
703
704void wxClassInfo::CallOnAny( const wxAny &data, wxObjectFunctor* functor ) const
705{
706 if ( data.GetTypeInfo()->GetKind() == wxT_OBJECT )
707 return m_variantToObjectConverter(data, functor);
708 else
709 return (*functor)(m_variantOfPtrToObjectConverter(data));
710}
711
712wxAny wxClassInfo::ObjectPtrToAny( wxObject* obj) const
713{
714 return m_objectToVariantConverter(obj);
715}
a095505c 716
bca6bd38
SC
717bool wxClassInfo::NeedsDirectConstruction() const
718{
719 return wx_dynamic_cast(wxObjectAllocator*, m_constructor) != NULL;
720}
721
2d51f067
SC
722// ----------------------------------------------------------------------------
723// wxDynamicObject support
724// ----------------------------------------------------------------------------
13830d6f 725
2d51f067
SC
726// Dynamic Objects are objects that have a real superclass instance and carry their
727// own attributes in a hash map. Like this it is possible to create the objects and
728// stream them, as if their class information was already available from compiled data
729
730struct wxDynamicObject::wxDynamicObjectInternal
731{
8f2b1cfd
SC
732 wxDynamicObjectInternal() {}
733
e765d7ee 734 wxStringToAnyHashMap m_properties;
13830d6f 735};
8f2b1cfd 736
13830d6f 737typedef list< wxDynamicObject* > wxDynamicObjectList;
8f2b1cfd
SC
738
739struct wxDynamicClassInfo::wxDynamicClassInfoInternal
740{
13830d6f
SC
741 wxDynamicObjectList m_dynamicObjects;
742};
2d51f067
SC
743
744// instantiates this object with an instance of its superclass
b8d5be01 745wxDynamicObject::wxDynamicObject(wxObject* superClassInstance, const wxDynamicClassInfo *info)
2d51f067 746{
13830d6f
SC
747 m_superClassInstance = superClassInstance;
748 m_classInfo = info;
749 m_data = new wxDynamicObjectInternal;
2d51f067
SC
750}
751
752wxDynamicObject::~wxDynamicObject()
753{
13830d6f
SC
754 wx_dynamic_cast(const wxDynamicClassInfo*, m_classInfo)->
755 m_data->m_dynamicObjects.remove( this );
756 delete m_data;
757 delete m_superClassInstance;
2d51f067
SC
758}
759
e765d7ee 760void wxDynamicObject::SetProperty (const wxChar *propertyName, const wxAny &value)
2d51f067 761{
13830d6f
SC
762 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
763 wxT("Accessing Unknown Property in a Dynamic Object") );
764 m_data->m_properties[propertyName] = value;
2d51f067
SC
765}
766
e765d7ee 767wxAny wxDynamicObject::GetProperty (const wxChar *propertyName) const
2d51f067 768{
13830d6f
SC
769 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
770 wxT("Accessing Unknown Property in a Dynamic Object") );
771 return m_data->m_properties[propertyName];
8f2b1cfd
SC
772}
773
cab1a605 774void wxDynamicObject::RemoveProperty( const wxChar *propertyName )
8f2b1cfd 775{
13830d6f
SC
776 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
777 wxT("Removing Unknown Property in a Dynamic Object") );
778 m_data->m_properties.erase( propertyName );
2d51f067
SC
779}
780
13830d6f
SC
781void wxDynamicObject::RenameProperty( const wxChar *oldPropertyName,
782 const wxChar *newPropertyName )
8f2b1cfd 783{
13830d6f
SC
784 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(oldPropertyName),
785 wxT("Renaming Unknown Property in a Dynamic Object") );
786
e765d7ee 787 wxAny value = m_data->m_properties[oldPropertyName];
13830d6f
SC
788 m_data->m_properties.erase( oldPropertyName );
789 m_data->m_properties[newPropertyName] = value;
8f2b1cfd
SC
790}
791
792
2d51f067 793// ----------------------------------------------------------------------------
13830d6f 794// wxDynamicClassInfo
2d51f067
SC
795// ----------------------------------------------------------------------------
796
13830d6f
SC
797wxDynamicClassInfo::wxDynamicClassInfo( const wxChar *unitName,
798 const wxChar *className,
799 const wxClassInfo* superClass ) :
800 wxClassInfo( unitName, className, new const wxClassInfo*[2])
2d51f067 801{
13830d6f
SC
802 GetParents()[0] = superClass;
803 GetParents()[1] = NULL;
804 m_data = new wxDynamicClassInfoInternal;
2d51f067
SC
805}
806
807wxDynamicClassInfo::~wxDynamicClassInfo()
808{
13830d6f
SC
809 delete[] GetParents();
810 delete m_data;
2d51f067
SC
811}
812
b8d5be01 813wxObject *wxDynamicClassInfo::AllocateObject() const
2d51f067 814{
13830d6f
SC
815 wxObject* parent = GetParents()[0]->AllocateObject();
816 wxDynamicObject *obj = new wxDynamicObject( parent, this );
817 m_data->m_dynamicObjects.push_back( obj );
818 return obj;
2d51f067
SC
819}
820
e765d7ee 821bool wxDynamicClassInfo::Create (wxObject *object, int paramCount, wxAny *params) const
2d51f067 822{
13830d6f
SC
823 wxDynamicObject *dynobj = wx_dynamic_cast( wxDynamicObject *, object );
824 wxASSERT_MSG( dynobj,
825 wxT("cannot call wxDynamicClassInfo::Create on ")
826 wxT("an object other than wxDynamicObject") );
827
828 return GetParents()[0]->Create( dynobj->GetSuperClassInstance(), paramCount, params );
2d51f067
SC
829}
830
831// get number of parameters for constructor
b8d5be01 832int wxDynamicClassInfo::GetCreateParamCount() const
2d51f067 833{
13830d6f 834 return GetParents()[0]->GetCreateParamCount();
2d51f067
SC
835}
836
837// get i-th constructor parameter
b8d5be01 838const wxChar* wxDynamicClassInfo::GetCreateParamName(int i) const
2d51f067 839{
13830d6f 840 return GetParents()[0]->GetCreateParamName( i );
2d51f067
SC
841}
842
e765d7ee 843void wxDynamicClassInfo::SetProperty(wxObject *object, const wxChar *propertyName, const wxAny &value) const
2d51f067 844{
13830d6f
SC
845 wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
846 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
2d51f067 847 if ( FindPropertyInfoInThisClass(propertyName) )
13830d6f 848 dynobj->SetProperty( propertyName, value );
2d51f067 849 else
13830d6f 850 GetParents()[0]->SetProperty( dynobj->GetSuperClassInstance(), propertyName, value );
2d51f067
SC
851}
852
e765d7ee 853wxAny wxDynamicClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const
2d51f067 854{
13830d6f
SC
855 wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
856 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
2d51f067 857 if ( FindPropertyInfoInThisClass(propertyName) )
13830d6f 858 return dynobj->GetProperty( propertyName );
2d51f067 859 else
13830d6f 860 return GetParents()[0]->GetProperty( dynobj->GetSuperClassInstance(), propertyName );
2d51f067
SC
861}
862
13830d6f 863void wxDynamicClassInfo::AddProperty( const wxChar *propertyName, const wxTypeInfo* typeInfo )
2d51f067 864{
e765d7ee
SC
865 EnsureInfosInited();
866 new wxPropertyInfo( m_firstProperty, this, propertyName, typeInfo->GetTypeName(), new wxGenericPropertyAccessor( propertyName ), wxAny() );
2d51f067
SC
867}
868
13830d6f 869void wxDynamicClassInfo::AddHandler( const wxChar *handlerName, wxObjectEventFunction address, const wxClassInfo* eventClassInfo )
2d51f067 870{
e765d7ee 871 EnsureInfosInited();
13830d6f 872 new wxHandlerInfo( m_firstHandler, this, handlerName, address, eventClassInfo );
2d51f067
SC
873}
874
2abce515 875// removes an existing runtime-property
cab1a605 876void wxDynamicClassInfo::RemoveProperty( const wxChar *propertyName )
2abce515 877{
13830d6f
SC
878 for ( wxDynamicObjectList::iterator iter = m_data->m_dynamicObjects.begin(); iter != m_data->m_dynamicObjects.end(); ++iter )
879 (*iter)->RemoveProperty( propertyName );
880 delete FindPropertyInfoInThisClass(propertyName);
2abce515
SC
881}
882
883// removes an existing runtime-handler
cab1a605 884void wxDynamicClassInfo::RemoveHandler( const wxChar *handlerName )
2abce515 885{
13830d6f 886 delete FindHandlerInfoInThisClass(handlerName);
499a9a62
SC
887}
888
889// renames an existing runtime-property
13830d6f 890void wxDynamicClassInfo::RenameProperty( const wxChar *oldPropertyName, const wxChar *newPropertyName )
499a9a62 891{
13830d6f
SC
892 wxPropertyInfo* pi = FindPropertyInfoInThisClass(oldPropertyName);
893 wxASSERT_MSG( pi,wxT("not existing property") );
894 pi->m_name = newPropertyName;
895 wx_dynamic_cast(wxGenericPropertyAccessor*, pi->GetAccessor())->RenameProperty( oldPropertyName, newPropertyName );
896 for ( wxDynamicObjectList::iterator iter = m_data->m_dynamicObjects.begin(); iter != m_data->m_dynamicObjects.end(); ++iter )
897 (*iter)->RenameProperty( oldPropertyName, newPropertyName );
499a9a62
SC
898}
899
900// renames an existing runtime-handler
13830d6f 901void wxDynamicClassInfo::RenameHandler( const wxChar *oldHandlerName, const wxChar *newHandlerName )
499a9a62 902{
13830d6f
SC
903 wxASSERT_MSG(FindHandlerInfoInThisClass(oldHandlerName),wxT("not existing handler") );
904 FindHandlerInfoInThisClass(oldHandlerName)->m_name = newHandlerName;
2abce515
SC
905}
906
2d51f067
SC
907// ----------------------------------------------------------------------------
908// wxGenericPropertyAccessor
909// ----------------------------------------------------------------------------
910
911struct wxGenericPropertyAccessor::wxGenericPropertyAccessorInternal
912{
13830d6f
SC
913 char filler;
914};
2d51f067 915
b8d5be01 916wxGenericPropertyAccessor::wxGenericPropertyAccessor( const wxString& propertyName )
13830d6f 917: wxPropertyAccessor( NULL, NULL, NULL, NULL )
2d51f067 918{
13830d6f
SC
919 m_data = new wxGenericPropertyAccessorInternal;
920 m_propertyName = propertyName;
921 m_getterName = wxT("Get")+propertyName;
922 m_setterName = wxT("Set")+propertyName;
2d51f067
SC
923}
924
925wxGenericPropertyAccessor::~wxGenericPropertyAccessor()
926{
13830d6f 927 delete m_data;
2d51f067 928}
13830d6f 929
e765d7ee 930void wxGenericPropertyAccessor::SetProperty(wxObject *object, const wxAny &value) const
2d51f067 931{
13830d6f
SC
932 wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
933 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
44a00712 934 dynobj->SetProperty(m_propertyName.c_str(), value );
2d51f067
SC
935}
936
e765d7ee 937void wxGenericPropertyAccessor::GetProperty(const wxObject *object, wxAny& value) const
2d51f067 938{
13830d6f
SC
939 const wxDynamicObject* dynobj = wx_dynamic_cast( const wxDynamicObject * , object );
940 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
44a00712 941 value = dynobj->GetProperty( m_propertyName.c_str() );
2d51f067 942}
8e3f3880 943
e765d7ee
SC
944// ----------------------------------------------------------------------------
945// wxGenericPropertyAccessor
946// ----------------------------------------------------------------------------
947
948wxString wxAnyGetAsString( const wxAny& data)
949{
950 if ( data.IsNull() || data.GetTypeInfo()==NULL )
951 return wxEmptyString;
952
953 wxString s;
954 data.GetTypeInfo()->ConvertToString(data,s);
955 return s;
956}
957
958const wxObject* wxAnyGetAsObjectPtr( const wxAny& data)
959{
960 if ( !data.IsNull() )
961 {
962 const wxClassTypeInfo* ti = wx_dynamic_cast(const wxClassTypeInfo*, data.GetTypeInfo());
963 if( ti )
964 return ti->GetClassInfo()->AnyToObjectPtr(data);
965 }
966 return NULL;
967}
968
969wxObjectFunctor::~wxObjectFunctor()
970{};
971
8e3f3880 972#endif // wxUSE_EXTENDED_RTTI