Remove all lines containing cvs/svn "$Id$" keyword.
[wxWidgets.git] / include / wx / xtiprop.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/xtiprop.h
3 // Purpose: XTI properties
4 // Author: Stefan Csomor
5 // Modified by: Francesco Montorsi
6 // Created: 27/07/03
7 // Copyright: (c) 1997 Julian Smart
8 // (c) 2003 Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _XTIPROP_H_
13 #define _XTIPROP_H_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_EXTENDED_RTTI
18
19 #include "wx/xti.h"
20 #include "wx/any.h"
21
22 /*
23 class WXDLLIMPEXP_BASE wxObject;
24 class WXDLLIMPEXP_BASE wxClassInfo;
25 class WXDLLIMPEXP_BASE wxDynamicClassInfo;
26 */
27 class WXDLLIMPEXP_BASE wxHashTable;
28 class WXDLLIMPEXP_BASE wxHashTable_Node;
29 class WXDLLIMPEXP_BASE wxEvent;
30 class WXDLLIMPEXP_BASE wxEvtHandler;
31
32 // ----------------------------------------------------------------------------
33 // Property Accessors
34 //
35 // wxPropertySetter/Getter/CollectionGetter/CollectionAdder are all property
36 // accessors which are managed by wxPropertyAccessor class which in turn is
37 // handled by wxPropertyInfo.
38 // ----------------------------------------------------------------------------
39
40 class WXDLLIMPEXP_BASE wxPropertySetter
41 {
42 public:
43 wxPropertySetter( const wxString name ) { m_name = name; }
44 virtual ~wxPropertySetter() {}
45
46 virtual void Set( wxObject *object, const wxAny &variantValue ) const = 0;
47 const wxString& GetName() const { return m_name; }
48
49 private:
50 wxString m_name;
51 };
52
53 class WXDLLIMPEXP_BASE wxPropertyGetter
54 {
55 public:
56 wxPropertyGetter( const wxString name ) { m_name = name; }
57 virtual ~wxPropertyGetter() {}
58
59 virtual void Get( const wxObject *object, wxAny& result) const = 0;
60 const wxString& GetName() const { return m_name; }
61
62 private:
63 wxString m_name;
64 };
65
66 class WXDLLIMPEXP_BASE wxPropertyCollectionGetter
67 {
68 public:
69 wxPropertyCollectionGetter( const wxString name ) { m_name = name; }
70 virtual ~wxPropertyCollectionGetter() {}
71
72 virtual void Get( const wxObject *object, wxAnyList& result) const = 0;
73 const wxString& GetName() const { return m_name; }
74
75 private:
76 wxString m_name;
77 };
78
79 template<typename coll_t> void WXDLLIMPEXP_BASE \
80 wxCollectionToVariantArray( const coll_t& coll, wxAnyList& result );
81
82 class WXDLLIMPEXP_BASE wxPropertyCollectionAdder
83 {
84 public:
85 wxPropertyCollectionAdder( const wxString name ) { m_name = name; }
86 virtual ~wxPropertyCollectionAdder() {}
87
88 virtual void Add( wxObject *object, const wxAny &variantValue ) const= 0;
89 const wxString& GetName() const { return m_name; }
90
91 private:
92 wxString m_name;
93 };
94
95 #define wxPROPERTY_SETTER( property, Klass, valueType, setterMethod ) \
96 class wxPropertySetter##property : public wxPropertySetter \
97 { \
98 public: \
99 wxINFUNC_CLASS_TYPE_FIX(Klass) \
100 wxPropertySetter##property() : wxPropertySetter( wxT(#setterMethod) ) {} \
101 virtual ~wxPropertySetter##property() {} \
102 \
103 void Set( wxObject *object, const wxAny &variantValue ) const \
104 { \
105 Klass *obj = dynamic_cast<Klass*>(object); \
106 valueType tempobj; \
107 if ( variantValue.GetAs(&tempobj) ) \
108 obj->setterMethod(tempobj); \
109 else \
110 obj->setterMethod(*wxANY_AS(variantValue, valueType*)); \
111 } \
112 };
113
114 #define wxPROPERTY_GETTER( property, Klass, valueType, gettermethod ) \
115 class wxPropertyGetter##property : public wxPropertyGetter \
116 { \
117 public: \
118 wxINFUNC_CLASS_TYPE_FIX(Klass) \
119 wxPropertyGetter##property() : wxPropertyGetter( wxT(#gettermethod) ) {} \
120 virtual ~wxPropertyGetter##property() {} \
121 \
122 void Get( const wxObject *object, wxAny &result) const \
123 { \
124 const Klass *obj = dynamic_cast<const Klass*>(object); \
125 result = wxAny( obj->gettermethod() ); \
126 } \
127 };
128
129 #define wxPROPERTY_COLLECTION_ADDER( property, Klass, valueType, addermethod ) \
130 class wxPropertyCollectionAdder##property : public wxPropertyCollectionAdder \
131 { \
132 public: \
133 wxINFUNC_CLASS_TYPE_FIX(Klass) \
134 wxPropertyCollectionAdder##property() : wxPropertyCollectionAdder( wxT(#addermethod) ) {} \
135 virtual ~wxPropertyCollectionAdder##property() {} \
136 \
137 void Add( wxObject *object, const wxAny &variantValue ) const \
138 { \
139 Klass *obj = dynamic_cast<Klass*>(object); \
140 valueType tempobj; \
141 if ( variantValue.GetAs(&tempobj) ) \
142 obj->addermethod(tempobj); \
143 else \
144 obj->addermethod(*wxANY_AS(variantValue, valueType*)); \
145 } \
146 };
147
148 #define wxPROPERTY_COLLECTION_GETTER( property, Klass, valueType, gettermethod ) \
149 class wxPropertyCollectionGetter##property : public wxPropertyCollectionGetter \
150 { \
151 public: \
152 wxINFUNC_CLASS_TYPE_FIX(Klass) \
153 wxPropertyCollectionGetter##property() : wxPropertyCollectionGetter( wxT(#gettermethod) ) {} \
154 virtual ~wxPropertyCollectionGetter##property() {} \
155 \
156 void Get( const wxObject *object, wxAnyList &result) const \
157 { \
158 const Klass *obj = dynamic_cast<const Klass*>(object); \
159 wxCollectionToVariantArray( obj->gettermethod(), result ); \
160 } \
161 };
162
163 class WXDLLIMPEXP_BASE wxPropertyAccessor
164 {
165 public:
166 wxPropertyAccessor( wxPropertySetter *setter, wxPropertyGetter *getter,
167 wxPropertyCollectionAdder *adder, wxPropertyCollectionGetter *collectionGetter )
168 { m_setter = setter; m_getter = getter; m_adder = adder;
169 m_collectionGetter = collectionGetter; }
170
171 virtual ~wxPropertyAccessor() {}
172
173 // Setting a simple property (non-collection)
174 virtual void SetProperty(wxObject *object, const wxAny &value) const
175 {
176 if ( m_setter )
177 m_setter->Set( object, value );
178 else
179 wxLogError( _("SetProperty called w/o valid setter") );
180 }
181
182 // Getting a simple property (non-collection)
183 virtual void GetProperty(const wxObject *object, wxAny &result) const
184 {
185 if ( m_getter )
186 m_getter->Get( object, result );
187 else
188 wxLogError( _("GetProperty called w/o valid getter") );
189 }
190
191 // Adding an element to a collection property
192 virtual void AddToPropertyCollection(wxObject *object, const wxAny &value) const
193 {
194 if ( m_adder )
195 m_adder->Add( object, value );
196 else
197 wxLogError( _("AddToPropertyCollection called w/o valid adder") );
198 }
199
200 // Getting a collection property
201 virtual void GetPropertyCollection( const wxObject *obj, wxAnyList &result) const
202 {
203 if ( m_collectionGetter )
204 m_collectionGetter->Get( obj, result);
205 else
206 wxLogError( _("GetPropertyCollection called w/o valid collection getter") );
207 }
208
209 virtual bool HasSetter() const { return m_setter != NULL; }
210 virtual bool HasCollectionGetter() const { return m_collectionGetter != NULL; }
211 virtual bool HasGetter() const { return m_getter != NULL; }
212 virtual bool HasAdder() const { return m_adder != NULL; }
213
214 virtual const wxString& GetCollectionGetterName() const
215 { return m_collectionGetter->GetName(); }
216 virtual const wxString& GetGetterName() const
217 { return m_getter->GetName(); }
218 virtual const wxString& GetSetterName() const
219 { return m_setter->GetName(); }
220 virtual const wxString& GetAdderName() const
221 { return m_adder->GetName(); }
222
223 protected:
224 wxPropertySetter *m_setter;
225 wxPropertyCollectionAdder *m_adder;
226 wxPropertyGetter *m_getter;
227 wxPropertyCollectionGetter* m_collectionGetter;
228 };
229
230 class WXDLLIMPEXP_BASE wxGenericPropertyAccessor : public wxPropertyAccessor
231 {
232 public:
233 wxGenericPropertyAccessor( const wxString &propName );
234 virtual ~wxGenericPropertyAccessor();
235
236 void RenameProperty( const wxString& WXUNUSED_UNLESS_DEBUG(oldName),
237 const wxString& newName )
238 {
239 wxASSERT( oldName == m_propertyName ); m_propertyName = newName;
240 }
241
242 virtual bool HasSetter() const { return true; }
243 virtual bool HasGetter() const { return true; }
244 virtual bool HasAdder() const { return false; }
245 virtual bool HasCollectionGetter() const { return false; }
246
247 virtual const wxString& GetGetterName() const
248 { return m_getterName; }
249 virtual const wxString& GetSetterName() const
250 { return m_setterName; }
251
252 virtual void SetProperty(wxObject *object, const wxAny &value) const;
253 virtual void GetProperty(const wxObject *object, wxAny &value) const;
254
255 // Adding an element to a collection property
256 virtual void AddToPropertyCollection(wxObject *WXUNUSED(object),
257 const wxAny &WXUNUSED(value)) const
258 {
259 wxLogError( _("AddToPropertyCollection called on a generic accessor") );
260 }
261
262 // Getting a collection property
263 virtual void GetPropertyCollection( const wxObject *WXUNUSED(obj),
264 wxAnyList &WXUNUSED(result)) const
265 {
266 wxLogError ( _("GetPropertyCollection called on a generic accessor") );
267 }
268
269 private:
270 struct wxGenericPropertyAccessorInternal;
271 wxGenericPropertyAccessorInternal* m_data;
272 wxString m_propertyName;
273 wxString m_setterName;
274 wxString m_getterName;
275 };
276
277 typedef long wxPropertyInfoFlags;
278 enum
279 {
280 // will be removed in future releases
281 wxPROP_DEPRECATED = 0x00000001,
282
283 // object graph property, will be streamed with priority (after constructor properties)
284 wxPROP_OBJECT_GRAPH = 0x00000002,
285
286 // this will only be streamed out and in as enum/set, the internal representation
287 // is still a long
288 wxPROP_ENUM_STORE_LONG = 0x00000004,
289
290 // don't stream out this property, needed eg to avoid streaming out children
291 // that are always created by their parents
292 wxPROP_DONT_STREAM = 0x00000008
293 };
294
295
296 // ----------------------------------------------------------------------------
297 // Property Support
298 //
299 // wxPropertyInfo is used to inquire of the property by name. It doesn't
300 // provide access to the property, only information about it. If you
301 // want access, look at wxPropertyAccessor.
302 // ----------------------------------------------------------------------------
303
304 class WXDLLIMPEXP_BASE wxPropertyInfo
305 {
306 friend class /* WXDLLIMPEXP_BASE */ wxDynamicClassInfo;
307
308 public:
309 wxPropertyInfo(wxPropertyInfo* &iter,
310 wxClassInfo* itsClass,
311 const wxString& name,
312 const wxString& typeName,
313 wxPropertyAccessor *accessor,
314 wxAny dv,
315 wxPropertyInfoFlags flags = 0,
316 const wxString& helpString = wxEmptyString,
317 const wxString& groupString = wxEmptyString) :
318 m_itsClass(itsClass),
319 m_name(name),
320 m_typeInfo(NULL),
321 m_typeName(typeName),
322 m_collectionElementTypeInfo(NULL),
323 m_accessor(accessor),
324 m_defaultValue(dv),
325 m_flags(flags),
326 m_helpString(helpString),
327 m_groupString(groupString)
328 {
329 Insert(iter);
330 }
331
332 wxPropertyInfo(wxPropertyInfo* &iter,
333 wxClassInfo* itsClass,
334 const wxString& name,
335 wxEventSourceTypeInfo* type,
336 wxPropertyAccessor *accessor,
337 wxAny dv,
338 wxPropertyInfoFlags flags = 0,
339 const wxString& helpString = wxEmptyString,
340 const wxString& groupString = wxEmptyString) :
341 m_itsClass(itsClass),
342 m_name(name),
343 m_typeInfo(type),
344 m_collectionElementTypeInfo(NULL),
345 m_accessor(accessor),
346 m_defaultValue(dv),
347 m_flags(flags),
348 m_helpString(helpString),
349 m_groupString(groupString)
350 {
351 Insert(iter);
352 }
353
354 wxPropertyInfo(wxPropertyInfo* &iter,
355 wxClassInfo* itsClass, const wxString& name,
356 const wxString& collectionTypeName,
357 const wxString& elementTypeName,
358 wxPropertyAccessor *accessor,
359 wxPropertyInfoFlags flags = 0,
360 const wxString& helpString = wxEmptyString,
361 const wxString& groupString = wxEmptyString) :
362 m_itsClass(itsClass),
363 m_name(name),
364 m_typeInfo(NULL),
365 m_typeName(collectionTypeName),
366 m_collectionElementTypeInfo(NULL),
367 m_collectionElementTypeName(elementTypeName),
368 m_accessor(accessor),
369 m_flags(flags),
370 m_helpString(helpString),
371 m_groupString(groupString)
372 {
373 Insert(iter);
374 }
375
376 ~wxPropertyInfo()
377 { Remove(); }
378
379 // return the class this property is declared in
380 const wxClassInfo* GetDeclaringClass() const { return m_itsClass; }
381
382 // return the name of this property
383 const wxString& GetName() const { return m_name; }
384
385 // returns the flags of this property
386 wxPropertyInfoFlags GetFlags() const { return m_flags; }
387
388 // returns the short help string of this property
389 const wxString& GetHelpString() const { return m_helpString; }
390
391 // returns the group string of this property
392 const wxString& GetGroupString() const { return m_groupString; }
393
394 // return the element type info of this property (for collections, otherwise NULL)
395 const wxTypeInfo * GetCollectionElementTypeInfo() const
396 {
397 if ( m_collectionElementTypeInfo == NULL )
398 m_collectionElementTypeInfo = wxTypeInfo::FindType(m_collectionElementTypeName);
399 return m_collectionElementTypeInfo;
400 }
401
402 // return the type info of this property
403 const wxTypeInfo * GetTypeInfo() const
404 {
405 if ( m_typeInfo == NULL )
406 m_typeInfo = wxTypeInfo::FindType(m_typeName);
407 return m_typeInfo;
408 }
409
410 // return the accessor for this property
411 wxPropertyAccessor* GetAccessor() const { return m_accessor; }
412
413 // returns NULL if this is the last property of this class
414 wxPropertyInfo* GetNext() const { return m_next; }
415
416 // returns the default value of this property, its kind may be wxT_VOID if it is not valid
417 wxAny GetDefaultValue() const { return m_defaultValue; }
418
419 private:
420
421 // inserts this property at the end of the linked chain which begins
422 // with "iter" property.
423 void Insert(wxPropertyInfo* &iter);
424
425 // removes this property from the linked chain of the m_itsClass properties.
426 void Remove();
427
428 wxClassInfo* m_itsClass;
429 wxString m_name;
430 mutable wxTypeInfo* m_typeInfo;
431 wxString m_typeName;
432 mutable wxTypeInfo* m_collectionElementTypeInfo;
433 wxString m_collectionElementTypeName;
434 wxPropertyAccessor* m_accessor;
435 wxAny m_defaultValue;
436 wxPropertyInfoFlags m_flags;
437 wxString m_helpString;
438 wxString m_groupString;
439 wxPropertyInfo* m_next;
440
441 // FIXME: what's this comment about??
442 // string representation of the default value
443 // to be assigned by the designer to the property
444 // when the component is dropped on the container.
445 };
446
447 // stl is giving problems when forwarding declarations, therefore we define it as a subclass
448
449 WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxPropertyInfo*, wxPropertyInfoMapBase,
450 class WXDLLIMPEXP_BASE );
451
452 class WXDLLIMPEXP_BASE wxPropertyInfoMap : public wxPropertyInfoMapBase {
453 };
454
455 WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxAny, wxStringToAnyHashMapBase,
456 class WXDLLIMPEXP_BASE );
457
458 class WXDLLIMPEXP_FWD_BASE wxStringToAnyHashMap : public wxStringToAnyHashMapBase {
459 };
460
461 #define wxBEGIN_PROPERTIES_TABLE(theClass) \
462 wxPropertyInfo *theClass::GetPropertiesStatic() \
463 { \
464 typedef theClass class_t; \
465 static wxPropertyInfo* first = NULL;
466
467 #define wxEND_PROPERTIES_TABLE() \
468 return first; }
469
470 #define wxHIDE_PROPERTY( pname ) \
471 static wxPropertyInfo _propertyInfo##pname( first, class_t::GetClassInfoStatic(), \
472 wxT(#pname), typeid(void).name(), NULL, wxAny(), wxPROP_DONT_STREAM, \
473 wxEmptyString, wxEmptyString );
474
475 #define wxPROPERTY( pname, type, setter, getter, defaultValue, flags, help, group) \
476 wxPROPERTY_SETTER( pname, class_t, type, setter ) \
477 static wxPropertySetter##pname _setter##pname; \
478 wxPROPERTY_GETTER( pname, class_t, type, getter ) \
479 static wxPropertyGetter##pname _getter##pname; \
480 static wxPropertyAccessor _accessor##pname( &_setter##pname, \
481 &_getter##pname, NULL, NULL ); \
482 static wxPropertyInfo _propertyInfo##pname( first, class_t::GetClassInfoStatic(), \
483 wxT(#pname), typeid(type).name(), &_accessor##pname, \
484 wxAny(defaultValue), flags, group, help );
485
486 #define wxPROPERTY_FLAGS( pname, flags, type, setter, getter,defaultValue, \
487 pflags, help, group) \
488 wxPROPERTY_SETTER( pname, class_t, type, setter ) \
489 static wxPropertySetter##pname _setter##pname; \
490 wxPROPERTY_GETTER( pname, class_t, type, getter ) \
491 static wxPropertyGetter##pname _getter##pname; \
492 static wxPropertyAccessor _accessor##pname( &_setter##pname, \
493 &_getter##pname, NULL, NULL ); \
494 static wxPropertyInfo _propertyInfo##pname( first, class_t::GetClassInfoStatic(), \
495 wxT(#pname), typeid(flags).name(), &_accessor##pname, \
496 wxAny(defaultValue), wxPROP_ENUM_STORE_LONG | pflags, help, group );
497
498 #define wxREADONLY_PROPERTY( pname, type, getter,defaultValue, flags, help, group) \
499 wxPROPERTY_GETTER( pname, class_t, type, getter ) \
500 static wxPropertyGetter##pname _getter##pname; \
501 static wxPropertyAccessor _accessor##pname( NULL, &_getter##pname, NULL, NULL ); \
502 static wxPropertyInfo _propertyInfo##pname( first, class_t::GetClassInfoStatic(), \
503 wxT(#pname), typeid(type).name(),&_accessor##pname, \
504 wxAny(defaultValue), flags, help, group );
505
506 #define wxREADONLY_PROPERTY_FLAGS( pname, flags, type, getter,defaultValue, \
507 pflags, help, group) \
508 wxPROPERTY_GETTER( pname, class_t, type, getter ) \
509 static wxPropertyGetter##pname _getter##pname; \
510 static wxPropertyAccessor _accessor##pname( NULL, &_getter##pname, NULL, NULL ); \
511 static wxPropertyInfo _propertyInfo##pname( first, class_t::GetClassInfoStatic(), \
512 wxT(#pname), typeid(flags).name(),&_accessor##pname, \
513 wxAny(defaultValue), wxPROP_ENUM_STORE_LONG | pflags, help, group );
514
515 #define wxPROPERTY_COLLECTION( pname, colltype, addelemtype, adder, getter, \
516 flags, help, group ) \
517 wxPROPERTY_COLLECTION_ADDER( pname, class_t, addelemtype, adder ) \
518 static wxPropertyCollectionAdder##pname _adder##pname; \
519 wxPROPERTY_COLLECTION_GETTER( pname, class_t, colltype, getter ) \
520 static wxPropertyCollectionGetter##pname _collectionGetter##pname; \
521 static wxPropertyAccessor _accessor##pname( NULL, NULL,&_adder##pname, \
522 &_collectionGetter##pname ); \
523 static wxPropertyInfo _propertyInfo##pname( first, class_t::GetClassInfoStatic(), \
524 wxT(#pname), typeid(colltype).name(),typeid(addelemtype).name(), \
525 &_accessor##pname, flags, help, group );
526
527 #define wxREADONLY_PROPERTY_COLLECTION( pname, colltype, addelemtype, getter, \
528 flags, help, group) \
529 wxPROPERTY_COLLECTION_GETTER( pname, class_t, colltype, getter ) \
530 static wxPropertyCollectionGetter##pname _collectionGetter##pname; \
531 static wxPropertyAccessor _accessor##pname( NULL, NULL, NULL, \
532 &_collectionGetter##pname ); \
533 static wxPropertyInfo _propertyInfo##pname( first,class_t::GetClassInfoStatic(), \
534 wxT(#pname), typeid(colltype).name(),typeid(addelemtype).name(), \
535 &_accessor##pname, flags, help, group );
536
537 #define wxEVENT_PROPERTY( name, eventType, eventClass ) \
538 static wxEventSourceTypeInfo _typeInfo##name( eventType, wxCLASSINFO( eventClass ) ); \
539 static wxPropertyInfo _propertyInfo##name( first,class_t::GetClassInfoStatic(), \
540 wxT(#name), &_typeInfo##name, NULL, wxAny() );
541
542 #define wxEVENT_RANGE_PROPERTY( name, eventType, lastEventType, eventClass ) \
543 static wxEventSourceTypeInfo _typeInfo##name( eventType, lastEventType, \
544 wxCLASSINFO( eventClass ) ); \
545 static wxPropertyInfo _propertyInfo##name( first, class_t::GetClassInfoStatic(), \
546 wxT(#name), &_typeInfo##name, NULL, wxAny() );
547
548 // ----------------------------------------------------------------------------
549 // Implementation Helper for Simple Properties
550 // ----------------------------------------------------------------------------
551
552 #define wxIMPLEMENT_PROPERTY(name, type) \
553 private: \
554 type m_##name; \
555 public: \
556 void Set##name( type const & p) { m_##name = p; } \
557 type const & Get##name() const { return m_##name; }
558
559 #endif // wxUSE_EXTENDED_RTTI
560 #endif // _XTIPROP_H_