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