source: vendor/trolltech/current/src/kernel/qmetaobject.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 32.7 KB
Line 
1/****************************************************************************
2** $Id: qmetaobject.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QMetaObject class
5**
6** Created : 930419
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qmetaobject.h"
39#include "qasciidict.h"
40
41#ifdef QT_THREAD_SUPPORT
42#include <private/qmutexpool_p.h>
43#endif // QT_THREAD_SUPPORT
44
45/*!
46 \class QMetaData qmetaobject.h
47 \reentrant
48
49 \brief The QMetaData class provides information about a member function that is known to the meta object system.
50
51 \internal
52
53 The struct consists of three members, \e name, \e method and \e access:
54
55 \code
56 const char *name; // - member name
57 const QUMethod* method; // - detailed method description
58 enum Access { Private, Protected, Public };
59 Access access; // - access permission
60 \endcode
61 */
62
63/*!
64 \class QClassInfo qmetaobject.h
65
66 \brief The QClassInfo class provides a struct that stores some basic information about a single class.
67
68 \internal
69
70 The class information is a simple \e name - \e value pair:
71
72 \code
73 const char* name;
74 const char* value;
75 \endcode
76
77 */
78
79
80/*!
81 \class QMetaObject qmetaobject.h
82 \brief The QMetaObject class contains meta information about Qt objects.
83
84 \ingroup objectmodel
85
86 The Meta Object System in Qt is responsible for the signals and
87 slots inter-object communication mechanism, runtime type
88 information and the property system. All meta information in Qt is
89 kept in a single instance of QMetaObject per class.
90
91 This class is not normally required for application programming.
92 But if you write meta applications, such as scripting engines or
93 GUI builders, you might find these functions useful:
94 \list
95 \i className() to get the name of a class.
96 \i superClassName() to get the name of the superclass.
97 \i inherits(), the function called by QObject::inherits().
98 \i superClass() to access the superclass's meta object.
99 \i numSlots(), numSignals(), slotNames(), and signalNames() to get
100 information about a class's signals and slots.
101 \i property() and propertyNames() to obtain information about a
102 class's properties.
103 \endlist
104
105 Classes may have a list of name-value pairs of class information.
106 The number of pairs is returned by numClassInfo(), and values are
107 returned by classInfo().
108
109 \sa \link moc.html moc (Meta Object Compiler)\endlink
110
111*/
112
113
114/*****************************************************************************
115 The private object.
116 *****************************************************************************/
117
118// extra flags from moc.y
119enum Flags {
120 Invalid = 0x00000000,
121 Readable = 0x00000001,
122 Writable = 0x00000002,
123 EnumOrSet = 0x00000004,
124 UnresolvedEnum = 0x00000008,
125 StdSet = 0x00000100,
126 Override = 0x00000200,
127 NotDesignable = 0x00001000,
128 DesignableOverride = 0x00002000,
129 NotScriptable = 0x00004000,
130 ScriptableOverride = 0x00008000,
131 NotStored = 0x00010000,
132 StoredOverride = 0x00020000
133};
134
135static QAsciiDict<void> *qt_metaobjects = 0;
136static int qt_metaobjects_count = 0;
137
138class QMetaObjectPrivate
139{
140public:
141 QMetaObjectPrivate() :
142#ifndef QT_NO_PROPERTIES
143 enumData(0), numEnumData(0),
144 propData(0),numPropData(0),
145 qt_static_property(0),
146#endif
147 classInfo(0), numClassInfo(0) {}
148#ifndef QT_NO_PROPERTIES
149 const QMetaEnum *enumData;
150 int numEnumData;
151 const QMetaProperty *propData;
152 int numPropData;
153 bool (*qt_static_property)(QObject*, int, int, QVariant*);
154#endif
155 const QClassInfo *classInfo;
156 int numClassInfo;
157};
158
159
160/*****************************************************************************
161 Internal dictionary for fast access to class members
162 *****************************************************************************/
163
164#if defined(Q_CANNOT_DELETE_CONSTANT)
165typedef QMetaData QConstMetaData;
166#else
167typedef const QMetaData QConstMetaData;
168#endif
169
170class Q_EXPORT QMemberDict : public QAsciiDict<QConstMetaData>
171{
172public:
173 QMemberDict( int size = 17, bool cs = TRUE, bool ck = TRUE ) :
174 QAsciiDict<QConstMetaData>(size,cs,ck) {}
175 QMemberDict( const QMemberDict &dict ) : QAsciiDict<QConstMetaData>(dict) {}
176 ~QMemberDict() { clear(); }
177 QMemberDict &operator=(const QMemberDict &dict)
178 { return (QMemberDict&)QAsciiDict<QConstMetaData>::operator=(dict); }
179};
180
181
182/*
183 Calculate optimal dictionary size for n entries using prime numbers,
184 and assuming there are no more than 40 entries.
185*/
186
187static int optDictSize( int n )
188{
189 if ( n < 6 )
190 n = 5;
191 else if ( n < 10 )
192 n = 11;
193 else if ( n < 14 )
194 n = 17;
195 else
196 n = 23;
197 return n;
198}
199
200
201/*****************************************************************************
202 QMetaObject member functions
203 *****************************************************************************/
204
205/*!\internal
206 */
207QMetaObject::QMetaObject( const char *const class_name, QMetaObject *super_class,
208 const QMetaData *const slot_data, int n_slots,
209 const QMetaData *const signal_data, int n_signals,
210#ifndef QT_NO_PROPERTIES
211 const QMetaProperty *const prop_data, int n_props,
212 const QMetaEnum *const enum_data, int n_enums,
213#endif
214 const QClassInfo *const class_info, int n_info )
215{
216 classname = class_name; // set meta data
217 superclass = super_class;
218 superclassname = superclass ? superclass->className() : 0;
219 slotDict = init( slotData = slot_data, n_slots );
220 signalDict = init( signalData = signal_data, n_signals );
221
222 d = new QMetaObjectPrivate;
223 reserved = 0;
224
225#ifndef QT_NO_PROPERTIES
226 d->propData = prop_data;
227 d->numPropData = n_props;
228 d->enumData = enum_data;
229 d->numEnumData = n_enums;
230#endif
231 d->classInfo = class_info;
232 d->numClassInfo = n_info;
233
234 signaloffset = superclass ? ( superclass->signalOffset() + superclass->numSignals() ) : 0;
235 slotoffset = superclass ? ( superclass->slotOffset() + superclass->numSlots() ) : 0;
236#ifndef QT_NO_PROPERTIES
237 propertyoffset = superclass ? ( superclass->propertyOffset() + superclass->numProperties() ) : 0;
238#endif
239}
240
241#ifndef QT_NO_PROPERTIES
242/*!\internal
243 */
244QMetaObject::QMetaObject( const char *const class_name, QMetaObject *super_class,
245 const QMetaData *const slot_data, int n_slots,
246 const QMetaData *const signal_data, int n_signals,
247 const QMetaProperty *const prop_data, int n_props,
248 const QMetaEnum *const enum_data, int n_enums,
249 bool (*qt_static_property)(QObject*, int, int, QVariant*),
250 const QClassInfo *const class_info, int n_info )
251{
252 classname = class_name; // set meta data
253 superclass = super_class;
254 superclassname = superclass ? superclass->className() : 0;
255 slotDict = init( slotData = slot_data, n_slots );
256 signalDict = init( signalData = signal_data, n_signals );
257
258 d = new QMetaObjectPrivate;
259 reserved = 0;
260
261 d->propData = prop_data;
262 d->numPropData = n_props;
263 d->enumData = enum_data;
264 d->numEnumData = n_enums;
265 d->qt_static_property = qt_static_property;
266 d->classInfo = class_info;
267 d->numClassInfo = n_info;
268
269 signaloffset = superclass ? ( superclass->signalOffset() + superclass->numSignals() ) : 0;
270 slotoffset = superclass ? ( superclass->slotOffset() + superclass->numSlots() ) : 0;
271 propertyoffset = superclass ? ( superclass->propertyOffset() + superclass->numProperties() ) : 0;
272}
273#endif
274
275/*!\internal
276 */
277QMetaObject::~QMetaObject()
278{
279 delete slotDict; // delete dicts
280 delete signalDict;
281 delete d;
282#ifdef QT_THREAD_SUPPORT
283 QMutexLocker( qt_global_mutexpool ?
284 qt_global_mutexpool->get( &qt_metaobjects ) : 0 );
285#endif // QT_THREAD_SUPPORT
286 if ( qt_metaobjects ) {
287 qt_metaobjects->remove( classname );
288 if ( qt_metaobjects->isEmpty() ) {
289 delete qt_metaobjects;
290 qt_metaobjects = 0;
291 }
292 }
293
294 // delete reserved; // Unused void*
295}
296
297
298/*!
299 \fn const char *QMetaObject::className() const
300
301 Returns the class name.
302
303 \sa QObject::className(), superClassName()
304*/
305
306/*!
307 \fn const char *QMetaObject::superClassName() const
308
309 Returns the class name of the superclass or 0 if there is no
310 superclass in the QObject hierachy.
311
312 \sa className()
313*/
314
315/*!
316 \fn QMetaObject *QMetaObject::superClass() const
317
318 Returns the meta object of the super class or 0 if there is no
319 such object.
320*/
321
322/*!
323 Returns the number of slots for this class.
324
325 If \a super is TRUE, inherited slots are included.
326
327 \sa slotNames()
328*/
329int QMetaObject::numSlots( bool super ) const // number of slots
330{
331 int n = slotDict ? slotDict->count() : 0;
332 if ( !super || !superclass )
333 return n;
334 return n + superclass->numSlots( super );
335}
336
337/*!
338 Returns the number of signals for this class.
339
340 If \a super is TRUE, inherited signals are included.
341
342 \sa signalNames()
343*/
344int QMetaObject::numSignals( bool super ) const // number of signals
345{
346 int n = signalDict ? signalDict->count() : 0;
347 if ( !super || !superclass )
348 return n;
349 return n + superclass->numSignals( super );
350}
351
352
353/*! \internal
354
355 Returns the meta data of the slot with the name \a n or 0 if no
356 such slot exists.
357
358 If \a super is TRUE, inherited slots are included.
359 */
360const QMetaData* QMetaObject::slot( int index, bool super ) const
361{
362 int idx = index - ( super ? slotOffset() : 0 );
363 if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
364 return slotData + idx;
365 }
366 if ( !super || !superclass )
367 return 0;
368 return superclass->slot( index, super );
369}
370
371/*! \internal
372
373 Returns the meta data of the signal with the name \a n or 0 if no
374 such signal exists.
375
376 If \a super is TRUE, inherited signals are included.
377 */
378const QMetaData* QMetaObject::signal( int index, bool super ) const
379{
380 int idx = index - ( super ? signalOffset() : 0 );
381 if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
382 return signalData + idx;
383 }
384 if ( !super || !superclass )
385 return 0;
386 return superclass->signal( index, super );
387}
388
389
390/*!
391 \fn int QMetaObject::signalOffset() const
392
393 \internal
394
395 Returns the signal offset for this metaobject.
396
397*/
398
399/*!
400 \fn int QMetaObject::propertyOffset() const
401
402 \internal
403
404 Returns the property offset for this metaobject.
405
406*/
407
408/*! \internal
409 Returns the index of the signal with name \n or -1 if no such signal exists.
410
411 If \a super is TRUE, inherited signals are included.
412*/
413int QMetaObject::findSignal( const char* n, bool super ) const
414{
415 const QMetaObject *mo = this;
416 int offset = -1;
417
418 do {
419 const QMetaData *md = mo->signalDict ? mo->signalDict->find( n ) : 0;
420 if ( md ) {
421#if defined(QT_CHECK_RANGE)
422 if ( offset != -1 ) {
423 qWarning( "QMetaObject::findSignal:%s: Conflict with %s::%s",
424 className(), mo->className(), n );
425 return offset;
426 }
427#endif
428 offset = mo->signalOffset() + ( md - mo->signalData );
429#if !defined(QT_CHECK_RANGE)
430 return offset;
431#endif
432 }
433 } while ( super && (mo = mo->superclass) );
434
435 return offset;
436}
437
438/*!
439 \fn int QMetaObject::slotOffset() const
440
441 \internal
442
443 Returns the slot offset for this metaobject.
444
445*/
446
447/*! \internal
448 Returns the index of the slot with name \n or -1 if no such slot exists.
449
450 If \a super is TRUE, inherited slots are included.
451 */
452int QMetaObject::findSlot( const char* n, bool super ) const
453{
454 const QMetaData *md = slotDict ? slotDict->find( n ) : 0;
455 if ( md )
456 return slotOffset() + ( md - slotData );
457 if ( !super || !superclass)
458 return -1;
459 return superclass->findSlot( n, super );
460}
461
462/*!\internal
463 */
464QMetaObject *QMetaObject::new_metaobject( const char *classname,
465 QMetaObject *superclassobject,
466 const QMetaData * const slot_data, int n_slots,
467 const QMetaData * const signal_data, int n_signals,
468#ifndef QT_NO_PROPERTIES
469 const QMetaProperty * const prop_data, int n_props,
470 const QMetaEnum * const enum_data, int n_enums,
471#endif
472 const QClassInfo * const class_info, int n_info )
473{
474 return new QMetaObject( classname, superclassobject, slot_data, n_slots,
475 signal_data, n_signals,
476#ifndef QT_NO_PROPERTIES
477 prop_data, n_props,
478 enum_data, n_enums,
479#endif
480 class_info, n_info );
481}
482
483#ifndef QT_NO_PROPERTIES
484/*!\internal
485 */
486QMetaObject *QMetaObject::new_metaobject( const char *classname,
487 QMetaObject *superclassobject,
488 const QMetaData * const slot_data, int n_slots,
489 const QMetaData * const signal_data, int n_signals,
490 const QMetaProperty * const prop_data, int n_props,
491 const QMetaEnum * const enum_data, int n_enums,
492 bool (*qt_static_property)(QObject*, int, int, QVariant*),
493 const QClassInfo * const class_info, int n_info )
494{
495 return new QMetaObject( classname, superclassobject, slot_data, n_slots,
496 signal_data, n_signals,
497 prop_data, n_props,
498 enum_data, n_enums,
499 qt_static_property,
500 class_info, n_info );
501}
502#endif
503
504/*!\internal
505 */
506QMemberDict *QMetaObject::init( const QMetaData * data, int n )
507{
508 if ( n == 0 ) // nothing, then make no dict
509 return 0;
510 QMemberDict *dict = new QMemberDict( optDictSize(n), TRUE, FALSE );
511 Q_CHECK_PTR( dict );
512 while ( n-- ) { // put all members into dict
513 dict->insert( data->name, data );
514 data++;
515 }
516 return dict;
517}
518
519/*!
520 Returns the number of items of class information available for
521 this class.
522
523 If \a super is TRUE, inherited class information is included.
524*/
525int QMetaObject::numClassInfo( bool super ) const
526{
527 return d->numClassInfo + ((super && superclass)?superclass->numClassInfo(super):0);
528}
529
530/*!
531 Returns the class information with index \a index or 0 if no such
532 information exists.
533
534 If \a super is TRUE, inherited class information is included.
535*/
536const QClassInfo* QMetaObject::classInfo( int index, bool super ) const
537{
538 if ( index < 0 )
539 return 0;
540 if ( index < d->numClassInfo )
541 return &(d->classInfo[ index ]);
542 if ( !super || !superclass )
543 return 0;
544 return superclass->classInfo( index - d->numClassInfo, super );
545}
546
547/*!
548 \overload
549 Returns the class information with name \a name or 0 if no such
550 information exists.
551
552 If \a super is TRUE, inherited class information is included.
553*/
554const char* QMetaObject::classInfo( const char* name, bool super ) const
555{
556 for( int i = 0; i < d->numClassInfo; ++i ) {
557 if ( qstrcmp( d->classInfo[i].name, name ) == 0 )
558 return d->classInfo[i].value;
559 }
560 if ( !super || !superclass )
561 return 0;
562 return superclass->classInfo( name, super );
563}
564
565#ifndef QT_NO_PROPERTIES
566
567/*!
568 Returns the number of properties for this class.
569
570 If \a super is TRUE, inherited properties are included.
571
572 \sa propertyNames()
573 */
574int QMetaObject::numProperties( bool super ) const // number of signals
575{
576 int n = d->numPropData;
577 if ( !super || !superclass )
578 return n;
579 return n + superclass->numProperties( super );
580}
581
582/*!
583 Returns the property meta data for the property at index \a index
584 or 0 if no such property exists.
585
586 If \a super is TRUE, inherited properties are included.
587
588 \sa propertyNames()
589 */
590const QMetaProperty* QMetaObject::property( int index, bool super ) const
591{
592 int idx = index - ( super ? propertyOffset() : 0 );
593 if ( d->propData && idx >= 0 && idx < (int)d->numPropData )
594 return d->propData + idx;
595 if ( !super || !superclass )
596 return 0;
597 return superclass->property( index, super );
598}
599
600
601/*!
602 Returns the index for the property with name \a name or -1 if no
603 such property exists.
604
605 If \a super is TRUE, inherited properties are included.
606
607 \sa property(), propertyNames()
608*/
609
610int QMetaObject::findProperty( const char *name, bool super ) const
611{
612 for( int i = 0; i < d->numPropData; ++i ) {
613 if ( d->propData[i].isValid() && qstrcmp( d->propData[i].name(), name ) == 0 ) {
614 return ( super ? propertyOffset() : 0 ) + i;
615 }
616 }
617 if ( !super || !superclass )
618 return -1;
619 return superclass->findProperty( name, super );
620}
621
622/*! \internal
623
624 Returns the index for the property \a prop
625 or -1 if the property can not be found.
626
627 If \a super is TRUE, inherited properties are included.
628
629 \sa property(), propertyNames()
630*/
631
632int QMetaObject::indexOfProperty( const QMetaProperty* prop, bool super ) const
633{
634 if ( *prop->meta == this )
635 return ( super ? propertyOffset() : 0 ) + ( prop - d->propData);
636 if ( !super || !superclass )
637 return -1;
638 return superclass->indexOfProperty( prop, super );
639}
640
641/*!\internal
642
643 Returns the parent property of property \a p or 0, if the property
644 cannot be resolved.
645
646 \a p has to be contained in this meta object
647*/
648
649const QMetaProperty* QMetaObject::resolveProperty( const QMetaProperty* p ) const
650{
651 if ( !superclass )
652 return 0;
653 return superclass->property( superclass->findProperty( p->n, TRUE ), TRUE );
654}
655
656/*!\internal
657
658 \overload
659
660 The version of resolveProperty that is used by moc generated code
661*/
662
663int QMetaObject::resolveProperty( int index ) const
664{
665 if ( !superclass )
666 return -1;
667 const QMetaProperty* p = d->propData + ( index - propertyOffset() );
668 return superclass->findProperty( p->n, TRUE );
669}
670
671
672/*!
673 Returns a list with the names of all this class's properties.
674
675 If \a super is TRUE, inherited properties are included.
676
677 \sa property()
678*/
679QStrList QMetaObject::propertyNames( bool super ) const
680{
681 QStrList l( FALSE );
682
683 if ( superclass && super ) {
684 QStrList sl = superclass->propertyNames( super );
685 for ( QStrListIterator slit( sl ); slit.current(); ++slit )
686 l.append( slit.current() );
687 }
688
689 for( int i = 0; i < d->numPropData; ++i ) {
690 if ( d->propData[i].isValid() )
691 l.append( d->propData[i].name() );
692 }
693
694 return l;
695}
696
697/*!
698 Returns a list with the names of all this class's signals.
699
700 If \a super is TRUE, inherited signals are included.
701*/
702QStrList QMetaObject::signalNames( bool super ) const
703{
704 QStrList l( FALSE );
705 int n = numSignals( super );
706 for( int i = 0; i < n; ++i ) {
707 l.append( signal(i, super)->name );
708 }
709 return l;
710}
711
712/*!
713 Returns a list with the names of all this class's slots.
714
715 If \a super is TRUE, inherited slots are included.
716
717 \sa numSlots()
718*/
719QStrList QMetaObject::slotNames( bool super ) const
720{
721 QStrList l( FALSE );
722 int n = numSlots( super );
723 for( int i = 0; i < n; ++i )
724 l.append( slot( i, super)->name );
725 return l;
726}
727
728/*!\internal
729
730 */
731
732int QMetaObject::numEnumerators( bool super ) const
733{
734 int n = 0;
735 if ( superclass && super )
736 n += superclass->numEnumerators( super );
737 return n + d->numEnumData;
738}
739
740/*!\internal
741
742 */
743QStrList QMetaObject::enumeratorNames( bool super ) const
744{
745 QStrList l( FALSE );
746
747 if ( superclass && super ) {
748 QStrList sl = superclass->enumeratorNames( super );
749 for ( QStrListIterator slit( sl ); slit.current(); ++slit )
750 l.append( slit.current() );
751 }
752
753 for( int i = 0; i < d->numEnumData; ++i ) {
754 if ( d->enumData[i].items )
755 l.append( d->enumData[i].name );
756 }
757
758 return l;
759}
760
761/*!\internal
762 */
763const QMetaEnum* QMetaObject::enumerator( const char* name, bool super ) const
764{
765 for( int i = 0; i < d->numEnumData; ++i )
766 if ( qstrcmp( d->enumData[i].name, name ) == 0 )
767 return &(d->enumData[i]);
768 if ( !super || !superclass )
769 return 0;
770 return superclass->enumerator( name, super );
771}
772
773#endif // QT_NO_PROPERTIES
774
775
776/*!
777 Returns TRUE if this class inherits \a clname within the meta
778 object inheritance chain; otherwise returns FALSE.
779
780 (A class is considered to inherit itself.)
781*/
782bool QMetaObject::inherits( const char* clname ) const
783{
784 const QMetaObject *meta = this;
785 while ( meta ) {
786 if ( qstrcmp(clname, meta->className()) == 0 )
787 return TRUE;
788 meta = meta->superclass;
789 }
790 return FALSE;
791}
792
793/*! \internal */
794
795QMetaObject *QMetaObject::metaObject( const char *class_name )
796{
797 if ( !qt_metaobjects )
798 return 0;
799#ifdef QT_THREAD_SUPPORT
800 QMutexLocker( qt_global_mutexpool ?
801 qt_global_mutexpool->get( &qt_metaobjects ) : 0 );
802#endif // QT_THREAD_SUPPORT
803 QtStaticMetaObjectFunction func = (QtStaticMetaObjectFunction)qt_metaobjects->find( class_name );
804 if ( func )
805 return func();
806 return 0;
807}
808
809/*! \internal */
810bool QMetaObject::hasMetaObject( const char *class_name )
811{
812 if ( !qt_metaobjects )
813 return FALSE;
814#ifdef QT_THREAD_SUPPORT
815 QMutexLocker( qt_global_mutexpool ?
816 qt_global_mutexpool->get( &qt_metaobjects ) : 0 );
817#endif // QT_THREAD_SUPPORT
818 return !!qt_metaobjects->find( class_name );
819}
820
821#ifndef QT_NO_PROPERTIES
822/*! \internal
823
824### this functions will go away. It exists purely for the sake of meta
825### object code generated with Qt 3.1.0
826*/
827bool QMetaObject::qt_static_property( QObject* o, int id, int f, QVariant* v)
828{
829 if ( d->qt_static_property )
830 return d->qt_static_property( o, id, f, v );
831 else if ( o ) // compatibility
832 return o->qt_property( id, f, v );
833 else if ( superclass )
834 return superclass->qt_static_property( o, id, f, v );
835 switch ( f ) {
836 case 3: case 4: case 5:
837 return TRUE;
838 default:
839 return FALSE;
840 }
841}
842
843
844/*!
845 \class QMetaProperty qmetaobject.h
846
847 \brief The QMetaProperty class stores meta data about a property.
848
849 \ingroup objectmodel
850
851 Property meta data includes type(), name(), and whether a property
852 is writable(), designable() and stored().
853
854 The functions isSetType(), isEnumType() and enumKeys() provide
855 further information about a property's type. The conversion
856 functions keyToValue(), valueToKey(), keysToValue() and
857 valueToKeys() allow conversion between the integer representation
858 of an enumeration or set value and its literal representation.
859
860 Actual property values are set and received through QObject's set
861 and get functions. See QObject::setProperty() and
862 QObject::property() for details.
863
864 You receive meta property data through an object's meta object.
865 See QMetaObject::property() and QMetaObject::propertyNames() for
866 details.
867*/
868
869/*!
870 Returns the possible enumeration keys if this property is an
871 enumeration type (or a set type).
872
873 \sa isEnumType()
874*/
875QStrList QMetaProperty::enumKeys() const
876{
877 QStrList l( FALSE );
878 const QMetaEnum* ed = enumData;
879 if ( !enumData && meta )
880 ed = (*meta)->enumerator( t, TRUE );
881 if ( !ed )
882 return l;
883 if ( ed != 0 ) {
884 for( uint i = 0; i < ed->count; ++i ) {
885 uint j = 0;
886 while ( j < i &&
887 ed->items[j].value != ed->items[i].value )
888 ++j;
889 if ( i == j )
890 l.append( ed->items[i].key );
891 }
892 }
893 return l;
894}
895
896/*!
897 Converts the enumeration key \a key to its integer value.
898
899 For set types, use keysToValue().
900
901 \sa valueToKey(), isSetType(), keysToValue()
902*/
903int QMetaProperty::keyToValue( const char* key ) const
904{
905 const QMetaEnum* ed = enumData;
906 if ( !enumData && meta )
907 ed = (*meta)->enumerator( t, TRUE );
908 if ( !ed )
909 return -1;
910 for ( uint i = 0; i < ed->count; ++i ) {
911 if ( !qstrcmp( key, ed->items[i].key) )
912 return ed->items[i].value;
913 }
914 return -1;
915}
916
917/*!
918 Converts the enumeration value \a value to its literal key.
919
920 For set types, use valueToKeys().
921
922 \sa valueToKey(), isSetType(), valueToKeys()
923*/
924const char* QMetaProperty::valueToKey( int value ) const
925{
926 const QMetaEnum* ed = enumData;
927 if ( !enumData && meta )
928 ed = (*meta)->enumerator( t, TRUE );
929 if ( !ed )
930 return 0;
931 for ( uint i = 0; i < ed->count; ++i ) {
932 if ( value == ed->items[i].value )
933 return ed->items[i].key ;
934 }
935 return 0;
936}
937
938/*!
939 Converts the list of keys \a keys to their combined (OR-ed)
940 integer value.
941
942 \sa isSetType(), valueToKey(), keysToValue()
943*/
944int QMetaProperty::keysToValue( const QStrList& keys ) const
945{
946 const QMetaEnum* ed = enumData;
947 if ( !enumData && meta )
948 ed = (*meta)->enumerator( t, TRUE );
949 if ( !ed )
950 return -1;
951 int value = 0;
952 for ( QStrListIterator it( keys ); it.current(); ++it ) {
953 uint i;
954 for( i = ed->count; i > 0; --i ) {
955 if ( !qstrcmp( it.current(), ed->items[i-1].key) ) {
956 value |= ed->items[i-1].value;
957 break;
958 }
959 }
960 if ( i == 0 )
961 value |= -1;
962 }
963 return value;
964}
965
966/*!
967 Converts the set value \a value to a list of keys.
968
969 \sa isSetType(), valueToKey(), valueToKeys()
970*/
971QStrList QMetaProperty::valueToKeys( int value ) const
972{
973 QStrList keys;
974 const QMetaEnum* ed = enumData;
975 if ( !enumData && meta )
976 ed = (*meta)->enumerator( t, TRUE );
977 if ( !ed )
978 return keys;
979
980 int v = value;
981 for( uint i = ed->count; i > 0; --i ) {
982 int k = ed->items[i-1].value;
983 if ( ( k != 0 && (v & k) == k ) || ( k == value) ) {
984 v = v & ~k;
985 keys.append( ed->items[i-1].key );
986 }
987 }
988 return keys;
989}
990
991bool QMetaProperty::writable() const
992{
993 if ( !testFlags( Override ) || testFlags( Writable ) )
994 return testFlags( Writable );
995 const QMetaObject* mo = (*meta);
996 const QMetaProperty* parent = mo->resolveProperty( this );
997 return parent ? parent->writable() : FALSE;
998}
999
1000/*!\internal
1001 */
1002bool QMetaProperty::stdSet() const
1003{
1004 if ( !testFlags( Override ) || testFlags( Writable ) )
1005 return testFlags( StdSet );
1006 const QMetaObject* mo = (*meta);
1007 const QMetaProperty* parent = mo->resolveProperty( this );
1008 return parent ? parent->stdSet() : FALSE;
1009}
1010
1011/*!\internal
1012 */
1013int QMetaProperty::id() const
1014{
1015 return _id < 0 ? (*meta)->indexOfProperty( this, TRUE ) : _id;
1016}
1017
1018/*! \internal
1019*/
1020void QMetaProperty::clear()
1021{
1022 t = n = 0;
1023 meta = 0;
1024 enumData = 0;
1025 _id = -1;
1026 flags = 0;
1027}
1028
1029bool QMetaProperty::isValid() const
1030{
1031 if ( testFlags( UnresolvedEnum ) ) {
1032 if ( !enumData && (!meta || !(*meta)->enumerator( t, TRUE ) ) )
1033 return FALSE;
1034 }
1035 if ( !testFlags( Override ) || testFlags( Readable ) )
1036 return testFlags( Readable );
1037 const QMetaObject* mo = (*meta);
1038 const QMetaProperty* parent = mo->resolveProperty( this );
1039 return parent ? parent->isValid() : FALSE;
1040}
1041
1042bool QMetaProperty::isSetType() const
1043{
1044 const QMetaEnum* ed = enumData;
1045 if ( !enumData && meta )
1046 ed = (*meta)->enumerator( t, TRUE );
1047 return ( ed != 0 && ed->set );
1048}
1049
1050bool QMetaProperty::isEnumType() const
1051{
1052 return testFlags( EnumOrSet );
1053}
1054
1055
1056
1057/*!
1058 \fn const char* QMetaProperty::type() const
1059
1060 Returns the type of the property.
1061*/
1062
1063/*!
1064 \fn const char* QMetaProperty::name() const
1065
1066 Returns the name of the property.
1067*/
1068
1069/*!
1070 \fn bool QMetaProperty::writable() const
1071
1072 Returns TRUE if the property is writable; otherwise returns FALSE.
1073
1074*/
1075
1076/*! \fn bool QMetaProperty::isValid() const
1077
1078 \internal
1079
1080 Returns whether the property is valid.
1081*/
1082
1083/*!
1084 \fn bool QMetaProperty::isEnumType() const
1085
1086 Returns TRUE if the property's type is an enumeration value;
1087 otherwise returns FALSE.
1088
1089 \sa isSetType(), enumKeys()
1090*/
1091
1092/*!
1093 \fn bool QMetaProperty::isSetType() const
1094
1095 Returns TRUE if the property's type is an enumeration value that
1096 is used as set, i.e. if the enumeration values can be OR-ed
1097 together; otherwise returns FALSE. A set type is implicitly also
1098 an enum type.
1099
1100 \sa isEnumType(), enumKeys()
1101*/
1102
1103
1104/*! Returns TRUE if the property is designable for object \a o;
1105 otherwise returns FALSE.
1106
1107 If no object \a o is given, the function returns a static
1108 approximation.
1109 */
1110bool QMetaProperty::designable( QObject* o ) const
1111{
1112 if ( !isValid() || !writable() )
1113 return FALSE;
1114 if ( o ) {
1115 int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
1116 return idx >= 0 && o->qt_property( idx, 3, 0 );
1117 }
1118 if ( testFlags( DesignableOverride ) ) {
1119 const QMetaObject* mo = (*meta);
1120 const QMetaProperty* parent = mo->resolveProperty( this );
1121 return parent ? parent->designable() : FALSE;
1122 }
1123 return !testFlags( NotDesignable );
1124}
1125
1126/*!
1127 Returns TRUE if the property is scriptable for object \a o;
1128 otherwise returns FALSE.
1129
1130 If no object \a o is given, the function returns a static
1131 approximation.
1132 */
1133bool QMetaProperty::scriptable( QObject* o ) const
1134{
1135 if ( o ) {
1136 int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
1137 return idx >= 0 && o->qt_property( idx, 4, 0 );
1138 }
1139 if ( testFlags( ScriptableOverride ) ) {
1140 const QMetaObject* mo = (*meta);
1141 const QMetaProperty* parent = mo->resolveProperty( this );
1142 return parent ? parent->scriptable() : FALSE;
1143 }
1144 return !testFlags( NotScriptable );
1145}
1146
1147/*!
1148 Returns TRUE if the property shall be stored for object \a o;
1149 otherwise returns FALSE.
1150
1151 If no object \a o is given, the function returns a static
1152 approximation.
1153 */
1154bool QMetaProperty::stored( QObject* o ) const
1155{
1156 if ( !isValid() || !writable() )
1157 return FALSE;
1158 if ( o ) {
1159 int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
1160 return idx >= 0 && o->qt_property( idx, 5, 0 );
1161 }
1162 if ( testFlags( StoredOverride ) ) {
1163 const QMetaObject* mo = (*meta);
1164 const QMetaProperty* parent = mo->resolveProperty( this );
1165 return parent ? parent->stored() : FALSE;
1166 }
1167 return !testFlags( NotStored );
1168}
1169
1170
1171/*!
1172 Tries to reset the property for object \a o with a reset method.
1173 On success, returns TRUE; otherwise returns FALSE.
1174
1175 Reset methods are optional, usually only a few properties support
1176 them.
1177*/
1178bool QMetaProperty::reset( QObject* o ) const
1179{
1180 if ( !o )
1181 return FALSE;
1182 int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
1183 if ( idx < 0 )
1184 return 0;
1185 return o->qt_property( idx, 2, 0 );
1186}
1187
1188
1189/*! \enum QMetaProperty::Flags
1190
1191 \internal
1192*/
1193
1194#endif // QT_NO_PROPERTIES
1195
1196/*
1197 * QMetaObjectCleanUp is used as static global object in the moc-generated cpp
1198 * files and deletes the QMetaObject provided with setMetaObject. It sets the
1199 * QObject reference to the metaObj to NULL when it is destroyed.
1200 */
1201QMetaObjectCleanUp::QMetaObjectCleanUp( const char *mo_name, QtStaticMetaObjectFunction func )
1202 : metaObject( 0 )
1203{
1204#ifdef QT_THREAD_SUPPORT
1205 QMutexLocker( qt_global_mutexpool ?
1206 qt_global_mutexpool->get( &qt_metaobjects ) : 0 );
1207#endif // QT_THREAD_SUPPORT
1208 if ( !qt_metaobjects )
1209 qt_metaobjects = new QAsciiDict<void>( 257 );
1210 qt_metaobjects->insert( mo_name, (void*)func );
1211
1212 qt_metaobjects_count++;
1213}
1214
1215QMetaObjectCleanUp::QMetaObjectCleanUp()
1216 : metaObject( 0 )
1217{
1218}
1219
1220/*! \fn bool QMetaProperty::testFlags( uint f ) const
1221 \internal
1222*/
1223
1224QMetaObjectCleanUp::~QMetaObjectCleanUp()
1225{
1226#ifdef QT_THREAD_SUPPORT
1227 QMutexLocker( qt_global_mutexpool ?
1228 qt_global_mutexpool->get( &qt_metaobjects ) : 0 );
1229#endif // QT_THREAD_SUPPORT
1230 if ( !--qt_metaobjects_count ) {
1231 delete qt_metaobjects;
1232 qt_metaobjects = 0;
1233 }
1234 if ( metaObject ) {
1235 delete *metaObject;
1236 *metaObject = 0;
1237 metaObject = 0;
1238 }
1239}
1240
1241void QMetaObjectCleanUp::setMetaObject( QMetaObject *&mo )
1242{
1243#if defined(QT_CHECK_RANGE)
1244 if ( metaObject )
1245 qWarning( "QMetaObjectCleanUp::setMetaObject: Double use of QMetaObjectCleanUp!" );
1246#endif
1247 metaObject = &mo;
1248}
Note: See TracBrowser for help on using the repository browser.