1///////////////////////////////////////////////////////////////////////////// 2// Name: src/common/xti.cpp 3// Purpose: runtime metadata information (extended class info 4// Author: Stefan Csomor 5// Modified by: 6// Created: 27/07/03 7// RCS-ID: $Id: xti.cpp 38857 2006-04-20 07:31:44Z ABX $ 8// Copyright: (c) 1997 Julian Smart 9// (c) 2003 Stefan Csomor 10// Licence: wxWindows licence 11///////////////////////////////////////////////////////////////////////////// 12 13// For compilers that support precompilation, includes "wx.h". 14#include "wx/wxprec.h" 15 16#ifdef __BORLANDC__ 17 #pragma hdrstop 18#endif 19 20#if wxUSE_EXTENDED_RTTI 21 22#ifndef WX_PRECOMP 23 #include "wx/object.h" 24 #include "wx/list.h" 25 #include "wx/hash.h" 26#endif 27 28#include "wx/xti.h" 29#include "wx/xml/xml.h" 30#include "wx/tokenzr.h" 31#include <string.h> 32 33#include "wx/beforestd.h" 34#include <map> 35#include <string> 36#include <list> 37#include "wx/afterstd.h" 38 39using namespace std ; 40 41// ---------------------------------------------------------------------------- 42// Enum Support 43// ---------------------------------------------------------------------------- 44 45wxEnumData::wxEnumData( wxEnumMemberData* data ) 46{ 47 m_members = data ; 48 for ( m_count = 0; m_members[m_count].m_name ; m_count++) 49 {} ; 50} 51 52bool wxEnumData::HasEnumMemberValue(const wxChar *name, int *value) const 53{ 54 int i; 55 for (i = 0; m_members[i].m_name ; i++ ) 56 { 57 if (!wxStrcmp(name, m_members[i].m_name)) 58 { 59 if ( value ) 60 *value = m_members[i].m_value; 61 return true ; 62 } 63 } 64 return false ; 65} 66 67int wxEnumData::GetEnumMemberValue(const wxChar *name) const 68{ 69 int i; 70 for (i = 0; m_members[i].m_name ; i++ ) 71 { 72 if (!wxStrcmp(name, m_members[i].m_name)) 73 { 74 return m_members[i].m_value; 75 } 76 } 77 return 0 ; 78} 79 80const wxChar *wxEnumData::GetEnumMemberName(int value) const 81{ 82 int i; 83 for (i = 0; m_members[i].m_name ; i++) 84 if (value == m_members[i].m_value) 85 return m_members[i].m_name; 86 87 return wxEmptyString ; 88} 89 90int wxEnumData::GetEnumMemberValueByIndex( int idx ) const 91{ 92 // we should cache the count in order to avoid out-of-bounds errors 93 return m_members[idx].m_value ; 94} 95 96const wxChar * wxEnumData::GetEnumMemberNameByIndex( int idx ) const 97{ 98 // we should cache the count in order to avoid out-of-bounds errors 99 return m_members[idx].m_name ; 100} 101 102// ---------------------------------------------------------------------------- 103// Type Information 104// ---------------------------------------------------------------------------- 105// ---------------------------------------------------------------------------- 106// value streaming 107// ---------------------------------------------------------------------------- 108 109// streamer specializations 110// for all built-in types 111 112// bool 113 114template<> void wxStringReadValue(const wxString &s , bool &data ) 115{ 116 int intdata ; 117 wxSscanf(s, _T("%d"), &intdata ) ; 118 data = (bool)intdata ; 119} 120 121template<> void wxStringWriteValue(wxString &s , const bool &data ) 122{ 123 s = wxString::Format(_T("%d"), data ) ; 124} 125 126// char 127 128template<> void wxStringReadValue(const wxString &s , char &data ) 129{ 130 int intdata ; 131 wxSscanf(s, _T("%d"), &intdata ) ; 132 data = char(intdata) ; 133} 134 135template<> void wxStringWriteValue(wxString &s , const char &data ) 136{ 137 s = wxString::Format(_T("%d"), data ) ; 138} 139 140// unsigned char 141 142template<> void wxStringReadValue(const wxString &s , unsigned char &data ) 143{ 144 int intdata ; 145 wxSscanf(s, _T("%d"), &intdata ) ; 146 data = (unsigned char)(intdata) ; 147} 148 149template<> void wxStringWriteValue(wxString &s , const unsigned char &data ) 150{ 151 s = wxString::Format(_T("%d"), data ) ; 152} 153 154// int 155 156template<> void wxStringReadValue(const wxString &s , int &data ) 157{ 158 wxSscanf(s, _T("%d"), &data ) ; 159} 160 161template<> void wxStringWriteValue(wxString &s , const int &data ) 162{ 163 s = wxString::Format(_T("%d"), data ) ; 164} 165 166// unsigned int 167 168template<> void wxStringReadValue(const wxString &s , unsigned int &data ) 169{ 170 wxSscanf(s, _T("%d"), &data ) ; 171} 172 173template<> void wxStringWriteValue(wxString &s , const unsigned int &data ) 174{ 175 s = wxString::Format(_T("%d"), data ) ; 176} 177 178// long 179 180template<> void wxStringReadValue(const wxString &s , long &data ) 181{ 182 wxSscanf(s, _T("%ld"), &data ) ; 183} 184 185template<> void wxStringWriteValue(wxString &s , const long &data ) 186{ 187 s = wxString::Format(_T("%ld"), data ) ; 188} 189 190// unsigned long 191 192template<> void wxStringReadValue(const wxString &s , unsigned long &data ) 193{ 194 wxSscanf(s, _T("%ld"), &data ) ; 195} 196 197template<> void wxStringWriteValue(wxString &s , const unsigned long &data ) 198{ 199 s = wxString::Format(_T("%ld"), data ) ; 200} 201 202// float 203 204template<> void wxStringReadValue(const wxString &s , float &data ) 205{ 206 wxSscanf(s, _T("%f"), &data ) ; 207} 208 209template<> void wxStringWriteValue(wxString &s , const float &data ) 210{ 211 s = wxString::Format(_T("%f"), data ) ; 212} 213 214// double 215 216template<> void wxStringReadValue(const wxString &s , double &data ) 217{ 218 wxSscanf(s, _T("%lf"), &data ) ; 219} 220 221template<> void wxStringWriteValue(wxString &s , const double &data ) 222{ 223 s = wxString::Format(_T("%lf"), data ) ; 224} 225 226// wxString 227 228template<> void wxStringReadValue(const wxString &s , wxString &data ) 229{ 230 data = s ; 231} 232 233template<> void wxStringWriteValue(wxString &s , const wxString &data ) 234{ 235 s = data ; 236} 237 238// built-ins 239// 240 241#if wxUSE_FUNC_TEMPLATE_POINTER 242#define wxBUILTIN_TYPE_INFO( element , type ) \ 243 wxBuiltInTypeInfo s_typeInfo##type(element , &wxToStringConverter<type> , &wxFromStringConverter<type> , typeid(type).name()) ; 244#else 245#define wxBUILTIN_TYPE_INFO( element , type ) \ 246 void _toString##element( const wxxVariant& data , wxString &result ) { wxToStringConverter<type>(data, result); } \ 247 void _fromString##element( const wxString& data , wxxVariant &result ) { wxFromStringConverter<type>(data, result); } \ 248 wxBuiltInTypeInfo s_typeInfo##type(element , &_toString##element , &_fromString##element , typeid(type).name()) ; 249#endif 250 251typedef unsigned char unsigned_char; 252typedef unsigned int unsigned_int; 253typedef unsigned long unsigned_long; 254 255wxBuiltInTypeInfo s_typeInfovoid( wxT_VOID , NULL , NULL , typeid(void).name()); 256wxBUILTIN_TYPE_INFO( wxT_BOOL , bool); 257wxBUILTIN_TYPE_INFO( wxT_CHAR , char); 258wxBUILTIN_TYPE_INFO( wxT_UCHAR , unsigned_char); 259wxBUILTIN_TYPE_INFO( wxT_INT , int); 260wxBUILTIN_TYPE_INFO( wxT_UINT , unsigned_int); 261wxBUILTIN_TYPE_INFO( wxT_LONG , long); 262wxBUILTIN_TYPE_INFO( wxT_ULONG , unsigned_long); 263wxBUILTIN_TYPE_INFO( wxT_FLOAT , float); 264wxBUILTIN_TYPE_INFO( wxT_DOUBLE , double); 265wxBUILTIN_TYPE_INFO( wxT_STRING , wxString); 266 267 268// this are compiler induced specialization which are never used anywhere 269 270wxILLEGAL_TYPE_SPECIALIZATION( char const * ) 271wxILLEGAL_TYPE_SPECIALIZATION( char * ) 272wxILLEGAL_TYPE_SPECIALIZATION( unsigned char * ) 273wxILLEGAL_TYPE_SPECIALIZATION( int * ) 274wxILLEGAL_TYPE_SPECIALIZATION( bool * ) 275wxILLEGAL_TYPE_SPECIALIZATION( long * ) 276wxILLEGAL_TYPE_SPECIALIZATION( wxString * ) 277 278wxCOLLECTION_TYPE_INFO( wxString , wxArrayString ) ; 279 280template<> void wxCollectionToVariantArray( wxArrayString const &theArray, wxxVariantArray &value) 281{ 282 wxArrayCollectionToVariantArray( theArray , value ) ; 283} 284 285wxTypeInfoMap *wxTypeInfo::ms_typeTable = NULL ; 286 287wxTypeInfo *wxTypeInfo::FindType(const wxChar *typeName) 288{ 289 wxTypeInfoMap::iterator iter = ms_typeTable->find(typeName) ; 290 wxASSERT_MSG( iter != ms_typeTable->end() , wxT("lookup for a non-existent type-info") ) ; 291 return (wxTypeInfo *)iter->second; 292} 293 294#if wxUSE_UNICODE 295wxClassTypeInfo::wxClassTypeInfo( wxTypeKind kind , wxClassInfo* classInfo , converterToString_t to , converterFromString_t from , const char *name) : 296wxTypeInfo( kind , to , from , name) 297{ wxASSERT_MSG( kind == wxT_OBJECT_PTR || kind == wxT_OBJECT , wxT("Illegal Kind for Enum Type")) ; m_classInfo = classInfo ;} 298#endif 299 300wxClassTypeInfo::wxClassTypeInfo( wxTypeKind kind , wxClassInfo* classInfo , converterToString_t to , converterFromString_t from , const wxString &name) : 301wxTypeInfo( kind , to , from , name) 302{ wxASSERT_MSG( kind == wxT_OBJECT_PTR || kind == wxT_OBJECT , wxT("Illegal Kind for Enum Type")) ; m_classInfo = classInfo ;} 303 304wxDelegateTypeInfo::wxDelegateTypeInfo( int eventType , wxClassInfo* eventClass , converterToString_t to , converterFromString_t from ) : 305wxTypeInfo ( wxT_DELEGATE , to , from , wxEmptyString ) 306{ m_eventClass = eventClass ; m_eventType = eventType ; m_lastEventType = -1 ;} 307 308wxDelegateTypeInfo::wxDelegateTypeInfo( int eventType , int lastEventType , wxClassInfo* eventClass , converterToString_t to , converterFromString_t from ) : 309wxTypeInfo ( wxT_DELEGATE , to , from , wxEmptyString ) 310{ m_eventClass = eventClass ; m_eventType = eventType ; m_lastEventType = lastEventType; } 311 312void wxTypeInfo::Register() 313{ 314 if ( ms_typeTable == NULL ) 315 ms_typeTable = new wxTypeInfoMap() ; 316 317 if( !m_name.empty() ) 318 (*ms_typeTable)[m_name] = this ; 319} 320 321void wxTypeInfo::Unregister() 322{ 323 if( !m_name.empty() ) 324 ms_typeTable->erase(m_name); 325} 326 327// removing header dependancy on string tokenizer 328 329void wxSetStringToArray( const wxString &s , wxArrayString &array ) 330{ 331 wxStringTokenizer tokenizer(s, wxT("| \t\n"), wxTOKEN_STRTOK); 332 wxString flag; 333 array.Clear() ; 334 while (tokenizer.HasMoreTokens()) 335 { 336 array.Add(tokenizer.GetNextToken()) ; 337 } 338} 339 340// ---------------------------------------------------------------------------- 341// wxClassInfo 342// ---------------------------------------------------------------------------- 343 344wxPropertyInfo::~wxPropertyInfo() 345{ 346 if ( this == m_itsClass->m_firstProperty ) 347 { 348 m_itsClass->m_firstProperty = m_next; 349 } 350 else 351 { 352 wxPropertyInfo *info = m_itsClass->m_firstProperty; 353 while (info) 354 { 355 if ( info->m_next == this ) 356 { 357 info->m_next = m_next; 358 break; 359 } 360 361 info = info->m_next; 362 } 363 } 364} 365 366wxHandlerInfo::~wxHandlerInfo() 367{ 368 if ( this == m_itsClass->m_firstHandler ) 369 { 370 m_itsClass->m_firstHandler = m_next; 371 } 372 else 373 { 374 wxHandlerInfo *info = m_itsClass->m_firstHandler; 375 while (info) 376 { 377 if ( info->m_next == this ) 378 { 379 info->m_next = m_next; 380 break; 381 } 382 383 info = info->m_next; 384 } 385 } 386} 387 388const wxPropertyAccessor *wxClassInfo::FindAccessor(const wxChar *PropertyName) const 389{ 390 const wxPropertyInfo* info = FindPropertyInfo( PropertyName ) ; 391 392 if ( info ) 393 return info->GetAccessor() ; 394 395 return NULL ; 396} 397 398wxPropertyInfo *wxClassInfo::FindPropertyInfoInThisClass (const wxChar *PropertyName) const 399{ 400 wxPropertyInfo* info = m_firstProperty ; 401 402 while( info ) 403 { 404 if ( wxStrcmp( info->GetName() , PropertyName ) == 0 ) 405 return info ; 406 info = info->GetNext() ; 407 } 408 409 return 0; 410} 411 412const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const wxChar *PropertyName) const 413{ 414 const wxPropertyInfo* info = FindPropertyInfoInThisClass( PropertyName ) ; 415 if ( info ) 416 return info ; 417 418 const wxClassInfo** parents = GetParents() ; 419 for ( int i = 0 ; parents[i] ; ++ i ) 420 { 421 if ( ( info = parents[i]->FindPropertyInfo( PropertyName ) ) != NULL ) 422 return info ; 423 } 424 425 return 0; 426} 427 428wxHandlerInfo *wxClassInfo::FindHandlerInfoInThisClass (const wxChar *PropertyName) const 429{ 430 wxHandlerInfo* info = m_firstHandler ; 431 432 while( info ) 433 { 434 if ( wxStrcmp( info->GetName() , PropertyName ) == 0 ) 435 return info ; 436 info = info->GetNext() ; 437 } 438 439 return 0; 440} 441 442const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const wxChar *PropertyName) const 443{ 444 const wxHandlerInfo* info = FindHandlerInfoInThisClass( PropertyName ) ; 445 446 if ( info ) 447 return info ; 448 449 const wxClassInfo** parents = GetParents() ; 450 for ( int i = 0 ; parents[i] ; ++ i ) 451 { 452 if ( ( info = parents[i]->FindHandlerInfo( PropertyName ) ) != NULL ) 453 return info ; 454 } 455 456 return 0; 457} 458 459wxObjectStreamingCallback wxClassInfo::GetStreamingCallback() const 460{ 461 if ( m_streamingCallback ) 462 return m_streamingCallback ; 463 464 wxObjectStreamingCallback retval = NULL ; 465 const wxClassInfo** parents = GetParents() ; 466 for ( int i = 0 ; parents[i] && retval == NULL ; ++ i ) 467 { 468 retval = parents[i]->GetStreamingCallback() ; 469 } 470 return retval ; 471} 472 473bool wxClassInfo::BeforeWriteObject( const wxObject *obj, wxWriter *streamer , wxPersister *persister , wxxVariantArray &metadata) const 474{ 475 wxObjectStreamingCallback sb = GetStreamingCallback() ; 476 if ( sb ) 477 return (*sb)(obj , streamer , persister , metadata ) ; 478 479 return true ; 480} 481 482void wxClassInfo::SetProperty(wxObject *object, const wxChar *propertyName, const wxxVariant &value) const 483{ 484 const wxPropertyAccessor *accessor; 485 486 accessor = FindAccessor(propertyName); 487 wxASSERT(accessor->HasSetter()); 488 accessor->SetProperty( object , value ) ; 489} 490 491wxxVariant wxClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const 492{ 493 const wxPropertyAccessor *accessor; 494 495 accessor = FindAccessor(propertyName); 496 wxASSERT(accessor->HasGetter()); 497 wxxVariant result ; 498 accessor->GetProperty(object,result); 499 return result ; 500} 501 502wxxVariantArray wxClassInfo::GetPropertyCollection(wxObject *object, const wxChar *propertyName) const 503{ 504 const wxPropertyAccessor *accessor; 505 506 accessor = FindAccessor(propertyName); 507 wxASSERT(accessor->HasGetter()); 508 wxxVariantArray result ; 509 accessor->GetPropertyCollection(object,result); 510 return result ; 511} 512 513void wxClassInfo::AddToPropertyCollection(wxObject *object, const wxChar *propertyName , const wxxVariant& value) const 514{ 515 const wxPropertyAccessor *accessor; 516 517 accessor = FindAccessor(propertyName); 518 wxASSERT(accessor->HasAdder()); 519 accessor->AddToPropertyCollection( object , value ) ; 520} 521 522// void wxClassInfo::GetProperties( wxPropertyInfoMap &map ) const 523// The map parameter (the name map that is) seems something special 524// to MSVC and so we use a other name. 525void wxClassInfo::GetProperties( wxPropertyInfoMap &infomap ) const 526{ 527 const wxPropertyInfo *pi = GetFirstProperty() ; 528 while( pi ) 529 { 530 if ( infomap.find( pi->GetName() ) == infomap.end() ) 531 infomap[pi->GetName()] = (wxPropertyInfo*) pi ; 532 533 pi = pi->GetNext() ; 534 } 535 536 const wxClassInfo** parents = GetParents() ; 537 for ( int i = 0 ; parents[i] ; ++ i ) 538 { 539 parents[i]->GetProperties( infomap ) ; 540 } 541} 542 543/* 544VARIANT TO OBJECT 545*/ 546 547wxObject* wxxVariant::GetAsObject() 548{ 549 const wxClassTypeInfo *ti = dynamic_cast<const wxClassTypeInfo*>( m_data->GetTypeInfo() ) ; 550 if ( ti ) 551 return ti->GetClassInfo()->VariantToInstance(*this) ; 552 else 553 return NULL ; 554} 555 556// ---------------------------------------------------------------------------- 557// wxDynamicObject support 558// ---------------------------------------------------------------------------- 559// 560// Dynamic Objects are objects that have a real superclass instance and carry their 561// own attributes in a hash map. Like this it is possible to create the objects and 562// stream them, as if their class information was already available from compiled data 563 564struct wxDynamicObject::wxDynamicObjectInternal 565{ 566 wxDynamicObjectInternal() {} 567 568#if wxUSE_UNICODE 569 map<wstring,wxxVariant> m_properties ; 570#else 571 map<string,wxxVariant> m_properties ; 572#endif 573} ; 574 575typedef list< wxDynamicObject* > wxDynamicObjectList ; 576 577struct wxDynamicClassInfo::wxDynamicClassInfoInternal 578{ 579 wxDynamicObjectList m_dynamicObjects ; 580} ; 581 582// instantiates this object with an instance of its superclass 583wxDynamicObject::wxDynamicObject(wxObject* superClassInstance, const wxDynamicClassInfo *info) 584{ 585 m_superClassInstance = superClassInstance ; 586 m_classInfo = info ; 587 m_data = new wxDynamicObjectInternal ; 588} 589 590wxDynamicObject::~wxDynamicObject() 591{ 592 dynamic_cast<const wxDynamicClassInfo*>(m_classInfo)->m_data->m_dynamicObjects.remove( this ) ; 593 delete m_data ; 594 delete m_superClassInstance ; 595} 596 597void wxDynamicObject::SetProperty (const wxChar *propertyName, const wxxVariant &value) 598{ 599 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),wxT("Accessing Unknown Property in a Dynamic Object") ) ; 600 m_data->m_properties[propertyName] = value ; 601} 602 603wxxVariant wxDynamicObject::GetProperty (const wxChar *propertyName) const 604{ 605 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),wxT("Accessing Unknown Property in a Dynamic Object") ) ; 606 return m_data->m_properties[propertyName] ; 607} 608 609void wxDynamicObject::RemoveProperty( const wxChar *propertyName ) 610{ 611 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),wxT("Removing Unknown Property in a Dynamic Object") ) ; 612 m_data->m_properties.erase( propertyName ) ; 613} 614 615void wxDynamicObject::RenameProperty( const wxChar *oldPropertyName , const wxChar *newPropertyName ) 616{ 617 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(oldPropertyName),wxT("Renaming Unknown Property in a Dynamic Object") ) ; 618 wxxVariant value = m_data->m_properties[oldPropertyName] ; 619 m_data->m_properties.erase( oldPropertyName ) ; 620 m_data->m_properties[newPropertyName] = value ; 621} 622 623 624// ---------------------------------------------------------------------------- 625// wxDynamiClassInfo 626// ---------------------------------------------------------------------------- 627 628wxDynamicClassInfo::wxDynamicClassInfo( const wxChar *unitName, const wxChar *className , const wxClassInfo* superClass ) : 629wxClassInfo( unitName, className , new const wxClassInfo*[2]) 630{ 631 GetParents()[0] = superClass ; 632 GetParents()[1] = NULL ; 633 m_data = new wxDynamicClassInfoInternal ; 634} 635 636wxDynamicClassInfo::~wxDynamicClassInfo() 637{ 638 delete[] GetParents() ; 639 delete m_data ; 640} 641 642wxObject *wxDynamicClassInfo::AllocateObject() const 643{ 644 wxObject* parent = GetParents()[0]->AllocateObject() ; 645 wxDynamicObject *obj = new wxDynamicObject( parent , this ) ; 646 m_data->m_dynamicObjects.push_back( obj ) ; 647 return obj ; 648} 649 650void wxDynamicClassInfo::Create (wxObject *object, int paramCount, wxxVariant *params) const 651{ 652 wxDynamicObject *dynobj = dynamic_cast< wxDynamicObject *>( object ) ; 653 wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::Create on an object other than wxDynamicObject") ) ; 654 GetParents()[0]->Create( dynobj->GetSuperClassInstance() , paramCount , params ) ; 655} 656 657// get number of parameters for constructor 658int wxDynamicClassInfo::GetCreateParamCount() const 659{ 660 return GetParents()[0]->GetCreateParamCount() ; 661} 662 663// get i-th constructor parameter 664const wxChar* wxDynamicClassInfo::GetCreateParamName(int i) const 665{ 666 return GetParents()[0]->GetCreateParamName( i ) ; 667} 668 669void wxDynamicClassInfo::SetProperty(wxObject *object, const wxChar *propertyName, const wxxVariant &value) const 670{ 671 wxDynamicObject* dynobj = dynamic_cast< wxDynamicObject * >( object ) ; 672 wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ; 673 if ( FindPropertyInfoInThisClass(propertyName) ) 674 dynobj->SetProperty( propertyName , value ) ; 675 else 676 GetParents()[0]->SetProperty( dynobj->GetSuperClassInstance() , propertyName , value ) ; 677} 678 679wxxVariant wxDynamicClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const 680{ 681 wxDynamicObject* dynobj = dynamic_cast< wxDynamicObject * >( object ) ; 682 wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ; 683 if ( FindPropertyInfoInThisClass(propertyName) ) 684 return dynobj->GetProperty( propertyName ) ; 685 else 686 return GetParents()[0]->GetProperty( dynobj->GetSuperClassInstance() , propertyName ) ; 687} 688 689void wxDynamicClassInfo::AddProperty( const wxChar *propertyName , const wxTypeInfo* typeInfo ) 690{ 691 new wxPropertyInfo( m_firstProperty , this , propertyName , typeInfo->GetTypeName() , new wxGenericPropertyAccessor( propertyName ) , wxxVariant() ) ; 692} 693 694void wxDynamicClassInfo::AddHandler( const wxChar *handlerName , wxObjectEventFunction address , const wxClassInfo* eventClassInfo ) 695{ 696 new wxHandlerInfo( m_firstHandler , this , handlerName , address , eventClassInfo ) ; 697} 698 699// removes an existing runtime-property 700void wxDynamicClassInfo::RemoveProperty( const wxChar *propertyName ) 701{ 702 for ( wxDynamicObjectList::iterator iter = m_data->m_dynamicObjects.begin() ; iter != m_data->m_dynamicObjects.end() ; ++iter ) 703 (*iter)->RemoveProperty( propertyName ) ; 704 delete FindPropertyInfoInThisClass(propertyName) ; 705} 706 707// removes an existing runtime-handler 708void wxDynamicClassInfo::RemoveHandler( const wxChar *handlerName ) 709{ 710 delete FindHandlerInfoInThisClass(handlerName) ; 711} 712 713// renames an existing runtime-property 714void wxDynamicClassInfo::RenameProperty( const wxChar *oldPropertyName , const wxChar *newPropertyName ) 715{ 716 wxPropertyInfo* pi = FindPropertyInfoInThisClass(oldPropertyName) ; 717 wxASSERT_MSG( pi ,wxT("not existing property") ) ; 718 pi->m_name = newPropertyName ; 719 dynamic_cast<wxGenericPropertyAccessor*>(pi->GetAccessor())->RenameProperty( oldPropertyName , newPropertyName ) ; 720 for ( wxDynamicObjectList::iterator iter = m_data->m_dynamicObjects.begin() ; iter != m_data->m_dynamicObjects.end() ; ++iter ) 721 (*iter)->RenameProperty( oldPropertyName , newPropertyName ) ; 722} 723 724// renames an existing runtime-handler 725void wxDynamicClassInfo::RenameHandler( const wxChar *oldHandlerName , const wxChar *newHandlerName ) 726{ 727 wxASSERT_MSG(FindHandlerInfoInThisClass(oldHandlerName),wxT("not existing handler") ) ; 728 FindHandlerInfoInThisClass(oldHandlerName)->m_name = newHandlerName ; 729} 730 731// ---------------------------------------------------------------------------- 732// wxGenericPropertyAccessor 733// ---------------------------------------------------------------------------- 734 735struct wxGenericPropertyAccessor::wxGenericPropertyAccessorInternal 736{ 737 char filler ; 738} ; 739 740wxGenericPropertyAccessor::wxGenericPropertyAccessor( const wxString& propertyName ) 741: wxPropertyAccessor( NULL , NULL , NULL , NULL ) 742{ 743 m_data = new wxGenericPropertyAccessorInternal ; 744 m_propertyName = propertyName ; 745 m_getterName = wxT("Get")+propertyName ; 746 m_setterName = wxT("Set")+propertyName ; 747} 748 749wxGenericPropertyAccessor::~wxGenericPropertyAccessor() 750{ 751 delete m_data ; 752} 753void wxGenericPropertyAccessor::SetProperty(wxObject *object, const wxxVariant &value) const 754{ 755 wxDynamicObject* dynobj = dynamic_cast< wxDynamicObject * >( object ) ; 756 wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ; 757 dynobj->SetProperty(m_propertyName , value ) ; 758} 759 760void wxGenericPropertyAccessor::GetProperty(const wxObject *object, wxxVariant& value) const 761{ 762 const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject * >( object ) ; 763 wxASSERT_MSG( dynobj , wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") ) ; 764 value = dynobj->GetProperty( m_propertyName ) ; 765} 766 767#endif // wxUSE_EXTENDED_RTTI 768