]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/xti.cpp
Disable handling of wxEVT_MOUSEWHEEL in wxVarScrollHelperEvtHandler in wxGTK.
[wxWidgets.git] / src / common / xti.cpp
... / ...
CommitLineData
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// Copyright: (c) 1997 Julian Smart
8// (c) 2003 Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#if wxUSE_EXTENDED_RTTI
20
21#ifndef WX_PRECOMP
22 #include "wx/object.h"
23 #include "wx/list.h"
24 #include "wx/hash.h"
25#endif
26
27#include "wx/xti.h"
28#include "wx/xml/xml.h"
29#include "wx/tokenzr.h"
30#include "wx/range.h"
31
32#include <string.h>
33
34#include "wx/beforestd.h"
35#include <map>
36#include <string>
37#include <list>
38#include "wx/afterstd.h"
39
40using namespace std;
41
42// ----------------------------------------------------------------------------
43// wxEnumData
44// ----------------------------------------------------------------------------
45
46wxEnumData::wxEnumData( wxEnumMemberData* data )
47{
48 m_members = data;
49 for ( m_count = 0; m_members[m_count].m_name; m_count++)
50 {};
51}
52
53bool wxEnumData::HasEnumMemberValue(const wxChar *name, int *value) const
54{
55 int i;
56 for (i = 0; m_members[i].m_name; i++ )
57 {
58 if (!wxStrcmp(name, m_members[i].m_name))
59 {
60 if ( value )
61 *value = m_members[i].m_value;
62 return true;
63 }
64 }
65 return false;
66}
67
68int wxEnumData::GetEnumMemberValue(const wxChar *name) const
69{
70 int i;
71 for (i = 0; m_members[i].m_name; i++ )
72 {
73 if (!wxStrcmp(name, m_members[i].m_name))
74 {
75 return m_members[i].m_value;
76 }
77 }
78 return 0;
79}
80
81const wxChar *wxEnumData::GetEnumMemberName(int value) const
82{
83 int i;
84 for (i = 0; m_members[i].m_name; i++)
85 if (value == m_members[i].m_value)
86 return m_members[i].m_name;
87
88 return wxEmptyString;
89}
90
91int wxEnumData::GetEnumMemberValueByIndex( int idx ) const
92{
93 // we should cache the count in order to avoid out-of-bounds errors
94 return m_members[idx].m_value;
95}
96
97const wxChar * wxEnumData::GetEnumMemberNameByIndex( int idx ) const
98{
99 // we should cache the count in order to avoid out-of-bounds errors
100 return m_members[idx].m_name;
101}
102
103// ----------------------------------------------------------------------------
104// Type Information
105// ----------------------------------------------------------------------------
106
107// ----------------------------------------------------------------------------
108// value streaming
109// ----------------------------------------------------------------------------
110
111// streamer specializations
112// for all built-in types
113
114// bool
115
116template<> void wxStringReadValue(const wxString &s, bool &data )
117{
118 int intdata;
119 wxSscanf(s, wxT("%d"), &intdata );
120 data = (bool)(intdata != 0);
121}
122
123template<> void wxStringWriteValue(wxString &s, const bool &data )
124{
125 s = wxString::Format(wxT("%d"), data );
126}
127
128// char
129
130template<> void wxStringReadValue(const wxString &s, char &data )
131{
132 int intdata;
133 wxSscanf(s, wxT("%d"), &intdata );
134 data = char(intdata);
135}
136
137template<> void wxStringWriteValue(wxString &s, const char &data )
138{
139 s = wxString::Format(wxT("%d"), data );
140}
141
142// unsigned char
143
144template<> void wxStringReadValue(const wxString &s, unsigned char &data )
145{
146 int intdata;
147 wxSscanf(s, wxT("%d"), &intdata );
148 data = (unsigned char)(intdata);
149}
150
151template<> void wxStringWriteValue(wxString &s, const unsigned char &data )
152{
153 s = wxString::Format(wxT("%d"), data );
154}
155
156// int
157
158template<> void wxStringReadValue(const wxString &s, int &data )
159{
160 wxSscanf(s, wxT("%d"), &data );
161}
162
163template<> void wxStringWriteValue(wxString &s, const int &data )
164{
165 s = wxString::Format(wxT("%d"), data );
166}
167
168// unsigned int
169
170template<> void wxStringReadValue(const wxString &s, unsigned int &data )
171{
172 wxSscanf(s, wxT("%d"), &data );
173}
174
175template<> void wxStringWriteValue(wxString &s, const unsigned int &data )
176{
177 s = wxString::Format(wxT("%d"), data );
178}
179
180// long
181
182template<> void wxStringReadValue(const wxString &s, long &data )
183{
184 wxSscanf(s, wxT("%ld"), &data );
185}
186
187template<> void wxStringWriteValue(wxString &s, const long &data )
188{
189 s = wxString::Format(wxT("%ld"), data );
190}
191
192// unsigned long
193
194template<> void wxStringReadValue(const wxString &s, unsigned long &data )
195{
196 wxSscanf(s, wxT("%ld"), &data );
197}
198
199template<> void wxStringWriteValue(wxString &s, const unsigned long &data )
200{
201 s = wxString::Format(wxT("%ld"), data );
202}
203
204#ifdef wxLongLong_t
205template<> void wxStringReadValue(const wxString &s, wxLongLong_t &data )
206{
207 wxSscanf(s, wxT("%lld"), &data );
208}
209
210template<> void wxStringWriteValue(wxString &s, const wxLongLong_t &data )
211{
212 s = wxString::Format(wxT("%lld"), data );
213}
214
215template<> void wxStringReadValue(const wxString &s, wxULongLong_t &data )
216{
217 wxSscanf(s, wxT("%lld"), &data );
218}
219
220template<> void wxStringWriteValue(wxString &s, const wxULongLong_t &data )
221{
222 s = wxString::Format(wxT("%lld"), data );
223}
224#endif
225// float
226
227template<> void wxStringReadValue(const wxString &s, float &data )
228{
229 wxSscanf(s, wxT("%f"), &data );
230}
231
232template<> void wxStringWriteValue(wxString &s, const float &data )
233{
234 s = wxString::Format(wxT("%f"), data );
235}
236
237// double
238
239template<> void wxStringReadValue(const wxString &s, double &data )
240{
241 wxSscanf(s, wxT("%lf"), &data );
242}
243
244template<> void wxStringWriteValue(wxString &s, const double &data )
245{
246 s = wxString::Format(wxT("%lf"), data );
247}
248
249// wxString
250
251template<> void wxStringReadValue(const wxString &s, wxString &data )
252{
253 data = s;
254}
255
256template<> void wxStringWriteValue(wxString &s, const wxString &data )
257{
258 s = data;
259}
260
261
262// built-ins
263//
264
265#if wxUSE_FUNC_TEMPLATE_POINTER
266 #define wxBUILTIN_TYPE_INFO( element, type ) \
267 wxBuiltInTypeInfo \
268 s_typeInfo##type(element, &wxToStringConverter<type>, \
269 &wxFromStringConverter<type>, typeid(type).name());
270#else
271 #define wxBUILTIN_TYPE_INFO( element, type ) \
272 void _toString##element( const wxAny& data, wxString &result ) \
273 { wxToStringConverter<type, data, result); } \
274 void _fromString##element( const wxString& data, wxAny &result ) \
275 { wxFromStringConverter<type, data, result); } \
276 wxBuiltInTypeInfo s_typeInfo##type(element, &_toString##element, \
277 &_fromString##element, typeid(type).name());
278#endif
279
280typedef unsigned char unsigned_char;
281typedef unsigned int unsigned_int;
282typedef unsigned long unsigned_long;
283
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);
295
296#ifdef wxLongLong_t
297wxBUILTIN_TYPE_INFO(wxT_LONGLONG, wxLongLong_t)
298wxBUILTIN_TYPE_INFO(wxT_ULONGLONG, wxULongLong_t)
299#endif
300
301// this are compiler induced specialization which are never used anywhere
302
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 * )
310
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
329wxCOLLECTION_TYPE_INFO( wxString, wxArrayString );
330
331template<> void wxCollectionToVariantArray( wxArrayString const &theArray,
332 wxAnyList &value)
333{
334 wxArrayCollectionToVariantArray( theArray, value );
335}
336
337wxTypeInfoMap *wxTypeInfo::ms_typeTable = NULL;
338
339wxTypeInfo *wxTypeInfo::FindType(const wxString& typeName)
340{
341 wxTypeInfoMap::iterator iter = ms_typeTable->find(typeName);
342
343 if (iter == ms_typeTable->end())
344 return NULL;
345
346 return (wxTypeInfo *)iter->second;
347}
348
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}
379
380void wxTypeInfo::Register()
381{
382 if ( ms_typeTable == NULL )
383 ms_typeTable = new wxTypeInfoMap();
384
385 if( !m_name.empty() )
386 (*ms_typeTable)[m_name] = this;
387}
388
389void wxTypeInfo::Unregister()
390{
391 if( !m_name.empty() )
392 ms_typeTable->erase(m_name);
393}
394
395// removing header dependency on string tokenizer
396
397void wxSetStringToArray( const wxString &s, wxArrayString &array )
398{
399 wxStringTokenizer tokenizer(s, wxT("| \t\n"), wxTOKEN_STRTOK);
400 wxString flag;
401 array.Clear();
402 while (tokenizer.HasMoreTokens())
403 {
404 array.Add(tokenizer.GetNextToken());
405 }
406}
407
408// ----------------------------------------------------------------------------
409// wxPropertyInfo
410// ----------------------------------------------------------------------------
411
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()
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 }
447
448}
449
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()
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
491
492// ----------------------------------------------------------------------------
493// wxClassInfo
494// ----------------------------------------------------------------------------
495
496bool wxClassInfo::Create(wxObject *object, int ParamCount, wxAny *Params) const
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
508wxObject *wxClassInfo::ConstructObject(int ParamCount, wxAny *Params) const
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
539const wxPropertyAccessor *wxClassInfo::FindAccessor(const wxChar *PropertyName) const
540{
541 const wxPropertyInfo* info = FindPropertyInfo( PropertyName );
542
543 if ( info )
544 return info->GetAccessor();
545
546 return NULL;
547}
548
549wxPropertyInfo *wxClassInfo::FindPropertyInfoInThisClass (const wxChar *PropertyName) const
550{
551 wxPropertyInfo* info = GetFirstProperty();
552
553 while( info )
554 {
555 if ( wxStrcmp( info->GetName(), PropertyName ) == 0 )
556 return info;
557 info = info->GetNext();
558 }
559
560 return 0;
561}
562
563const wxPropertyInfo *wxClassInfo::FindPropertyInfo (const wxChar *PropertyName) const
564{
565 const wxPropertyInfo* info = FindPropertyInfoInThisClass( PropertyName );
566 if ( info )
567 return info;
568
569 const wxClassInfo** parents = GetParents();
570 for ( int i = 0; parents[i]; ++ i )
571 {
572 if ( ( info = parents[i]->FindPropertyInfo( PropertyName ) ) != NULL )
573 return info;
574 }
575
576 return 0;
577}
578
579wxHandlerInfo *wxClassInfo::FindHandlerInfoInThisClass (const wxChar *PropertyName) const
580{
581 wxHandlerInfo* info = GetFirstHandler();
582
583 while( info )
584 {
585 if ( wxStrcmp( info->GetName(), PropertyName ) == 0 )
586 return info;
587 info = info->GetNext();
588 }
589
590 return 0;
591}
592
593const wxHandlerInfo *wxClassInfo::FindHandlerInfo (const wxChar *PropertyName) const
594{
595 const wxHandlerInfo* info = FindHandlerInfoInThisClass( PropertyName );
596
597 if ( info )
598 return info;
599
600 const wxClassInfo** parents = GetParents();
601 for ( int i = 0; parents[i]; ++ i )
602 {
603 if ( ( info = parents[i]->FindHandlerInfo( PropertyName ) ) != NULL )
604 return info;
605 }
606
607 return 0;
608}
609
610wxObjectStreamingCallback wxClassInfo::GetStreamingCallback() const
611{
612 if ( m_streamingCallback )
613 return m_streamingCallback;
614
615 wxObjectStreamingCallback retval = NULL;
616 const wxClassInfo** parents = GetParents();
617 for ( int i = 0; parents[i] && retval == NULL; ++ i )
618 {
619 retval = parents[i]->GetStreamingCallback();
620 }
621 return retval;
622}
623
624bool wxClassInfo::BeforeWriteObject( const wxObject *obj, wxObjectWriter *streamer,
625 wxObjectWriterCallback *writercallback, const wxStringToAnyHashMap &metadata) const
626{
627 wxObjectStreamingCallback sb = GetStreamingCallback();
628 if ( sb )
629 return (*sb)(obj, streamer, writercallback, metadata );
630
631 return true;
632}
633
634void wxClassInfo::SetProperty(wxObject *object, const wxChar *propertyName,
635 const wxAny &value) const
636{
637 const wxPropertyAccessor *accessor;
638
639 accessor = FindAccessor(propertyName);
640 wxASSERT(accessor->HasSetter());
641 accessor->SetProperty( object, value );
642}
643
644wxAny wxClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const
645{
646 const wxPropertyAccessor *accessor;
647
648 accessor = FindAccessor(propertyName);
649 wxASSERT(accessor->HasGetter());
650 wxAny result;
651 accessor->GetProperty(object,result);
652 return result;
653}
654
655wxAnyList wxClassInfo::GetPropertyCollection(wxObject *object,
656 const wxChar *propertyName) const
657{
658 const wxPropertyAccessor *accessor;
659
660 accessor = FindAccessor(propertyName);
661 wxASSERT(accessor->HasGetter());
662 wxAnyList result;
663 accessor->GetPropertyCollection(object,result);
664 return result;
665}
666
667void wxClassInfo::AddToPropertyCollection(wxObject *object, const wxChar *propertyName,
668 const wxAny& value) const
669{
670 const wxPropertyAccessor *accessor;
671
672 accessor = FindAccessor(propertyName);
673 wxASSERT(accessor->HasAdder());
674 accessor->AddToPropertyCollection( object, value );
675}
676
677// void wxClassInfo::GetProperties( wxPropertyInfoMap &map ) const
678// The map parameter (the name map that is) seems something special
679// to MSVC and so we use a other name.
680void wxClassInfo::GetProperties( wxPropertyInfoMap &infomap ) const
681{
682 const wxPropertyInfo *pi = GetFirstProperty();
683 while( pi )
684 {
685 if ( infomap.find( pi->GetName() ) == infomap.end() )
686 infomap[pi->GetName()] = (wxPropertyInfo*) pi;
687
688 pi = pi->GetNext();
689 }
690
691 const wxClassInfo** parents = GetParents();
692 for ( int i = 0; parents[i]; ++ i )
693 {
694 parents[i]->GetProperties( infomap );
695 }
696}
697
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}
715
716bool wxClassInfo::NeedsDirectConstruction() const
717{
718 return wx_dynamic_cast(wxObjectAllocator*, m_constructor) != NULL;
719}
720
721// ----------------------------------------------------------------------------
722// wxDynamicObject support
723// ----------------------------------------------------------------------------
724
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{
731 wxDynamicObjectInternal() {}
732
733 wxStringToAnyHashMap m_properties;
734};
735
736typedef list< wxDynamicObject* > wxDynamicObjectList;
737
738struct wxDynamicClassInfo::wxDynamicClassInfoInternal
739{
740 wxDynamicObjectList m_dynamicObjects;
741};
742
743// instantiates this object with an instance of its superclass
744wxDynamicObject::wxDynamicObject(wxObject* superClassInstance, const wxDynamicClassInfo *info)
745{
746 m_superClassInstance = superClassInstance;
747 m_classInfo = info;
748 m_data = new wxDynamicObjectInternal;
749}
750
751wxDynamicObject::~wxDynamicObject()
752{
753 wx_dynamic_cast(const wxDynamicClassInfo*, m_classInfo)->
754 m_data->m_dynamicObjects.remove( this );
755 delete m_data;
756 delete m_superClassInstance;
757}
758
759void wxDynamicObject::SetProperty (const wxChar *propertyName, const wxAny &value)
760{
761 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
762 wxT("Accessing Unknown Property in a Dynamic Object") );
763 m_data->m_properties[propertyName] = value;
764}
765
766wxAny wxDynamicObject::GetProperty (const wxChar *propertyName) const
767{
768 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
769 wxT("Accessing Unknown Property in a Dynamic Object") );
770 return m_data->m_properties[propertyName];
771}
772
773void wxDynamicObject::RemoveProperty( const wxChar *propertyName )
774{
775 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(propertyName),
776 wxT("Removing Unknown Property in a Dynamic Object") );
777 m_data->m_properties.erase( propertyName );
778}
779
780void wxDynamicObject::RenameProperty( const wxChar *oldPropertyName,
781 const wxChar *newPropertyName )
782{
783 wxASSERT_MSG(m_classInfo->FindPropertyInfoInThisClass(oldPropertyName),
784 wxT("Renaming Unknown Property in a Dynamic Object") );
785
786 wxAny value = m_data->m_properties[oldPropertyName];
787 m_data->m_properties.erase( oldPropertyName );
788 m_data->m_properties[newPropertyName] = value;
789}
790
791
792// ----------------------------------------------------------------------------
793// wxDynamicClassInfo
794// ----------------------------------------------------------------------------
795
796wxDynamicClassInfo::wxDynamicClassInfo( const wxChar *unitName,
797 const wxChar *className,
798 const wxClassInfo* superClass ) :
799 wxClassInfo( unitName, className, new const wxClassInfo*[2])
800{
801 GetParents()[0] = superClass;
802 GetParents()[1] = NULL;
803 m_data = new wxDynamicClassInfoInternal;
804}
805
806wxDynamicClassInfo::~wxDynamicClassInfo()
807{
808 delete[] GetParents();
809 delete m_data;
810}
811
812wxObject *wxDynamicClassInfo::AllocateObject() const
813{
814 wxObject* parent = GetParents()[0]->AllocateObject();
815 wxDynamicObject *obj = new wxDynamicObject( parent, this );
816 m_data->m_dynamicObjects.push_back( obj );
817 return obj;
818}
819
820bool wxDynamicClassInfo::Create (wxObject *object, int paramCount, wxAny *params) const
821{
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 );
828}
829
830// get number of parameters for constructor
831int wxDynamicClassInfo::GetCreateParamCount() const
832{
833 return GetParents()[0]->GetCreateParamCount();
834}
835
836// get i-th constructor parameter
837const wxChar* wxDynamicClassInfo::GetCreateParamName(int i) const
838{
839 return GetParents()[0]->GetCreateParamName( i );
840}
841
842void wxDynamicClassInfo::SetProperty(wxObject *object, const wxChar *propertyName, const wxAny &value) const
843{
844 wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
845 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
846 if ( FindPropertyInfoInThisClass(propertyName) )
847 dynobj->SetProperty( propertyName, value );
848 else
849 GetParents()[0]->SetProperty( dynobj->GetSuperClassInstance(), propertyName, value );
850}
851
852wxAny wxDynamicClassInfo::GetProperty(wxObject *object, const wxChar *propertyName) const
853{
854 wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
855 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
856 if ( FindPropertyInfoInThisClass(propertyName) )
857 return dynobj->GetProperty( propertyName );
858 else
859 return GetParents()[0]->GetProperty( dynobj->GetSuperClassInstance(), propertyName );
860}
861
862void wxDynamicClassInfo::AddProperty( const wxChar *propertyName, const wxTypeInfo* typeInfo )
863{
864 EnsureInfosInited();
865 new wxPropertyInfo( m_firstProperty, this, propertyName, typeInfo->GetTypeName(), new wxGenericPropertyAccessor( propertyName ), wxAny() );
866}
867
868void wxDynamicClassInfo::AddHandler( const wxChar *handlerName, wxObjectEventFunction address, const wxClassInfo* eventClassInfo )
869{
870 EnsureInfosInited();
871 new wxHandlerInfo( m_firstHandler, this, handlerName, address, eventClassInfo );
872}
873
874// removes an existing runtime-property
875void wxDynamicClassInfo::RemoveProperty( const wxChar *propertyName )
876{
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);
880}
881
882// removes an existing runtime-handler
883void wxDynamicClassInfo::RemoveHandler( const wxChar *handlerName )
884{
885 delete FindHandlerInfoInThisClass(handlerName);
886}
887
888// renames an existing runtime-property
889void wxDynamicClassInfo::RenameProperty( const wxChar *oldPropertyName, const wxChar *newPropertyName )
890{
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 );
897}
898
899// renames an existing runtime-handler
900void wxDynamicClassInfo::RenameHandler( const wxChar *oldHandlerName, const wxChar *newHandlerName )
901{
902 wxASSERT_MSG(FindHandlerInfoInThisClass(oldHandlerName),wxT("not existing handler") );
903 FindHandlerInfoInThisClass(oldHandlerName)->m_name = newHandlerName;
904}
905
906// ----------------------------------------------------------------------------
907// wxGenericPropertyAccessor
908// ----------------------------------------------------------------------------
909
910struct wxGenericPropertyAccessor::wxGenericPropertyAccessorInternal
911{
912 char filler;
913};
914
915wxGenericPropertyAccessor::wxGenericPropertyAccessor( const wxString& propertyName )
916: wxPropertyAccessor( NULL, NULL, NULL, NULL )
917{
918 m_data = new wxGenericPropertyAccessorInternal;
919 m_propertyName = propertyName;
920 m_getterName = wxT("Get")+propertyName;
921 m_setterName = wxT("Set")+propertyName;
922}
923
924wxGenericPropertyAccessor::~wxGenericPropertyAccessor()
925{
926 delete m_data;
927}
928
929void wxGenericPropertyAccessor::SetProperty(wxObject *object, const wxAny &value) const
930{
931 wxDynamicObject* dynobj = wx_dynamic_cast(wxDynamicObject*, object);
932 wxASSERT_MSG( dynobj, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
933 dynobj->SetProperty(m_propertyName.c_str(), value );
934}
935
936void wxGenericPropertyAccessor::GetProperty(const wxObject *object, wxAny& value) const
937{
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") );
940 value = dynobj->GetProperty( m_propertyName.c_str() );
941}
942
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
971#endif // wxUSE_EXTENDED_RTTI