PageRenderTime 129ms CodeModel.GetById 20ms RepoModel.GetById 7ms app.codeStats 0ms

/src/_ref15/kernel/qmetaobject.cpp

https://bitbucket.org/sigman/xte_lib
C++ | 1871 lines | 1130 code | 136 blank | 605 comment | 343 complexity | 96e00cb3908d48bfd2baab99e3d9602a MD5 | raw file
Possible License(s): MIT, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 1992-2004 Trolltech AS. All rights reserved.
  4. **
  5. ** This file is part of the core module of the Qt Toolkit.
  6. **
  7. ** Licensees holding valid Qt Preview licenses may use this file in
  8. ** accordance with the Qt Preview License Agreement provided with the
  9. ** Software.
  10. **
  11. ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
  12. ** information about Qt Commercial License Agreements.
  13. **
  14. ** Contact info@trolltech.com if any conditions of this licensing are
  15. ** not clear to you.
  16. **
  17. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  18. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. **
  20. ****************************************************************************/
  21. #include "qmetaobject.h"
  22. #include "qobject.h"
  23. #include <qcoreapplication.h>
  24. #include <qdatastream.h>
  25. #include <qstringlist.h>
  26. #include <qcorevariant.h>
  27. #include <qhash.h>
  28. #include <ctype.h>
  29. /*!
  30. \class QMetaObject qmetaobject.h
  31. \brief The QMetaObject class contains meta information about Qt
  32. objects.
  33. \ingroup objectmodel
  34. The Qt Meta Object System in Qt is responsible for the signals and
  35. slots inter-object communication mechanism, runtime type
  36. information, and the Qt property system. A single QMetaObject
  37. instance is created for each QObject subclass that is used in an
  38. application, and this instance stores all the meta information for
  39. the QObject subclass.
  40. This class is not normally required for application programming,
  41. but it is useful if you write meta applications, such as scripting
  42. engines or GUI builders.
  43. The functions you are most likely to find useful are these:
  44. \list
  45. \i className() returns the name of a class.
  46. \i superClass() returns the super-class's meta object.
  47. \i slotCount(), slot(), signalCount(), and signal() provide information
  48. about a class's signals and slots.
  49. \i enumeratorCount() and enumerator() provide information about
  50. a class's enumerators.
  51. \i propertyCount() and property() provide information about a
  52. class's properties.
  53. \endlist
  54. The index functions indexOfSlot(), indexOfSignal(),
  55. indexOfEnumerator(), and indexOfProperty() map names of member
  56. functions, enumerators, or properties to indices in the meta
  57. object. For example, Qt uses indexOfSignal() and indexOfSlot()
  58. internally when you connect a signal to a slot.
  59. Classes can also have a list of name--value pairs of additional
  60. \link QMetaClassInfo class information\endlink. The number of
  61. pairs is returned by classInfoCount(), single pairs are returned
  62. by classInfo(), and you can search for pairs with
  63. indexOfClassInfo().
  64. \sa \link moc.html moc (Meta QObject Compiler)\endlink
  65. */
  66. /*!
  67. \enum QMetaObject::Call
  68. \internal
  69. \value InvokeSlot
  70. \value EmitSignal
  71. \value ReadProperty
  72. \value WriteProperty
  73. \value ResetProperty
  74. \value QueryPropertyDesignable
  75. \value QueryPropertyScriptable
  76. \value QueryPropertyStored
  77. \value QueryPropertyEditable
  78. */
  79. /*!
  80. \fn void QMetaObject::activate(QObject *obj, int signal_index, void **argv)
  81. \internal
  82. */
  83. /*!
  84. \enum QMetaMember::Access
  85. \internal
  86. */
  87. // do not touch without touching the moc as well
  88. enum ProperyFlags {
  89. Invalid = 0x00000000,
  90. Readable = 0x00000001,
  91. Writable = 0x00000002,
  92. Resetable = 0x00000004,
  93. EnumOrFlag = 0x00000008,
  94. StdCppSet = 0x00000100,
  95. Override = 0x00000200,
  96. Designable = 0x00001000,
  97. ResolveDesignable = 0x00002000,
  98. Scriptable = 0x00004000,
  99. ResolveScriptable = 0x00008000,
  100. Stored = 0x00010000,
  101. ResolveStored = 0x00020000,
  102. Editable = 0x00040000,
  103. ResolveEditable = 0x00080000
  104. };
  105. enum FunctionFlags {
  106. AccessPrivate = 0x01,
  107. AccessPublic = 0x02,
  108. AccessProtected = 0x04,
  109. AccessMask = 0x07, //mask
  110. Compatability = QMetaMember::Compatability,
  111. Cloned = QMetaMember::Cloned
  112. };
  113. struct QMetaObjectPrivate
  114. {
  115. int revision;
  116. int className;
  117. int classInfoCount, classInfoData;
  118. int signalCount, signalData;
  119. int slotCount, slotData;
  120. int propertyCount, propertyData;
  121. int enumeratorCount, enumeratorData;
  122. };
  123. static inline const QMetaObjectPrivate *priv(const uint* data)
  124. { return reinterpret_cast<const QMetaObjectPrivate*>(data); }
  125. /*!
  126. \fn const char *QMetaObject::className() const
  127. Returns the class name.
  128. \sa superClass()
  129. */
  130. /*!
  131. \fn QMetaObject *QMetaObject::superClass() const
  132. Returns the meta object of the super-class, or 0 if there is no
  133. such object.
  134. */
  135. /*!
  136. \internal
  137. Returns \a obj if object \a obj inherits from this meta
  138. object; otherwise returns 0.
  139. */
  140. QObject *QMetaObject::cast(const QObject *obj) const
  141. {
  142. if (obj) {
  143. const QMetaObject *m = obj->metaObject();
  144. do {
  145. if (m == this)
  146. return const_cast<QObject*>(obj);
  147. } while ((m = m->d.superdata));
  148. }
  149. return 0;
  150. }
  151. #ifndef QT_NO_TRANSLATION
  152. /*!
  153. \internal
  154. Forwards a tr() call from the \c Q_OBJECT macro to the QApplication.
  155. */
  156. QString QMetaObject::tr(const char *s, const char *c) const
  157. {
  158. if (QCoreApplication::instance())
  159. return QCoreApplication::instance()->translate(d.stringdata, s, c, QCoreApplication::DefaultCodec);
  160. else
  161. return QString::fromLatin1(s);
  162. }
  163. /*!
  164. \internal
  165. Forwards a trUtf8() call from the \c Q_OBJECT macro to the
  166. QApplication.
  167. */
  168. QString QMetaObject::trUtf8(const char *s, const char *c) const
  169. {
  170. if (QCoreApplication::instance())
  171. return QCoreApplication::instance()->translate(d.stringdata, s, c, QCoreApplication::UnicodeUTF8);
  172. else
  173. return QString::fromUtf8(s);
  174. }
  175. #endif // QT_NO_TRANSLATION
  176. /*!
  177. Returns the slot offset for this class; i.e. the index position of
  178. this class's first slot. The offset is the sum of all the slots in
  179. the class's super-classes (which is always positive since QObject
  180. has the deleteLater() slot).
  181. */
  182. int QMetaObject::slotOffset() const
  183. {
  184. int offset = 0;
  185. const QMetaObject *m = d.superdata;
  186. while (m) {
  187. offset += priv(m->d.data)->slotCount;
  188. m = m->d.superdata;
  189. }
  190. return offset;
  191. }
  192. /*!
  193. Returns the signal offset for this class; i.e. the index position
  194. of this class's first signal. The offset is the sum of all the
  195. signals in the class's super-classes (which is always positive
  196. since QObject has the slots destroyed() and destroyed(QObject*)).
  197. */
  198. int QMetaObject::signalOffset() const
  199. {
  200. int offset = 0;
  201. const QMetaObject *m = d.superdata;
  202. while (m) {
  203. offset += priv(m->d.data)->signalCount;
  204. m = m->d.superdata;
  205. }
  206. return offset;
  207. }
  208. /*!
  209. Returns the enumerator offset for this class; i.e. the index
  210. position of this class's first enumerator. If the class has no
  211. super-classes with enumerators, the offset is 0; otherwise the
  212. offset is the sum of all the enumerators in the class's
  213. super-classes.
  214. */
  215. int QMetaObject::enumeratorOffset() const
  216. {
  217. int offset = 0;
  218. const QMetaObject *m = d.superdata;
  219. while (m) {
  220. offset += priv(m->d.data)->enumeratorCount;
  221. m = m->d.superdata;
  222. }
  223. return offset;
  224. }
  225. /*!
  226. Returns the property offset for this class; i.e. the index
  227. position of this class's first property. The offset is the sum of
  228. all the properties in the class's super-classes (which is always
  229. positive since QObject has the name() property).
  230. */
  231. int QMetaObject::propertyOffset() const
  232. {
  233. int offset = 0;
  234. const QMetaObject *m = d.superdata;
  235. while (m) {
  236. offset += priv(m->d.data)->propertyCount;
  237. m = m->d.superdata;
  238. }
  239. return offset;
  240. }
  241. /*!
  242. Returns the class information offset for this class; i.e. the
  243. index position of this class's first class information item. If
  244. the class has no super-classes with class information, the offset
  245. is 0; otherwise the offset is the sum of all the class information
  246. items in the class's super-classes.
  247. */
  248. int QMetaObject::classInfoOffset() const
  249. {
  250. int offset = 0;
  251. const QMetaObject *m = d.superdata;
  252. while (m) {
  253. offset += priv(m->d.data)->classInfoCount;
  254. m = m->d.superdata;
  255. }
  256. return offset;
  257. }
  258. /*!
  259. Returns the number of slots in this class.
  260. \sa slot()
  261. */
  262. int QMetaObject::slotCount() const
  263. {
  264. int n = priv(d.data)->slotCount;
  265. const QMetaObject *m = d.superdata;
  266. while (m) {
  267. n += priv(m->d.data)->slotCount;
  268. m = m->d.superdata;
  269. }
  270. return n;
  271. }
  272. /*!
  273. Returns the number of signals in this class.
  274. \sa signal()
  275. */
  276. int QMetaObject::signalCount() const
  277. {
  278. int n = priv(d.data)->signalCount;
  279. const QMetaObject *m = d.superdata;
  280. while (m) {
  281. n += priv(m->d.data)->signalCount;
  282. m = m->d.superdata;
  283. }
  284. return n;
  285. }
  286. /*!
  287. Returns the number of enumerators in this class.
  288. \sa enumerator()
  289. */
  290. int QMetaObject::enumeratorCount() const
  291. {
  292. int n = priv(d.data)->enumeratorCount;
  293. const QMetaObject *m = d.superdata;
  294. while (m) {
  295. n += priv(m->d.data)->enumeratorCount;
  296. m = m->d.superdata;
  297. }
  298. return n;
  299. }
  300. /*!
  301. Returns the number of properties in this class.
  302. \sa property()
  303. */
  304. int QMetaObject::propertyCount() const
  305. {
  306. int n = priv(d.data)->propertyCount;
  307. const QMetaObject *m = d.superdata;
  308. while (m) {
  309. n += priv(m->d.data)->propertyCount;
  310. m = m->d.superdata;
  311. }
  312. return n;
  313. }
  314. /*!
  315. Returns the number of items of class information in this class.
  316. */
  317. int QMetaObject::classInfoCount() const
  318. {
  319. int n = priv(d.data)->classInfoCount;
  320. const QMetaObject *m = d.superdata;
  321. while (m) {
  322. n += priv(m->d.data)->classInfoCount;
  323. m = m->d.superdata;
  324. }
  325. return n;
  326. }
  327. /*!
  328. Finds \a slot and returns its index; otherwise returns -1.
  329. \sa slot(), slotCount()
  330. */
  331. int QMetaObject::indexOfSlot(const char *slot) const
  332. {
  333. int i = -1;
  334. const QMetaObject *m = this;
  335. while (m && i < 0) {
  336. for (i = priv(m->d.data)->slotCount-1; i >= 0; --i)
  337. if (strcmp(slot, m->d.stringdata
  338. + m->d.data[priv(m->d.data)->slotData + 5*i]) == 0) {
  339. i += m->slotOffset();
  340. break;
  341. }
  342. m = m->d.superdata;
  343. }
  344. return i;
  345. }
  346. /*!
  347. Finds \a signal and returns its index; otherwise returns -1.
  348. \sa signal(), signalCount()
  349. */
  350. int QMetaObject::indexOfSignal(const char *signal) const
  351. {
  352. int i = -1;
  353. const QMetaObject *m = this;
  354. while (m && i < 0) {
  355. for (i = priv(m->d.data)->signalCount-1; i >= 0; --i)
  356. if (strcmp(signal, m->d.stringdata
  357. + m->d.data[priv(m->d.data)->signalData + 5*i]) == 0) {
  358. i += m->signalOffset();
  359. break;
  360. }
  361. m = m->d.superdata;
  362. }
  363. #ifndef QT_NO_DEBUG
  364. if (i >= 0 && m->d.superdata) {
  365. int conflict = m->d.superdata->indexOfSignal(signal);
  366. if (conflict >= 0)
  367. qWarning("QMetaObject::indexOfSignal:%s: Conflict with %s::%s",
  368. m->d.stringdata, m->d.superdata->d.stringdata, signal);
  369. }
  370. #endif
  371. return i;
  372. }
  373. /*!
  374. Finds enumerator \a name and returns its index; otherwise returns
  375. -1.
  376. \sa enumerator(), enumeratorCount()
  377. */
  378. int QMetaObject::indexOfEnumerator(const char *name) const
  379. {
  380. int i = -1;
  381. const QMetaObject *m = this;
  382. int scope = 0;
  383. const char *qualified_name = name;
  384. const char *s = name;
  385. while (*s && *s != ':')
  386. ++s;
  387. if (*s && *(s+1)==':') {
  388. scope = s - name;
  389. name += scope + 2;
  390. }
  391. while (m && i < 0) {
  392. for (i = priv(m->d.data)->enumeratorCount-1; i >= 0; --i) {
  393. if ((!scope || strncmp(qualified_name, m->d.stringdata, scope) == 0)
  394. && strcmp(name, m->d.stringdata
  395. + m->d.data[priv(m->d.data)->enumeratorData + 4*i]) == 0) {
  396. i += m->enumeratorOffset();
  397. break;
  398. }
  399. }
  400. m = m->d.superdata;
  401. }
  402. return i;
  403. }
  404. /*!
  405. Finds property \a name and returns its index; otherwise returns
  406. -1.
  407. \sa property(), propertyCount()
  408. */
  409. int QMetaObject::indexOfProperty(const char *name) const
  410. {
  411. int i = -1;
  412. const QMetaObject *m = this;
  413. while (m && i < 0) {
  414. for (i = priv(m->d.data)->propertyCount-1; i >= 0; --i)
  415. if (strcmp(name, m->d.stringdata
  416. + m->d.data[priv(m->d.data)->propertyData + 3*i]) == 0) {
  417. i += m->propertyOffset();
  418. break;
  419. }
  420. m = m->d.superdata;
  421. }
  422. return i;
  423. }
  424. /*!
  425. Finds class information item \a name and returns its index;
  426. otherwise returns -1.
  427. \sa classInfo(), classInfoCount()
  428. */
  429. int QMetaObject::indexOfClassInfo(const char *name) const
  430. {
  431. int i = -1;
  432. const QMetaObject *m = this;
  433. while (m && i < 0) {
  434. for (i = priv(m->d.data)->classInfoCount-1; i >= 0; --i)
  435. if (strcmp(name, m->d.stringdata
  436. + m->d.data[priv(d.data)->classInfoData + 2*i]) == 0) {
  437. i += m->classInfoOffset();
  438. break;
  439. }
  440. m = m->d.superdata;
  441. }
  442. return i;
  443. }
  444. /*!
  445. Returns the meta data for the slot with the given \a index.
  446. \sa indexOfSlot()
  447. */
  448. QMetaMember QMetaObject::slot(int index) const
  449. {
  450. int i = index;
  451. i -= slotOffset();
  452. if (i < 0 && d.superdata)
  453. return d.superdata->slot(index);
  454. QMetaMember result;
  455. if (i >= 0 && i <= priv(d.data)->slotCount) {
  456. result.mobj = this;
  457. result.handle = priv(d.data)->slotData + 5*i;
  458. }
  459. return result;
  460. }
  461. /*!
  462. Returns the meta data for the signal with the given \a index.
  463. \sa indexOfSignal()
  464. */
  465. QMetaMember QMetaObject::signal(int index) const
  466. {
  467. int i = index;
  468. i -= signalOffset();
  469. if (i < 0 && d.superdata)
  470. return d.superdata->signal(index);
  471. QMetaMember result;
  472. if (i >= 0 && i <= priv(d.data)->signalCount) {
  473. result.mobj = this;
  474. result.handle = priv(d.data)->signalData + 5*i;
  475. }
  476. return result;
  477. }
  478. /*!
  479. Returns the meta data for the enumerator with the given \a index.
  480. \sa indexOfEnumerator()
  481. */
  482. QMetaEnum QMetaObject::enumerator(int index) const
  483. {
  484. int i = index;
  485. i -= enumeratorOffset();
  486. if (i < 0 && d.superdata)
  487. return d.superdata->enumerator(index);
  488. QMetaEnum result;
  489. if (i >= 0 && i <= priv(d.data)->enumeratorCount) {
  490. result.mobj = this;
  491. result.handle = priv(d.data)->enumeratorData + 4*i;
  492. }
  493. return result;
  494. }
  495. /*!
  496. Returns the meta data for the property with the given \a index.
  497. \sa indexOfProperty()
  498. */
  499. QMetaProperty QMetaObject::property(int index) const
  500. {
  501. int i = index;
  502. i -= propertyOffset();
  503. if (i < 0 && d.superdata)
  504. return d.superdata->property(index);
  505. QMetaProperty result;
  506. if (i >= 0 && i <= priv(d.data)->propertyCount) {
  507. int handle = priv(d.data)->propertyData + 3*i;
  508. int flags = d.data[handle + 2];
  509. const char *name = d.stringdata + d.data[handle];
  510. const char *type = d.stringdata + d.data[handle + 1];
  511. if ((flags & Override) && d.superdata){
  512. result = property(d.superdata->indexOfProperty(name));
  513. if (qstrcmp(result.typeName(), type)) // type missmatch, no override
  514. ::memset(&result, 0, sizeof(QMetaProperty));
  515. }
  516. if (flags & EnumOrFlag) {
  517. result.menum = enumerator(indexOfEnumerator(type));
  518. }
  519. if (flags & Readable) {
  520. result.mobj[ReadProperty] = this;
  521. result.idx[ReadProperty] = i;
  522. }
  523. if (flags & Writable) {
  524. result.mobj[WriteProperty] = this;
  525. result.idx[WriteProperty] = i;
  526. }
  527. if (flags & Resetable) {
  528. result.mobj[ResetProperty] = this;
  529. result.idx[ResetProperty] = i;
  530. }
  531. if ((flags & ResolveDesignable) == 0) {
  532. result.mobj[QueryPropertyDesignable] = this;
  533. result.idx[QueryPropertyDesignable] = i;
  534. }
  535. if ((flags & ResolveScriptable) == 0) {
  536. result.mobj[QueryPropertyScriptable] = this;
  537. result.idx[QueryPropertyScriptable] = i;
  538. }
  539. if ((flags & ResolveStored) == 0) {
  540. result.mobj[QueryPropertyStored] = this;
  541. result.idx[QueryPropertyStored] = i;
  542. }
  543. if ((flags & ResolveEditable) == 0) {
  544. result.mobj[QueryPropertyEditable] = this;
  545. result.idx[QueryPropertyEditable] = i;
  546. }
  547. }
  548. return result;
  549. }
  550. /*!
  551. Returns the meta data for the item of class information with the
  552. given \a index.
  553. \sa indexOfClassInfo()
  554. */
  555. QMetaClassInfo QMetaObject::classInfo(int index) const
  556. {
  557. int i = index;
  558. i -= classInfoOffset();
  559. if (i < 0 && d.superdata)
  560. return d.superdata->classInfo(index);
  561. QMetaClassInfo result;
  562. if (i >= 0 && i <= priv(d.data)->classInfoCount) {
  563. result.mobj = this;
  564. result.handle = priv(d.data)->classInfoData + 2*i;
  565. }
  566. return result;
  567. }
  568. /*!
  569. Returns true if the \a signal and \a member arguments are
  570. compatible; otherwise returns false.
  571. Both \a signal and \a member are expected to be normalized.
  572. \sa normalizedSignature()
  573. */
  574. bool QMetaObject::checkConnectArgs(const char *signal, const char *member)
  575. {
  576. const char *s1 = signal;
  577. const char *s2 = member;
  578. while (*s1++ != '(') { } // scan to first '('
  579. while (*s2++ != '(') { }
  580. if (*s2 == ')' || qstrcmp(s1,s2) == 0) // member has no args or
  581. return true; // exact match
  582. int s1len = strlen(s1);
  583. int s2len = strlen(s2);
  584. if (s2len < s1len && strncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==',')
  585. return true; // member has less args
  586. return false;
  587. }
  588. static inline bool is_ident_char(char s)
  589. {
  590. return ((s >= 'a' && s <= 'z')
  591. || (s >= 'A' && s <= 'Z')
  592. || (s >= '0' && s <= '9')
  593. || s == '_'
  594. );
  595. }
  596. static inline bool is_space(char s)
  597. {
  598. return (s == ' ' || s == '\t');
  599. }
  600. // WARNING: a copy of this function is in moc.cpp
  601. static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixScope = true, bool adjustConst = true)
  602. {
  603. int len = e - t;
  604. if (strncmp("void", t, len) == 0)
  605. return QByteArray();
  606. /*
  607. Convert 'char const *' into 'const char *'. Start at index 1,
  608. not 0, because 'const char *' is already OK.
  609. */
  610. QByteArray constbuf;
  611. for (int i = 1; i < len; i++) {
  612. if (t[i] == 'c' &&
  613. strncmp(t + i + 1, "onst", 4) == 0) {
  614. constbuf = QByteArray(t, len);
  615. if (is_space(t[i-1]))
  616. constbuf.remove(i-1, 6);
  617. else
  618. constbuf.remove(i, 5);
  619. constbuf.prepend("const ");
  620. t = constbuf.data();
  621. e = constbuf.data() + constbuf.length();
  622. break;
  623. }
  624. /*
  625. We musn't convert 'char * const *' into 'const char **'
  626. and we must beware of 'Bar<const Bla>'.
  627. */
  628. if (t[i] == '&' || t[i] == '*' ||t[i] == '<')
  629. break;
  630. }
  631. if (adjustConst && e > t + 6 && strncmp("const ", t, 6) == 0) {
  632. if (*(e-1) == '&') { // treat const reference as value
  633. t += 6;
  634. --e;
  635. } else if (is_ident_char(*(e-1))) { // treat const value as value
  636. t += 6;
  637. }
  638. }
  639. QByteArray result;
  640. result.reserve(len);
  641. // some type substitutions for 'unsigned x'
  642. if (strncmp("unsigned ", t, 9) == 0) {
  643. if (strncmp("int", t+9, 3) == 0) {
  644. t += 9+3;
  645. result += "uint";
  646. } else if (strncmp("long", t+9, 4) == 0) {
  647. t += 9+4;
  648. result += "ulong";
  649. }
  650. }
  651. while (t != e) {
  652. char c = *t++;
  653. if (fixScope && c == ':' && *t == ':' ) {
  654. ++t;
  655. c = *t++;
  656. int i = result.size() - 1;
  657. while (i >= 0 && is_ident_char(result.at(i)))
  658. --i;
  659. result.resize(i + 1);
  660. }
  661. result += c;
  662. if (c == '<') {
  663. //template recursion
  664. const char* tt = t;
  665. int templdepth = 1;
  666. while (t != e) {
  667. c = *t++;
  668. if (c == '<')
  669. ++templdepth;
  670. if (c == '>')
  671. --templdepth;
  672. if (templdepth == 0) {
  673. result += normalizeTypeInternal(tt, t-1, fixScope, false);
  674. result += c;
  675. if (*t == '>')
  676. result += ' '; // avoid >>
  677. break;
  678. }
  679. }
  680. }
  681. }
  682. return result;
  683. }
  684. /*!
  685. Normalizes the signature of the given \a member.
  686. Qt uses normalized signatures to decide whether two given signals
  687. and slots are compatible. Normalization reduces whitespace to a
  688. minimum, moves 'const' to the front where appropriate, removes
  689. 'const' from value types and replaces const references with
  690. values.
  691. \sa checkConnectArgs()
  692. */
  693. QByteArray QMetaObject::normalizedSignature(const char *member)
  694. {
  695. const char *s = member;
  696. if (!s || !*s)
  697. return "";
  698. int len = strlen(s);
  699. char stackbuf[64];
  700. char *buf = (len >= 64 ? new char[len+1] : stackbuf);
  701. char *d = buf;
  702. char last = 0;
  703. while(*s && is_space(*s))
  704. s++;
  705. while (*s) {
  706. while (*s && !is_space(*s))
  707. last = *d++ = *s++;
  708. while (*s && is_space(*s))
  709. s++;
  710. if (*s && is_ident_char(*s) && is_ident_char(last))
  711. last = *d++ = ' ';
  712. }
  713. *d = '\0';
  714. d = buf;
  715. QByteArray result;
  716. result.reserve(len);
  717. int argdepth = 0;
  718. int templdepth = 0;
  719. while (*d) {
  720. if (argdepth == 1) {
  721. const char *t = d;
  722. while (*d&& (templdepth
  723. || (*d != ',' && *d != ')'))) {
  724. if (*d == '<')
  725. ++templdepth;
  726. if (*d == '>')
  727. --templdepth;
  728. d++;
  729. }
  730. result += normalizeTypeInternal(t, d);
  731. }
  732. if (*d == '(')
  733. ++argdepth;
  734. if (*d == ')')
  735. --argdepth;
  736. result += *d++;
  737. }
  738. if (buf != stackbuf)
  739. delete [] buf;
  740. return result;
  741. }
  742. /*!
  743. \class QMetaMember qmetaobject.h
  744. \brief The QMetaMember class provides meta data about a signal or
  745. slot member function.
  746. \ingroup objectmodel
  747. A QMetaMember has a signature(), a list of parameters(), a
  748. return typeName(), a tag(), and an access() specifier.
  749. */
  750. /*!
  751. \enum QMetaMember::Attributes
  752. \value Compatability
  753. \value Cloned
  754. */
  755. /*!
  756. \fn QMetaMember::QMetaMember()
  757. \internal
  758. */
  759. /*!
  760. Returns the signature of this member.
  761. */
  762. const char *QMetaMember::signature() const
  763. {
  764. if (!mobj)
  765. return 0;
  766. return mobj->d.stringdata + mobj->d.data[handle];
  767. }
  768. /*!
  769. Returns a comma-separated list of parameter names.
  770. */
  771. const char *QMetaMember::parameters() const
  772. {
  773. if (!mobj)
  774. return 0;
  775. return mobj->d.stringdata + mobj->d.data[handle + 1];
  776. }
  777. /*!
  778. Returns the return type of this member, or an empty string if the
  779. return type is \e void.
  780. */
  781. const char *QMetaMember::typeName() const
  782. {
  783. if (!mobj)
  784. return 0;
  785. return mobj->d.stringdata + mobj->d.data[handle + 2];
  786. }
  787. /*!
  788. Returns the tag associated with this member.
  789. */
  790. const char *QMetaMember::tag() const
  791. {
  792. if (!mobj)
  793. return 0;
  794. return mobj->d.stringdata + mobj->d.data[handle + 3];
  795. }
  796. /*! \internal */
  797. int QMetaMember::attributes() const
  798. {
  799. if (!mobj)
  800. return false;
  801. return mobj->d.data[handle + 4] & ~AccessMask;
  802. }
  803. /*!
  804. Returns the access specification of this member: private,
  805. protected, or public. Signals are always protected.
  806. */
  807. QMetaMember::Access QMetaMember::access() const
  808. {
  809. if (!mobj)
  810. return Private;
  811. switch(mobj->d.data[handle + 4] & AccessMask) {
  812. case AccessPublic:
  813. return Public;
  814. case AccessPrivate:
  815. return Private;
  816. case AccessProtected:
  817. return Protected;
  818. default:
  819. break;
  820. }
  821. return Private;
  822. }
  823. /*!
  824. \class QMetaEnum qmetaobject.h
  825. \brief The QMetaEnum class provides meta data about an enumerator.
  826. \ingroup objectmodel
  827. Use name() for the enumerator's name. The enumerator's keys (names
  828. of each enumerated item) are returned by key(); use keyCount() to find
  829. the number of keys. isFlag() returns whether the enumerator is
  830. meant to be used as a flag, meaning that its values can be combined
  831. using the OR operator.
  832. The conversion functions keyToValue(), valueToKey(), keysToValue(),
  833. and valueToKeys() allow conversion between the integer
  834. representation of an enumeration or set value and its literal
  835. representation. The scope() function returns the class scope this
  836. enumerator was declared in.
  837. */
  838. /*!
  839. \fn bool QMetaEnum::isValid() const
  840. Returns true if this enum is valid (has a name); otherwise returns
  841. false.
  842. */
  843. /*!
  844. \fn QMetaEnum::QMetaEnum()
  845. \internal
  846. */
  847. /*!
  848. Returns the name of the enumerator.
  849. \sa isValid()
  850. */
  851. const char* QMetaEnum::name() const
  852. {
  853. if (!mobj)
  854. return 0;
  855. return mobj->d.stringdata + mobj->d.data[handle];
  856. }
  857. /*!
  858. Returns the number of keys.
  859. \sa key()
  860. */
  861. int QMetaEnum::keyCount() const
  862. {
  863. if (!mobj)
  864. return 0;
  865. return mobj->d.data[handle + 2];
  866. }
  867. /*!
  868. Returns the key with the given \a index, or 0 if no such key exists.
  869. \sa keyCount() value()
  870. */
  871. const char *QMetaEnum::key(int index) const
  872. {
  873. if (!mobj)
  874. return 0;
  875. int count = mobj->d.data[handle + 2];
  876. int data = mobj->d.data[handle + 3];
  877. if (index >= 0 && index < count)
  878. return mobj->d.stringdata + mobj->d.data[data + 2*index];
  879. return 0;
  880. }
  881. /*!
  882. Returns the value with the given \a index; or returns -1 if there
  883. is no such value.
  884. \sa keyCount() key()
  885. */
  886. int QMetaEnum::value(int index) const
  887. {
  888. if (!mobj)
  889. return 0;
  890. int count = mobj->d.data[handle + 2];
  891. int data = mobj->d.data[handle + 3];
  892. if (index >= 0 && index < count)
  893. return mobj->d.data[data + 2*index + 1];
  894. return -1;
  895. }
  896. /*!
  897. Returns true if this enumerator is used as a flag; otherwise returns
  898. false.
  899. When used as flags, enumerators can be combined using the OR
  900. operator.
  901. \sa keysToValue(), valueToKeys()
  902. */
  903. bool QMetaEnum::isFlag() const
  904. {
  905. return mobj && mobj->d.data[handle + 1];
  906. }
  907. /*!
  908. Returns the scope this enumerator was declared in.
  909. */
  910. const char *QMetaEnum::scope() const
  911. {
  912. return mobj?mobj->d.stringdata : 0;
  913. }
  914. /*!
  915. Returns the integer value of the given enumeration \a key, or -1
  916. if \a key is not defined.
  917. For set types, use keysToValue().
  918. \sa valueToKey(), isFlag(), keysToValue()
  919. */
  920. int QMetaEnum::keyToValue(const char *key) const
  921. {
  922. if (!mobj || !key)
  923. return -1;
  924. int scope = 0;
  925. const char *qualified_key = key;
  926. const char *s = key;
  927. while (*s && *s != ':')
  928. ++s;
  929. if (*s && *(s+1)==':') {
  930. scope = s - key;
  931. key += scope + 2;
  932. }
  933. int count = mobj->d.data[handle + 2];
  934. int data = mobj->d.data[handle + 3];
  935. for (int i = 0; i < count; ++i)
  936. if ((!scope || strncmp(qualified_key, mobj->d.stringdata, scope) == 0)
  937. && strcmp(key, mobj->d.stringdata + mobj->d.data[data + 2*i]) == 0)
  938. return mobj->d.data[data + 2*i + 1];
  939. return -1;
  940. }
  941. /*!
  942. Returns the string that is used as the name of the given
  943. enumeration \a value, or 0 if \a value is not defined.
  944. For set types, use valueToKeys().
  945. \sa valueToKey() isFlag() valueToKeys()
  946. */
  947. const char* QMetaEnum::valueToKey(int value) const
  948. {
  949. if (!mobj)
  950. return 0;
  951. int count = mobj->d.data[handle + 2];
  952. int data = mobj->d.data[handle + 3];
  953. for (int i = 0; i < count; ++i)
  954. if (value == (int)mobj->d.data[data + 2*i + 1])
  955. return mobj->d.stringdata + mobj->d.data[data + 2*i];
  956. return 0;
  957. }
  958. /*!
  959. Returns the value derived from combining together the values of the
  960. \a keys using the OR operator. Note that the strings in \a keys
  961. must be '|'-separated.
  962. \sa isFlag(), valueToKey(), keysToValue()
  963. */
  964. int QMetaEnum::keysToValue(const char *keys) const
  965. {
  966. if (!mobj)
  967. return -1;
  968. QStringList l = QString::fromLatin1(keys).split(QLatin1Char('|'));
  969. //#### TODO write proper code, do not use QStringList
  970. int value = 0;
  971. int count = mobj->d.data[handle + 2];
  972. int data = mobj->d.data[handle + 3];
  973. for (int li = 0; li < l.size(); ++li) {
  974. QString trimmed = l.at(li).trimmed();
  975. const char *key = trimmed.latin1();
  976. int scope = 0;
  977. const char *qualified_key = key;
  978. const char *s = key;
  979. while (*s && *s != ':')
  980. ++s;
  981. if (*s && *(s+1)==':') {
  982. scope = s - key;
  983. key += scope + 2;
  984. }
  985. int i;
  986. for (i = count-1; i >= 0; --i)
  987. if ((!scope || strncmp(qualified_key, mobj->d.stringdata, scope) == 0)
  988. && strcmp(key, mobj->d.stringdata + mobj->d.data[data + 2*i]) == 0) {
  989. value |= mobj->d.data[data + 2*i + 1];
  990. break;
  991. }
  992. if (i < 0)
  993. value |= -1;
  994. }
  995. return value;
  996. }
  997. /*!
  998. Returns a byte array of '|'-separated keys that represents the
  999. given \a value.
  1000. \sa isFlag(), valueToKey(), valueToKeys()
  1001. */
  1002. QByteArray QMetaEnum::valueToKeys(int value) const
  1003. {
  1004. QByteArray keys;
  1005. if (!mobj)
  1006. return keys;
  1007. int count = mobj->d.data[handle + 2];
  1008. int data = mobj->d.data[handle + 3];
  1009. int v = value;
  1010. for(int i = count - 1; i >= 0; --i) {
  1011. int k = mobj->d.data[data + 2*i + 1];
  1012. if ((k != 0 && (v & k) == k ) || (k == value)) {
  1013. v = v & ~k;
  1014. if (!keys.isEmpty())
  1015. keys += '|';
  1016. keys += mobj->d.stringdata + mobj->d.data[data + 2*i];
  1017. }
  1018. }
  1019. return keys;
  1020. }
  1021. /*!
  1022. \class QMetaProperty qmetaobject.h
  1023. \brief The QMetaProperty class provides meta data about a property.
  1024. \ingroup objectmodel
  1025. A property has a name() and a type(), as well as various
  1026. attributes that specify its behavior: isReadable(), isWritable(),
  1027. isDesignable(), isScriptable(), isStored(), and isEditable().
  1028. If the property is an enumeration, isEnumType() returns true; if the
  1029. property is an enumeration that is also a flag (i.e. its values
  1030. can be combined using the OR operator), isEnumType() and
  1031. isFlagType() both return true. The enumerator for these types is
  1032. available from enumerator().
  1033. The property's values are set and retrieved with read(), write(),
  1034. and reset(); they can also be changed through QObject's set and get
  1035. functions. See QObject::setProperty() and QObject::property() for
  1036. details.
  1037. You get meta property data through an object's meta object. See
  1038. QMetaObject::property() and QMetaObject::propertyCount() for
  1039. details.
  1040. */
  1041. /*!
  1042. \fn bool QMetaProperty::isValid() const
  1043. Returns true if this property is valid (readable); otherwise
  1044. returns false.
  1045. */
  1046. /*!
  1047. Constructs an invalid property
  1048. \internal
  1049. */
  1050. QMetaProperty::QMetaProperty()
  1051. {
  1052. ::memset(this, 0, sizeof(QMetaProperty));
  1053. }
  1054. /*!
  1055. Returns this property's name.
  1056. */
  1057. const char *QMetaProperty::name() const
  1058. {
  1059. if (!mobj[QMetaObject::ReadProperty])
  1060. return 0;
  1061. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1062. return mobj[QMetaObject::ReadProperty]->d.stringdata + mobj[QMetaObject::ReadProperty]->d.data[handle];
  1063. }
  1064. /*!
  1065. Returns the name of this property's type.
  1066. */
  1067. const char *QMetaProperty::typeName() const
  1068. {
  1069. if (!mobj[QMetaObject::ReadProperty])
  1070. return 0;
  1071. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1072. return mobj[QMetaObject::ReadProperty]->d.stringdata + mobj[QMetaObject::ReadProperty]->d.data[handle + 1];
  1073. }
  1074. /*!
  1075. Returns this property's type. The return value is one
  1076. of the values of the QCoreVariant::Type enumeration, or
  1077. -1 for properties of type QVariant.
  1078. */
  1079. uint QMetaProperty::type() const
  1080. {
  1081. if (!mobj[QMetaObject::ReadProperty])
  1082. return 0;
  1083. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1084. int flags = mobj[QMetaObject::ReadProperty]->d.data[handle + 2];
  1085. return (QCoreVariant::Type)flags >> 24;
  1086. }
  1087. /*!
  1088. Returns true if the property's type is an enumeration value that
  1089. is used as a flag; otherwise returns false.
  1090. Flags can be combined using the OR operator. A set type is
  1091. implicitly also an enum type.
  1092. \sa isEnumType(), enumerator()
  1093. */
  1094. bool QMetaProperty::isFlagType() const
  1095. {
  1096. return isEnumType() && menum.isFlag();
  1097. }
  1098. /*!
  1099. Returns true if the property's type is an enumeration value;
  1100. otherwise returns false.
  1101. \sa enumerator(), isFlagType()
  1102. */
  1103. bool QMetaProperty::isEnumType() const
  1104. {
  1105. if (!mobj[QMetaObject::ReadProperty])
  1106. return 0;
  1107. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1108. int flags = mobj[QMetaObject::ReadProperty]->d.data[handle + 2];
  1109. return (flags & EnumOrFlag) && menum.name();
  1110. }
  1111. /*!
  1112. \internal
  1113. Returns true if the property has a C++ setter function that
  1114. follows Qt's standard "name" / "setName" pattern. Designer and uic
  1115. query hasStdCppSet() in order to avoid expensive
  1116. QObject::setProperty() calls. All properties in Qt [should] follow
  1117. this pattern.
  1118. */
  1119. bool QMetaProperty::hasStdCppSet() const
  1120. {
  1121. if (!mobj[QMetaObject::ReadProperty])
  1122. return 0;
  1123. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1124. int flags = mobj[QMetaObject::ReadProperty]->d.data[handle + 2];
  1125. return (flags & StdCppSet);
  1126. }
  1127. /*!
  1128. Returns the enumerator if this property's type is an enumerator
  1129. type; otherwise the returned value is undefined.
  1130. \sa isEnumType()
  1131. */
  1132. QMetaEnum QMetaProperty::enumerator() const
  1133. {
  1134. return menum;
  1135. }
  1136. /*!
  1137. \fn QCoreVariant QMetaProperty::read(const QObject *object) const
  1138. Reads the property's value from the given \a object. Returns the value
  1139. if it was able to read it; otherwise returns an invalid variant.
  1140. \sa write() isReadable()
  1141. */
  1142. QCoreVariant QMetaProperty::read(const QObject *obj) const
  1143. {
  1144. if (!obj || !mobj[QMetaObject::ReadProperty])
  1145. return QCoreVariant();
  1146. QCoreVariant::Type t = QCoreVariant::Int;
  1147. if (!isEnumType()) {
  1148. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1149. int flags = mobj[QMetaObject::ReadProperty]->d.data[handle + 2];
  1150. t = (QCoreVariant::Type)(flags >> 24);
  1151. if (t == QCoreVariant::Invalid)
  1152. t = QCoreVariant::nameToType(mobj[QMetaObject::ReadProperty]->d.stringdata
  1153. + mobj[QMetaObject::ReadProperty]->d.data[handle + 1]);
  1154. if (t == QCoreVariant::Invalid)
  1155. return QCoreVariant();
  1156. }
  1157. QCoreVariant value;
  1158. void *argv[1];
  1159. void *user = 0;
  1160. if ((uint)t == 0xffffffff) {
  1161. argv[0] = &value;
  1162. } else if (t == QCoreVariant::UserType) {
  1163. qVariantSet(value, user, typeName());
  1164. argv[0] = &user;
  1165. } else {
  1166. value = QCoreVariant(t, (void*)0);
  1167. argv[0] = value.data();
  1168. }
  1169. const_cast<QObject*>(obj)->qt_metacall(QMetaObject::ReadProperty,
  1170. idx[QMetaObject::ReadProperty] + mobj[QMetaObject::ReadProperty]->propertyOffset(),
  1171. argv);
  1172. if (t == QCoreVariant::UserType)
  1173. qVariantSet(value, user, typeName());
  1174. else if ((uint)t != 0xffffffff && argv[0] != value.data())
  1175. return QCoreVariant(t, argv[0]);
  1176. return value;
  1177. }
  1178. /*!
  1179. \fn bool QMetaProperty::write(QObject *object, const QCoreVariant &value) const
  1180. Writes \a value as the property's value to the given \a object. Returns
  1181. true if the write succeeded; otherwise returns false.
  1182. \sa read() isWritable()
  1183. */
  1184. bool QMetaProperty::write(QObject *obj, const QCoreVariant &value) const
  1185. {
  1186. if (!obj || !isWritable())
  1187. return false;
  1188. QCoreVariant v = value;
  1189. QCoreVariant::Type t = QCoreVariant::Invalid;
  1190. if (isEnumType()) {
  1191. if (v.type() == QCoreVariant::String || v.type() == QCoreVariant::CString) {
  1192. if (isFlagType())
  1193. v = QCoreVariant(menum.keysToValue(value.toByteArray()));
  1194. else
  1195. v = QCoreVariant(menum.keyToValue(value.toByteArray()));
  1196. } else if (v.type() != QCoreVariant::Int && v.type() != QCoreVariant::UInt) {
  1197. return false;
  1198. }
  1199. v.cast(QCoreVariant::Int);
  1200. } else {
  1201. int handle = priv(mobj[QMetaObject::WriteProperty]->d.data)->propertyData + 3*idx[QMetaObject::WriteProperty];
  1202. int flags = mobj[QMetaObject::WriteProperty]->d.data[handle + 2];
  1203. t = (QCoreVariant::Type)(flags >> 24);
  1204. if (t == QCoreVariant::Invalid)
  1205. t = QCoreVariant::nameToType(mobj[QMetaObject::WriteProperty]->d.stringdata
  1206. + mobj[QMetaObject::WriteProperty]->d.data[handle + 1]);
  1207. if (t != QCoreVariant::Invalid && (uint)t != 0xffffffff && t != QCoreVariant::UserType && !v.cast(t))
  1208. return false;
  1209. }
  1210. void *argv[1];
  1211. if ((uint)t == 0xffffffff)
  1212. argv[0] = &v;
  1213. else
  1214. argv[0] = v.data();
  1215. obj->qt_metacall(QMetaObject::WriteProperty,
  1216. idx[QMetaObject::WriteProperty] + mobj[QMetaObject::WriteProperty]->propertyOffset(),
  1217. argv);
  1218. return true;
  1219. }
  1220. /*!
  1221. \fn bool QMetaProperty::reset(QObject *object) const
  1222. Resets the property for the given \a object with a reset method.
  1223. Returns true if the reset worked; otherwise returns false.
  1224. Reset methods are optional; only a few properties support them.
  1225. */
  1226. bool QMetaProperty::reset(QObject *obj) const
  1227. {
  1228. if (!obj || !mobj[QMetaObject::ResetProperty])
  1229. return false;
  1230. void *argv[] = { 0 };
  1231. obj->qt_metacall(QMetaObject::ResetProperty,
  1232. idx[QMetaObject::ResetProperty] + mobj[QMetaObject::ResetProperty]->propertyOffset(),
  1233. argv);
  1234. return true;
  1235. }
  1236. /*!
  1237. Returns true if this property is readable; otherwise returns false.
  1238. \sa read() isWritable()
  1239. */
  1240. bool QMetaProperty::isReadable() const
  1241. {
  1242. return mobj[QMetaObject::ReadProperty] != 0;
  1243. }
  1244. /*!
  1245. Returns true if this property is writable; otherwise returns
  1246. false.
  1247. \sa write() isReadable()
  1248. */
  1249. bool QMetaProperty::isWritable() const
  1250. {
  1251. if (!mobj[QMetaObject::WriteProperty])
  1252. return false;
  1253. int handle = priv(mobj[QMetaObject::ReadProperty]->d.data)->propertyData + 3*idx[QMetaObject::ReadProperty];
  1254. int flags = mobj[QMetaObject::ReadProperty]->d.data[handle + 2];
  1255. return !(flags & EnumOrFlag) || menum.name();
  1256. }
  1257. static bool qt_query_property(const QMetaObject*const*mobj,const int *idx, uint flag,
  1258. QMetaObject::Call call, const QObject* obj)
  1259. {
  1260. if (!mobj[call])
  1261. return false;
  1262. int handle = priv(mobj[call]->d.data)->propertyData + 3*idx[call];
  1263. int flags = mobj[call]->d.data[handle + 2];
  1264. bool b = (flags & flag);
  1265. if (obj) {
  1266. void *argv[] = { &b };
  1267. const_cast<QObject*>(obj)->qt_metacall(call,
  1268. idx[call]
  1269. + mobj[call]->propertyOffset(),
  1270. argv);
  1271. }
  1272. return b;
  1273. }
  1274. /*!
  1275. \fn bool QMetaProperty::isDesignable(const QObject *object) const
  1276. Returns true if this property is designable for the given \a object;
  1277. otherwise returns false.
  1278. If no \a object is given, the function returns false if the
  1279. \c{Q_PROPERTY}'s \c DESIGNABLE attribute is false; otherwise
  1280. returns true (if the attribute is true or is a function or expression).
  1281. */
  1282. bool QMetaProperty::isDesignable(const QObject *obj) const
  1283. {
  1284. if (!mobj[QMetaObject::WriteProperty])
  1285. return false;
  1286. return qt_query_property(mobj, idx, Designable,
  1287. QMetaObject::QueryPropertyDesignable,
  1288. obj);
  1289. }
  1290. /*!
  1291. \fn bool QMetaProperty::isScriptable(const QObject *object) const
  1292. Returns true if the property is scriptable for the given \a object;
  1293. otherwise returns false.
  1294. If no \a object is given, the function returns false if the
  1295. \c{Q_PROPERTY}'s \c DESIGNABLE attribute is false; otherwise returns
  1296. true (if the attribute is true or is a function or expression).
  1297. */
  1298. bool QMetaProperty::isScriptable(const QObject *obj) const
  1299. {
  1300. return qt_query_property(mobj, idx, Scriptable,
  1301. QMetaObject::QueryPropertyScriptable,
  1302. obj);
  1303. }
  1304. /*!
  1305. \fn bool QMetaProperty::isStored(const QObject *object) const
  1306. Returns true if the property is stored for \a object; otherwise returns
  1307. false.
  1308. If no \a object is given, the function returns false if the
  1309. \c{Q_PROPERTY}'s \c DESIGNABLE attribute is false; otherwise returns
  1310. true (if the attribute is true or is a function or expression).
  1311. */
  1312. bool QMetaProperty::isStored(const QObject *obj) const
  1313. {
  1314. return qt_query_property(mobj, idx, Stored,
  1315. QMetaObject::QueryPropertyStored,
  1316. obj);
  1317. }
  1318. /*!
  1319. \fn bool QMetaProperty::isEditable(const QObject *object) const
  1320. Returns true if the property is editable for the given \a object;
  1321. otherwise returns false.
  1322. If no \a object is given, the function returns false if the
  1323. \c{Q_PROPERTY}'s \c DESIGNABLE attribute is false; otherwise returns
  1324. true (if the attribute is true or is a function or expression).
  1325. */
  1326. bool QMetaProperty::isEditable(const QObject *obj) const
  1327. {
  1328. return qt_query_property(mobj, idx, Editable,
  1329. QMetaObject::QueryPropertyEditable,
  1330. obj);
  1331. }
  1332. /*!
  1333. \class QMetaClassInfo qmetaobject.h
  1334. \brief The QMetaClassInfo class provides additional information
  1335. about a class.
  1336. \ingroup objectmodel
  1337. Class information items are simple \e{name}--\e{value} pairs that
  1338. are specified using \c Q_CLASSINFO in the source code. The
  1339. information can be retrieved using name() and value().
  1340. */
  1341. /*!
  1342. \fn QMetaClassInfo::QMetaClassInfo()
  1343. \internal
  1344. */
  1345. /*!
  1346. Returns the name of this item.
  1347. \sa value()
  1348. */
  1349. const char* QMetaClassInfo::name() const
  1350. {
  1351. if (!mobj)
  1352. return 0;
  1353. return mobj->d.stringdata + mobj->d.data[handle];
  1354. }
  1355. /*!
  1356. Returns the value of this item.
  1357. \sa name()
  1358. */
  1359. const char* QMetaClassInfo::value() const
  1360. {
  1361. if (!mobj)
  1362. return 0;
  1363. return mobj->d.stringdata + mobj->d.data[handle + 1];
  1364. }
  1365. /*!
  1366. \class QMetaType qmetaobject.h
  1367. \brief The QMetaType class manages named types in the meta object system.
  1368. \internal
  1369. \ingroup objectmodel
  1370. The class is used to queue signals and slots connections.
  1371. */
  1372. static const struct { const char * typeName; int type; } types[] = {
  1373. {"void*", QMetaType::VoidStar},
  1374. {"long", QMetaType::Long},
  1375. {"int", QMetaType::Int},
  1376. {"short", QMetaType::Short},
  1377. {"char", QMetaType::Char},
  1378. {"ulong", QMetaType::ULong},
  1379. {"unsigned long", QMetaType::ULong},
  1380. {"uint", QMetaType::UInt},
  1381. {"unsigned int", QMetaType::UInt},
  1382. {"ushort", QMetaType::UShort},
  1383. {"unsigned short", QMetaType::UShort},
  1384. {"uchar", QMetaType::UChar},
  1385. {"unsigned char", QMetaType::UChar},
  1386. {"bool", QMetaType::Bool},
  1387. {"float", QMetaType::Float},
  1388. {"double", QMetaType::Double},
  1389. {"QChar", QMetaType::QChar},
  1390. {"QByteArray", QMetaType::QByteArray},
  1391. {"QString", QMetaType::QString},
  1392. {"void", QMetaType::Void},
  1393. {"", QMetaType::Void},
  1394. {0, QMetaType::Void}
  1395. };
  1396. class QCustomTypeInfo
  1397. {
  1398. public:
  1399. QCustomTypeInfo() : typeName(0, '\0'), copy(0), destr(0), saveOp(0), loadOp(0) {}
  1400. inline void setData(const char *tname, QMetaType::CopyConstructor cp, QMetaType::Destructor de)
  1401. { typeName = tname; copy = cp; destr = de; }
  1402. inline void setData(QMetaType::CopyConstructor cp, QMetaType::Destructor de)
  1403. { copy = cp; destr = de; }
  1404. inline void setOperators(QMetaType::SaveOperator sOp, QMetaType::LoadOperator lOp)
  1405. { saveOp = sOp; loadOp = lOp; }
  1406. QByteArray typeName;
  1407. QMetaType::CopyConstructor copy;
  1408. QMetaType::Destructor destr;
  1409. QMetaType::SaveOperator saveOp;
  1410. QMetaType::LoadOperator loadOp;
  1411. };
  1412. Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
  1413. void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
  1414. LoadOperator loadOp)
  1415. {
  1416. int idx = type(typeName);
  1417. if (!idx)
  1418. return;
  1419. QVector<QCustomTypeInfo> *ct = customTypes();
  1420. if (!ct)
  1421. return;
  1422. (*ct)[idx - User].setOperators(saveOp, loadOp);
  1423. }
  1424. /*!
  1425. Returns the type name associated with the given \a type, or 0 if no
  1426. matching type was found. The returned pointer must not be deleted.
  1427. */
  1428. const char *QMetaType::typeName(int type)
  1429. {
  1430. if (type >= User) {
  1431. if (!isRegistered(type))
  1432. return 0;
  1433. const QVector<QCustomTypeInfo> * const ct = customTypes();
  1434. if (!ct)
  1435. return 0;
  1436. return ct->at(type - User).typeName.constData();
  1437. }
  1438. int i = 0;
  1439. while (types[i].typeName) {
  1440. if (types[i].type == type)
  1441. return types[i].typeName;
  1442. ++i;
  1443. }
  1444. return 0;
  1445. }
  1446. /*!
  1447. Registers a user type for marshalling, with \a typeName, a \a
  1448. destructor, and a \a copyConstructor. Returns the type's handle,
  1449. or -1 if the type could not be registered.
  1450. */
  1451. int QMetaType::registerType(const char *typeName, Destructor destructor,
  1452. CopyConstructor copyConstructor)
  1453. {
  1454. QVector<QCustomTypeInfo> *ct = customTypes();
  1455. static int currentIdx = User;
  1456. if (!ct || !typeName || !destructor || !copyConstructor)
  1457. return -1;
  1458. int idx = type(typeName);
  1459. if (idx) {
  1460. if (idx < User) {
  1461. qWarning("cannot re-register basic type '%s'", typeName);
  1462. return -1;
  1463. }
  1464. (*ct)[idx - User].setData(copyConstructor, destructor);
  1465. } else {
  1466. idx = currentIdx++;
  1467. ct->resize(ct->count() + 1);
  1468. (*ct)[idx - User].setData(typeName, copyConstructor, destructor);
  1469. }
  1470. return idx;
  1471. }
  1472. /*!
  1473. Returns true if the custom datatype with ID \a type is registered;
  1474. otherwise returns false.
  1475. */
  1476. bool QMetaType::isRegistered(int type)
  1477. {
  1478. const QVector<QCustomTypeInfo> * const ct = customTypes();
  1479. return (type >= User) && (ct && ct->count() > type - User);
  1480. }
  1481. /*!
  1482. Returns a handle to the type called \a typeName, or 0 if there is
  1483. no such type.
  1484. */
  1485. int QMetaType::type(const char *typeName)
  1486. {
  1487. if (!typeName)
  1488. return 0;
  1489. int i = 0;
  1490. while (types[i].typeName && strcmp(typeName, types[i].typeName))
  1491. ++i;
  1492. if (!types[i].type) {
  1493. const QVector<QCustomTypeInfo> * const ct = customTypes();
  1494. for (int v = 0; ct && v < ct->count(); ++v) {
  1495. if (strcmp(ct->at(v).typeName, typeName) == 0)
  1496. return v + User;
  1497. }
  1498. }
  1499. return types[i].type;
  1500. }
  1501. bool QMetaType::save(QDataStream &stream, int type, const void *data)
  1502. {
  1503. // FIXME - also stream simple types?
  1504. if (!data || !isRegistered(type))
  1505. return false;
  1506. const QVector<QCustomTypeInfo> * const ct = customTypes();
  1507. if (!ct)
  1508. return false;
  1509. QMetaType::SaveOperator saveOp = ct->at(type - User).saveOp;
  1510. if (!saveOp)
  1511. return false;
  1512. saveOp(stream, data);
  1513. return true;
  1514. }
  1515. bool QMetaType::load(QDataStream &stream, int type, void *data)
  1516. {
  1517. // FIXME - also stream simple types?
  1518. if (!data || !isRegistered(type))
  1519. return false;
  1520. const QVector<QCustomTypeInfo> * const ct = customTypes();
  1521. if (!ct)
  1522. return false;
  1523. QMetaType::LoadOperator loadOp = ct->at(type - User).loadOp;
  1524. if (!loadOp)
  1525. return false;
  1526. loadOp(stream, data);
  1527. return true;
  1528. }
  1529. /*
  1530. Returns a copy of data, assuming it is of type \a type.
  1531. */
  1532. void *QMetaType::copy(int type, const void *data)
  1533. {
  1534. if (!data)
  1535. return 0;
  1536. switch(type) {
  1537. case QMetaType::VoidStar:
  1538. return new void *(*static_cast<void* const *>(data));
  1539. case QMetaType::Long:
  1540. return new long(*static_cast<const long*>(data));
  1541. case QMetaType::Int:
  1542. return new int(*static_cast<const int*>(data));
  1543. case QMetaType::Short:
  1544. return new short(*static_cast<const short*>(data));
  1545. case QMetaType::Char:
  1546. return new char(*static_cast<const char*>(data));
  1547. case QMetaType::ULong:
  1548. return new ulong(*static_cast<const ulong*>(data));
  1549. case QMetaType::UInt:
  1550. return new uint(*static_cast<const uint*>(data));
  1551. case QMetaType::UShort:
  1552. return new ushort(*static_cast<const ushort*>(data));
  1553. case QMetaType::UChar:
  1554. return new uchar(*static_cast<const uchar*>(data));
  1555. case QMetaType::Bool:
  1556. return new bool(*static_cast<const bool*>(data));
  1557. case QMetaType::Float:
  1558. return new float(*static_cast<const float*>(data));
  1559. case QMetaType::Double:
  1560. return new double(*static_cast<const double*>(data));
  1561. case QMetaType::QChar:
  1562. return new ::QChar(*static_

Large files files are truncated, but you can click here to view the full file