| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtCore module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qmetaobjectbuilder_p.h" |
| |
| #include "qobject_p.h" |
| #include "qmetaobject_p.h" |
| |
| #include <vector> |
| #include <stdlib.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \class QMetaObjectBuilder |
| \inmodule QtCore |
| \internal |
| \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime. |
| |
| */ |
| |
| /*! |
| \enum QMetaObjectBuilder::AddMember |
| This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject() |
| |
| \value ClassName Add the class name. |
| \value SuperClass Add the super class. |
| \value Methods Add methods that aren't signals or slots. |
| \value Signals Add signals. |
| \value Slots Add slots. |
| \value Constructors Add constructors. |
| \value Properties Add properties. |
| \value Enumerators Add enumerators. |
| \value ClassInfos Add items of class information. |
| \value RelatedMetaObjects Add related meta objects. |
| \value StaticMetacall Add the static metacall function. |
| \value PublicMethods Add public methods (ignored for signals). |
| \value ProtectedMethods Add protected methods (ignored for signals). |
| \value PrivateMethods All private methods (ignored for signals). |
| \value AllMembers Add all members. |
| \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function. |
| */ |
| |
| // copied from moc's generator.cpp |
| namespace QtPrivate { |
| Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type) |
| { |
| int id = QMetaType::type(type); |
| if (!id && !type.isEmpty() && type != "void") |
| return false; |
| return (id < QMetaType::User); |
| } |
| } // namespace QtPrivate |
| |
| // copied from qmetaobject.cpp |
| static inline Q_DECL_UNUSED const QMetaObjectPrivate *priv(const uint* data) |
| { return reinterpret_cast<const QMetaObjectPrivate*>(data); } |
| |
| class QMetaMethodBuilderPrivate |
| { |
| public: |
| QMetaMethodBuilderPrivate |
| (QMetaMethod::MethodType _methodType, |
| const QByteArray& _signature, |
| const QByteArray& _returnType = QByteArray("void"), |
| QMetaMethod::Access _access = QMetaMethod::Public, |
| int _revision = 0) |
| : signature(QMetaObject::normalizedSignature(_signature.constData())), |
| returnType(QMetaObject::normalizedType(_returnType)), |
| attributes(((int)_access) | (((int)_methodType) << 2)), |
| revision(_revision) |
| { |
| Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull()); |
| } |
| |
| QByteArray signature; |
| QByteArray returnType; |
| QList<QByteArray> parameterNames; |
| QByteArray tag; |
| int attributes; |
| int revision; |
| |
| QMetaMethod::MethodType methodType() const |
| { |
| return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2); |
| } |
| |
| QMetaMethod::Access access() const |
| { |
| return (QMetaMethod::Access)(attributes & AccessMask); |
| } |
| |
| void setAccess(QMetaMethod::Access value) |
| { |
| attributes = ((attributes & ~AccessMask) | (int)value); |
| } |
| |
| QList<QByteArray> parameterTypes() const |
| { |
| return QMetaObjectPrivate::parameterTypeNamesFromSignature(signature); |
| } |
| |
| int parameterCount() const |
| { |
| return parameterTypes().size(); |
| } |
| |
| QByteArray name() const |
| { |
| return signature.left(qMax(signature.indexOf('('), 0)); |
| } |
| }; |
| Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_MOVABLE_TYPE); |
| |
| class QMetaPropertyBuilderPrivate |
| { |
| public: |
| QMetaPropertyBuilderPrivate |
| (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1, |
| int _revision = 0) |
| : name(_name), |
| type(QMetaObject::normalizedType(_type.constData())), |
| flags(Readable | Writable | Scriptable), notifySignal(-1), |
| revision(_revision) |
| { |
| if (notifierIdx >= 0) { |
| flags |= Notify; |
| notifySignal = notifierIdx; |
| } |
| } |
| |
| QByteArray name; |
| QByteArray type; |
| int flags; |
| int notifySignal; |
| int revision; |
| |
| bool flag(int f) const |
| { |
| return ((flags & f) != 0); |
| } |
| |
| void setFlag(int f, bool value) |
| { |
| if (value) |
| flags |= f; |
| else |
| flags &= ~f; |
| } |
| }; |
| Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_MOVABLE_TYPE); |
| |
| class QMetaEnumBuilderPrivate |
| { |
| public: |
| QMetaEnumBuilderPrivate(const QByteArray& _name) |
| : name(_name), enumName(_name), isFlag(false), isScoped(false) |
| { |
| } |
| |
| QByteArray name; |
| QByteArray enumName; |
| bool isFlag; |
| bool isScoped; |
| QList<QByteArray> keys; |
| QVector<int> values; |
| }; |
| Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_MOVABLE_TYPE); |
| |
| class QMetaObjectBuilderPrivate |
| { |
| public: |
| QMetaObjectBuilderPrivate() |
| : flags(0) |
| { |
| superClass = &QObject::staticMetaObject; |
| staticMetacallFunction = 0; |
| } |
| |
| bool hasRevisionedProperties() const; |
| bool hasRevisionedMethods() const; |
| |
| QByteArray className; |
| const QMetaObject *superClass; |
| QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction; |
| std::vector<QMetaMethodBuilderPrivate> methods; |
| std::vector<QMetaMethodBuilderPrivate> constructors; |
| std::vector<QMetaPropertyBuilderPrivate> properties; |
| QList<QByteArray> classInfoNames; |
| QList<QByteArray> classInfoValues; |
| std::vector<QMetaEnumBuilderPrivate> enumerators; |
| QList<const QMetaObject *> relatedMetaObjects; |
| int flags; |
| }; |
| |
| bool QMetaObjectBuilderPrivate::hasRevisionedProperties() const |
| { |
| for (const auto &property : properties) { |
| if (property.revision) |
| return true; |
| } |
| return false; |
| } |
| |
| bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const |
| { |
| for (const auto &method : methods) { |
| if (method.revision) |
| return true; |
| } |
| return false; |
| } |
| |
| /*! |
| Constructs a new QMetaObjectBuilder. |
| */ |
| QMetaObjectBuilder::QMetaObjectBuilder() |
| { |
| d = new QMetaObjectBuilderPrivate(); |
| } |
| |
| /*! |
| Constructs a new QMetaObjectBuilder which is a copy of the |
| meta object information in \a prototype. Note: the super class |
| contents for \a prototype are not copied, only the immediate |
| class that is defined by \a prototype. |
| |
| The \a members parameter indicates which members of \a prototype |
| should be added. The default is AllMembers. |
| |
| \sa addMetaObject() |
| */ |
| QMetaObjectBuilder::QMetaObjectBuilder |
| (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members) |
| { |
| d = new QMetaObjectBuilderPrivate(); |
| addMetaObject(prototype, members); |
| } |
| |
| /*! |
| Destroys this meta object builder. |
| */ |
| QMetaObjectBuilder::~QMetaObjectBuilder() |
| { |
| delete d; |
| } |
| |
| /*! |
| Returns the name of the class being constructed by this |
| meta object builder. The default value is an empty QByteArray. |
| |
| \sa setClassName(), superClass() |
| */ |
| QByteArray QMetaObjectBuilder::className() const |
| { |
| return d->className; |
| } |
| |
| /*! |
| Sets the \a name of the class being constructed by this |
| meta object builder. |
| |
| \sa className(), setSuperClass() |
| */ |
| void QMetaObjectBuilder::setClassName(const QByteArray& name) |
| { |
| d->className = name; |
| } |
| |
| /*! |
| Returns the superclass meta object of the class being constructed |
| by this meta object builder. The default value is the meta object |
| for QObject. |
| |
| \sa setSuperClass(), className() |
| */ |
| const QMetaObject *QMetaObjectBuilder::superClass() const |
| { |
| return d->superClass; |
| } |
| |
| /*! |
| Sets the superclass meta object of the class being constructed |
| by this meta object builder to \a meta. The \a meta parameter |
| must not be null. |
| |
| \sa superClass(), setClassName() |
| */ |
| void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta) |
| { |
| Q_ASSERT(meta); |
| d->superClass = meta; |
| } |
| |
| /*! |
| Returns the flags of the class being constructed by this meta object |
| builder. |
| |
| \sa setFlags() |
| */ |
| QMetaObjectBuilder::MetaObjectFlags QMetaObjectBuilder::flags() const |
| { |
| return (QMetaObjectBuilder::MetaObjectFlags)d->flags; |
| } |
| |
| /*! |
| Sets the \a flags of the class being constructed by this meta object |
| builder. |
| |
| \sa flags() |
| */ |
| void QMetaObjectBuilder::setFlags(MetaObjectFlags flags) |
| { |
| d->flags = flags; |
| } |
| |
| /*! |
| Returns the number of methods in this class, excluding the number |
| of methods in the base class. These include signals and slots |
| as well as normal member functions. |
| |
| \sa addMethod(), method(), removeMethod(), indexOfMethod() |
| */ |
| int QMetaObjectBuilder::methodCount() const |
| { |
| return int(d->methods.size()); |
| } |
| |
| /*! |
| Returns the number of constructors in this class. |
| |
| \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor() |
| */ |
| int QMetaObjectBuilder::constructorCount() const |
| { |
| return int(d->constructors.size()); |
| } |
| |
| /*! |
| Returns the number of properties in this class, excluding the number |
| of properties in the base class. |
| |
| \sa addProperty(), property(), removeProperty(), indexOfProperty() |
| */ |
| int QMetaObjectBuilder::propertyCount() const |
| { |
| return int(d->properties.size()); |
| } |
| |
| /*! |
| Returns the number of enumerators in this class, excluding the |
| number of enumerators in the base class. |
| |
| \sa addEnumerator(), enumerator(), removeEnumerator() |
| \sa indexOfEnumerator() |
| */ |
| int QMetaObjectBuilder::enumeratorCount() const |
| { |
| return int(d->enumerators.size()); |
| } |
| |
| /*! |
| Returns the number of items of class information in this class, |
| exclusing the number of items of class information in the base class. |
| |
| \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo() |
| \sa indexOfClassInfo() |
| */ |
| int QMetaObjectBuilder::classInfoCount() const |
| { |
| return d->classInfoNames.size(); |
| } |
| |
| /*! |
| Returns the number of related meta objects that are associated |
| with this class. |
| |
| Related meta objects are used when resolving the enumerated type |
| associated with a property, where the enumerated type is in a |
| different class from the property. |
| |
| \sa addRelatedMetaObject(), relatedMetaObject() |
| \sa removeRelatedMetaObject() |
| */ |
| int QMetaObjectBuilder::relatedMetaObjectCount() const |
| { |
| return d->relatedMetaObjects.size(); |
| } |
| |
| /*! |
| Adds a new public method to this class with the specified \a signature. |
| Returns an object that can be used to adjust the other attributes |
| of the method. The \a signature will be normalized before it is |
| added to the class. |
| |
| \sa method(), methodCount(), removeMethod(), indexOfMethod() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature) |
| { |
| int index = int(d->methods.size()); |
| d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature)); |
| return QMetaMethodBuilder(this, index); |
| } |
| |
| /*! |
| Adds a new public method to this class with the specified |
| \a signature and \a returnType. Returns an object that can be |
| used to adjust the other attributes of the method. The \a signature |
| and \a returnType will be normalized before they are added to |
| the class. |
| |
| \sa method(), methodCount(), removeMethod(), indexOfMethod() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addMethod |
| (const QByteArray& signature, const QByteArray& returnType) |
| { |
| int index = int(d->methods.size()); |
| d->methods.push_back(QMetaMethodBuilderPrivate |
| (QMetaMethod::Method, signature, returnType)); |
| return QMetaMethodBuilder(this, index); |
| } |
| |
| /*! |
| Adds a new public method to this class that has the same information as |
| \a prototype. This is used to clone the methods of an existing |
| QMetaObject. Returns an object that can be used to adjust the |
| attributes of the method. |
| |
| This function will detect if \a prototype is an ordinary method, |
| signal, slot, or constructor and act accordingly. |
| |
| \sa method(), methodCount(), removeMethod(), indexOfMethod() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype) |
| { |
| QMetaMethodBuilder method; |
| if (prototype.methodType() == QMetaMethod::Method) |
| method = addMethod(prototype.methodSignature()); |
| else if (prototype.methodType() == QMetaMethod::Signal) |
| method = addSignal(prototype.methodSignature()); |
| else if (prototype.methodType() == QMetaMethod::Slot) |
| method = addSlot(prototype.methodSignature()); |
| else if (prototype.methodType() == QMetaMethod::Constructor) |
| method = addConstructor(prototype.methodSignature()); |
| method.setReturnType(prototype.typeName()); |
| method.setParameterNames(prototype.parameterNames()); |
| method.setTag(prototype.tag()); |
| method.setAccess(prototype.access()); |
| method.setAttributes(prototype.attributes()); |
| method.setRevision(prototype.revision()); |
| return method; |
| } |
| |
| /*! |
| Adds a new public slot to this class with the specified \a signature. |
| Returns an object that can be used to adjust the other attributes |
| of the slot. The \a signature will be normalized before it is |
| added to the class. |
| |
| \sa addMethod(), addSignal(), indexOfSlot() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature) |
| { |
| int index = int(d->methods.size()); |
| d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature)); |
| return QMetaMethodBuilder(this, index); |
| } |
| |
| /*! |
| Adds a new signal to this class with the specified \a signature. |
| Returns an object that can be used to adjust the other attributes |
| of the signal. The \a signature will be normalized before it is |
| added to the class. |
| |
| \sa addMethod(), addSlot(), indexOfSignal() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature) |
| { |
| int index = int(d->methods.size()); |
| d->methods.push_back(QMetaMethodBuilderPrivate |
| (QMetaMethod::Signal, signature, QByteArray("void"), QMetaMethod::Public)); |
| return QMetaMethodBuilder(this, index); |
| } |
| |
| /*! |
| Adds a new constructor to this class with the specified \a signature. |
| Returns an object that can be used to adjust the other attributes |
| of the constructor. The \a signature will be normalized before it is |
| added to the class. |
| |
| \sa constructor(), constructorCount(), removeConstructor() |
| \sa indexOfConstructor() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature) |
| { |
| int index = int(d->constructors.size()); |
| d->constructors.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature, |
| /*returnType=*/QByteArray())); |
| return QMetaMethodBuilder(this, -(index + 1)); |
| } |
| |
| /*! |
| Adds a new constructor to this class that has the same information as |
| \a prototype. This is used to clone the constructors of an existing |
| QMetaObject. Returns an object that can be used to adjust the |
| attributes of the constructor. |
| |
| This function requires that \a prototype be a constructor. |
| |
| \sa constructor(), constructorCount(), removeConstructor() |
| \sa indexOfConstructor() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype) |
| { |
| Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor); |
| QMetaMethodBuilder ctor = addConstructor(prototype.methodSignature()); |
| ctor.setReturnType(prototype.typeName()); |
| ctor.setParameterNames(prototype.parameterNames()); |
| ctor.setTag(prototype.tag()); |
| ctor.setAccess(prototype.access()); |
| ctor.setAttributes(prototype.attributes()); |
| return ctor; |
| } |
| |
| /*! |
| Adds a new readable/writable property to this class with the |
| specified \a name and \a type. Returns an object that can be used |
| to adjust the other attributes of the property. The \a type will |
| be normalized before it is added to the class. \a notifierId will |
| be registered as the property's \e notify signal. |
| |
| \sa property(), propertyCount(), removeProperty(), indexOfProperty() |
| */ |
| QMetaPropertyBuilder QMetaObjectBuilder::addProperty |
| (const QByteArray& name, const QByteArray& type, int notifierId) |
| { |
| int index = int(d->properties.size()); |
| d->properties.push_back(QMetaPropertyBuilderPrivate(name, type, notifierId)); |
| return QMetaPropertyBuilder(this, index); |
| } |
| |
| /*! |
| Adds a new property to this class that has the same information as |
| \a prototype. This is used to clone the properties of an existing |
| QMetaObject. Returns an object that can be used to adjust the |
| attributes of the property. |
| |
| \sa property(), propertyCount(), removeProperty(), indexOfProperty() |
| */ |
| QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& prototype) |
| { |
| QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName()); |
| property.setReadable(prototype.isReadable()); |
| property.setWritable(prototype.isWritable()); |
| property.setResettable(prototype.isResettable()); |
| property.setDesignable(prototype.isDesignable()); |
| property.setScriptable(prototype.isScriptable()); |
| property.setStored(prototype.isStored()); |
| property.setEditable(prototype.isEditable()); |
| property.setUser(prototype.isUser()); |
| property.setStdCppSet(prototype.hasStdCppSet()); |
| property.setEnumOrFlag(prototype.isEnumType()); |
| property.setConstant(prototype.isConstant()); |
| property.setFinal(prototype.isFinal()); |
| property.setRevision(prototype.revision()); |
| if (prototype.hasNotifySignal()) { |
| // Find an existing method for the notify signal, or add a new one. |
| QMetaMethod method = prototype.notifySignal(); |
| int index = indexOfMethod(method.methodSignature()); |
| if (index == -1) |
| index = addMethod(method).index(); |
| d->properties[property._index].notifySignal = index; |
| d->properties[property._index].setFlag(Notify, true); |
| } |
| return property; |
| } |
| |
| /*! |
| Adds a new enumerator to this class with the specified |
| \a name. Returns an object that can be used to adjust |
| the other attributes of the enumerator. |
| |
| \sa enumerator(), enumeratorCount(), removeEnumerator() |
| \sa indexOfEnumerator() |
| */ |
| QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name) |
| { |
| int index = int(d->enumerators.size()); |
| d->enumerators.push_back(QMetaEnumBuilderPrivate(name)); |
| return QMetaEnumBuilder(this, index); |
| } |
| |
| /*! |
| Adds a new enumerator to this class that has the same information as |
| \a prototype. This is used to clone the enumerators of an existing |
| QMetaObject. Returns an object that can be used to adjust the |
| attributes of the enumerator. |
| |
| \sa enumerator(), enumeratorCount(), removeEnumerator() |
| \sa indexOfEnumerator() |
| */ |
| QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype) |
| { |
| QMetaEnumBuilder en = addEnumerator(prototype.name()); |
| en.setEnumName(prototype.enumName()); |
| en.setIsFlag(prototype.isFlag()); |
| en.setIsScoped(prototype.isScoped()); |
| int count = prototype.keyCount(); |
| for (int index = 0; index < count; ++index) |
| en.addKey(prototype.key(index), prototype.value(index)); |
| return en; |
| } |
| |
| /*! |
| Adds \a name and \a value as an item of class information to this class. |
| Returns the index of the new item of class information. |
| |
| \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo() |
| \sa indexOfClassInfo() |
| */ |
| int QMetaObjectBuilder::addClassInfo(const QByteArray& name, const QByteArray& value) |
| { |
| int index = d->classInfoNames.size(); |
| d->classInfoNames += name; |
| d->classInfoValues += value; |
| return index; |
| } |
| |
| /*! |
| Adds \a meta to this class as a related meta object. Returns |
| the index of the new related meta object entry. |
| |
| Related meta objects are used when resolving the enumerated type |
| associated with a property, where the enumerated type is in a |
| different class from the property. |
| |
| \sa relatedMetaObjectCount(), relatedMetaObject() |
| \sa removeRelatedMetaObject() |
| */ |
| int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta) |
| { |
| Q_ASSERT(meta); |
| int index = d->relatedMetaObjects.size(); |
| d->relatedMetaObjects.append(meta); |
| return index; |
| } |
| |
| /*! |
| Adds the contents of \a prototype to this meta object builder. |
| This function is useful for cloning the contents of an existing QMetaObject. |
| |
| The \a members parameter indicates which members of \a prototype |
| should be added. The default is AllMembers. |
| */ |
| void QMetaObjectBuilder::addMetaObject |
| (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members) |
| { |
| Q_ASSERT(prototype); |
| int index; |
| |
| if ((members & ClassName) != 0) |
| d->className = prototype->className(); |
| |
| if ((members & SuperClass) != 0) |
| d->superClass = prototype->superClass(); |
| |
| if ((members & (Methods | Signals | Slots)) != 0) { |
| for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) { |
| QMetaMethod method = prototype->method(index); |
| if (method.methodType() != QMetaMethod::Signal) { |
| if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0) |
| continue; |
| if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0) |
| continue; |
| if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0) |
| continue; |
| } |
| if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) { |
| addMethod(method); |
| } else if (method.methodType() == QMetaMethod::Signal && |
| (members & Signals) != 0) { |
| addMethod(method); |
| } else if (method.methodType() == QMetaMethod::Slot && |
| (members & Slots) != 0) { |
| addMethod(method); |
| } |
| } |
| } |
| |
| if ((members & Constructors) != 0) { |
| for (index = 0; index < prototype->constructorCount(); ++index) |
| addConstructor(prototype->constructor(index)); |
| } |
| |
| if ((members & Properties) != 0) { |
| for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index) |
| addProperty(prototype->property(index)); |
| } |
| |
| if ((members & Enumerators) != 0) { |
| for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index) |
| addEnumerator(prototype->enumerator(index)); |
| } |
| |
| if ((members & ClassInfos) != 0) { |
| for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) { |
| QMetaClassInfo ci = prototype->classInfo(index); |
| addClassInfo(ci.name(), ci.value()); |
| } |
| } |
| |
| if ((members & RelatedMetaObjects) != 0) { |
| Q_ASSERT(priv(prototype->d.data)->revision >= 2); |
| const auto *objects = prototype->d.relatedMetaObjects; |
| if (objects) { |
| while (*objects != 0) { |
| addRelatedMetaObject(*objects); |
| ++objects; |
| } |
| } |
| } |
| |
| if ((members & StaticMetacall) != 0) { |
| Q_ASSERT(priv(prototype->d.data)->revision >= 6); |
| if (prototype->d.static_metacall) |
| setStaticMetacallFunction(prototype->d.static_metacall); |
| } |
| } |
| |
| /*! |
| Returns the method at \a index in this class. |
| |
| \sa methodCount(), addMethod(), removeMethod(), indexOfMethod() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::method(int index) const |
| { |
| if (uint(index) < d->methods.size()) |
| return QMetaMethodBuilder(this, index); |
| else |
| return QMetaMethodBuilder(); |
| } |
| |
| /*! |
| Returns the constructor at \a index in this class. |
| |
| \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor() |
| */ |
| QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const |
| { |
| if (uint(index) < d->constructors.size()) |
| return QMetaMethodBuilder(this, -(index + 1)); |
| else |
| return QMetaMethodBuilder(); |
| } |
| |
| /*! |
| Returns the property at \a index in this class. |
| |
| \sa methodCount(), addMethod(), removeMethod(), indexOfProperty() |
| */ |
| QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const |
| { |
| if (uint(index) < d->properties.size()) |
| return QMetaPropertyBuilder(this, index); |
| else |
| return QMetaPropertyBuilder(); |
| } |
| |
| /*! |
| Returns the enumerator at \a index in this class. |
| |
| \sa enumeratorCount(), addEnumerator(), removeEnumerator() |
| \sa indexOfEnumerator() |
| */ |
| QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const |
| { |
| if (uint(index) < d->enumerators.size()) |
| return QMetaEnumBuilder(this, index); |
| else |
| return QMetaEnumBuilder(); |
| } |
| |
| /*! |
| Returns the related meta object at \a index in this class. |
| |
| Related meta objects are used when resolving the enumerated type |
| associated with a property, where the enumerated type is in a |
| different class from the property. |
| |
| \sa relatedMetaObjectCount(), addRelatedMetaObject() |
| \sa removeRelatedMetaObject() |
| */ |
| const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const |
| { |
| if (index >= 0 && index < d->relatedMetaObjects.size()) |
| return d->relatedMetaObjects[index]; |
| else |
| return 0; |
| } |
| |
| /*! |
| Returns the name of the item of class information at \a index |
| in this class. |
| |
| \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo() |
| \sa indexOfClassInfo() |
| */ |
| QByteArray QMetaObjectBuilder::classInfoName(int index) const |
| { |
| if (index >= 0 && index < d->classInfoNames.size()) |
| return d->classInfoNames[index]; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Returns the value of the item of class information at \a index |
| in this class. |
| |
| \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo() |
| \sa indexOfClassInfo() |
| */ |
| QByteArray QMetaObjectBuilder::classInfoValue(int index) const |
| { |
| if (index >= 0 && index < d->classInfoValues.size()) |
| return d->classInfoValues[index]; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Removes the method at \a index from this class. The indices of |
| all following methods will be adjusted downwards by 1. If the |
| method is registered as a notify signal on a property, then the |
| notify signal will be removed from the property. |
| |
| \sa methodCount(), addMethod(), method(), indexOfMethod() |
| */ |
| void QMetaObjectBuilder::removeMethod(int index) |
| { |
| if (uint(index) < d->methods.size()) { |
| d->methods.erase(d->methods.begin() + index); |
| for (auto &property : d->properties) { |
| // Adjust the indices of property notify signal references. |
| if (property.notifySignal == index) { |
| property.notifySignal = -1; |
| property.setFlag(Notify, false); |
| } else if (property.notifySignal > index) |
| property.notifySignal--; |
| } |
| } |
| } |
| |
| /*! |
| Removes the constructor at \a index from this class. The indices of |
| all following constructors will be adjusted downwards by 1. |
| |
| \sa constructorCount(), addConstructor(), constructor() |
| \sa indexOfConstructor() |
| */ |
| void QMetaObjectBuilder::removeConstructor(int index) |
| { |
| if (uint(index) < d->constructors.size()) |
| d->constructors.erase(d->constructors.begin() + index); |
| } |
| |
| /*! |
| Removes the property at \a index from this class. The indices of |
| all following properties will be adjusted downwards by 1. |
| |
| \sa propertyCount(), addProperty(), property(), indexOfProperty() |
| */ |
| void QMetaObjectBuilder::removeProperty(int index) |
| { |
| if (uint(index) < d->properties.size()) |
| d->properties.erase(d->properties.begin() + index); |
| } |
| |
| /*! |
| Removes the enumerator at \a index from this class. The indices of |
| all following enumerators will be adjusted downwards by 1. |
| |
| \sa enumertorCount(), addEnumerator(), enumerator() |
| \sa indexOfEnumerator() |
| */ |
| void QMetaObjectBuilder::removeEnumerator(int index) |
| { |
| if (uint(index) < d->enumerators.size()) |
| d->enumerators.erase(d->enumerators.begin() + index); |
| } |
| |
| /*! |
| Removes the item of class information at \a index from this class. |
| The indices of all following items will be adjusted downwards by 1. |
| |
| \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue() |
| \sa indexOfClassInfo() |
| */ |
| void QMetaObjectBuilder::removeClassInfo(int index) |
| { |
| if (index >= 0 && index < d->classInfoNames.size()) { |
| d->classInfoNames.removeAt(index); |
| d->classInfoValues.removeAt(index); |
| } |
| } |
| |
| /*! |
| Removes the related meta object at \a index from this class. |
| The indices of all following related meta objects will be adjusted |
| downwards by 1. |
| |
| Related meta objects are used when resolving the enumerated type |
| associated with a property, where the enumerated type is in a |
| different class from the property. |
| |
| \sa relatedMetaObjectCount(), addRelatedMetaObject() |
| \sa relatedMetaObject() |
| */ |
| void QMetaObjectBuilder::removeRelatedMetaObject(int index) |
| { |
| if (index >= 0 && index < d->relatedMetaObjects.size()) |
| d->relatedMetaObjects.removeAt(index); |
| } |
| |
| /*! |
| Finds a method with the specified \a signature and returns its index; |
| otherwise returns -1. The \a signature will be normalized by this method. |
| |
| \sa method(), methodCount(), addMethod(), removeMethod() |
| */ |
| int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature) |
| { |
| QByteArray sig = QMetaObject::normalizedSignature(signature); |
| for (const auto &method : d->methods) { |
| if (sig == method.signature) |
| return int(&method - &d->methods.front()); |
| } |
| return -1; |
| } |
| |
| /*! |
| Finds a signal with the specified \a signature and returns its index; |
| otherwise returns -1. The \a signature will be normalized by this method. |
| |
| \sa indexOfMethod(), indexOfSlot() |
| */ |
| int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature) |
| { |
| QByteArray sig = QMetaObject::normalizedSignature(signature); |
| for (const auto &method : d->methods) { |
| if (method.methodType() == QMetaMethod::Signal && sig == method.signature) |
| return int(&method - &d->methods.front()); |
| } |
| return -1; |
| } |
| |
| /*! |
| Finds a slot with the specified \a signature and returns its index; |
| otherwise returns -1. The \a signature will be normalized by this method. |
| |
| \sa indexOfMethod(), indexOfSignal() |
| */ |
| int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature) |
| { |
| QByteArray sig = QMetaObject::normalizedSignature(signature); |
| for (const auto &method : d->methods) { |
| if (method.methodType() == QMetaMethod::Slot && sig == method.signature) |
| return int(&method - &d->methods.front()); |
| } |
| return -1; |
| } |
| |
| /*! |
| Finds a constructor with the specified \a signature and returns its index; |
| otherwise returns -1. The \a signature will be normalized by this method. |
| |
| \sa constructor(), constructorCount(), addConstructor(), removeConstructor() |
| */ |
| int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature) |
| { |
| QByteArray sig = QMetaObject::normalizedSignature(signature); |
| for (const auto &constructor : d->constructors) { |
| if (sig == constructor.signature) |
| return int(&constructor - &d->constructors.front()); |
| } |
| return -1; |
| } |
| |
| /*! |
| Finds a property with the specified \a name and returns its index; |
| otherwise returns -1. |
| |
| \sa property(), propertyCount(), addProperty(), removeProperty() |
| */ |
| int QMetaObjectBuilder::indexOfProperty(const QByteArray& name) |
| { |
| for (const auto &property : d->properties) { |
| if (name == property.name) |
| return int(&property - &d->properties.front()); |
| } |
| return -1; |
| } |
| |
| /*! |
| Finds an enumerator with the specified \a name and returns its index; |
| otherwise returns -1. |
| |
| \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator() |
| */ |
| int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name) |
| { |
| for (const auto &enumerator : d->enumerators) { |
| if (name == enumerator.name) |
| return int(&enumerator - &d->enumerators.front()); |
| } |
| return -1; |
| } |
| |
| /*! |
| Finds an item of class information with the specified \a name and |
| returns its index; otherwise returns -1. |
| |
| \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo() |
| \sa removeClassInfo() |
| */ |
| int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name) |
| { |
| for (int index = 0; index < d->classInfoNames.size(); ++index) { |
| if (name == d->classInfoNames[index]) |
| return index; |
| } |
| return -1; |
| } |
| |
| // Align on a specific type boundary. |
| #define ALIGN(size,type) \ |
| (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1) |
| |
| /*! |
| \class QMetaStringTable |
| \inmodule QtCore |
| \internal |
| \brief The QMetaStringTable class can generate a meta-object string table at runtime. |
| */ |
| |
| QMetaStringTable::QMetaStringTable(const QByteArray &className) |
| : m_index(0) |
| , m_className(className) |
| { |
| const int index = enter(m_className); |
| Q_ASSERT(index == 0); |
| Q_UNUSED(index); |
| } |
| |
| // Enters the given value into the string table (if it hasn't already been |
| // entered). Returns the index of the string. |
| int QMetaStringTable::enter(const QByteArray &value) |
| { |
| Entries::iterator it = m_entries.find(value); |
| if (it != m_entries.end()) |
| return it.value(); |
| int pos = m_index; |
| m_entries.insert(value, pos); |
| ++m_index; |
| return pos; |
| } |
| |
| int QMetaStringTable::preferredAlignment() |
| { |
| return Q_ALIGNOF(QByteArrayData); |
| } |
| |
| // Returns the size (in bytes) required for serializing this string table. |
| int QMetaStringTable::blobSize() const |
| { |
| int size = m_entries.size() * sizeof(QByteArrayData); |
| Entries::const_iterator it; |
| for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it) |
| size += it.key().size() + 1; |
| return size; |
| } |
| |
| static void writeString(char *out, int i, const QByteArray &str, |
| const int offsetOfStringdataMember, int &stringdataOffset) |
| { |
| int size = str.size(); |
| qptrdiff offset = offsetOfStringdataMember + stringdataOffset |
| - i * sizeof(QByteArrayData); |
| const QByteArrayData data = |
| Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset); |
| |
| memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData)); |
| |
| memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size); |
| out[offsetOfStringdataMember + stringdataOffset + size] = '\0'; |
| |
| stringdataOffset += size + 1; |
| } |
| |
| // Writes strings to string data struct. |
| // The struct consists of an array of QByteArrayData, followed by a char array |
| // containing the actual strings. This format must match the one produced by |
| // moc (see generator.cpp). |
| void QMetaStringTable::writeBlob(char *out) const |
| { |
| Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1))); |
| |
| int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData); |
| int stringdataOffset = 0; |
| |
| // qt_metacast expects the first string in the string table to be the class name. |
| writeString(out, /*index*/0, m_className, offsetOfStringdataMember, stringdataOffset); |
| |
| for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd(); |
| it != end; ++it) { |
| const int i = it.value(); |
| if (i == 0) |
| continue; |
| const QByteArray &str = it.key(); |
| |
| writeString(out, i, str, offsetOfStringdataMember, stringdataOffset); |
| } |
| } |
| |
| // Returns the sum of all parameters (including return type) for the given |
| // \a methods. This is needed for calculating the size of the methods' |
| // parameter type/name meta-data. |
| static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> &methods) |
| { |
| int sum = 0; |
| for (const auto &method : methods) |
| sum += method.parameterCount() + 1; // +1 for return type |
| return sum; |
| } |
| |
| // Build a QMetaObject in "buf" based on the information in "d". |
| // If "buf" is null, then return the number of bytes needed to |
| // build the QMetaObject. Returns -1 if the metaobject if |
| // relocatable is set, but the metaobject contains relatedMetaObjects. |
| static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, |
| int expectedSize, bool relocatable) |
| { |
| Q_UNUSED(expectedSize); // Avoid warning in release mode |
| int size = 0; |
| int dataIndex; |
| int paramsIndex; |
| int enumIndex; |
| int index; |
| bool hasRevisionedMethods = d->hasRevisionedMethods(); |
| bool hasRevisionedProperties = d->hasRevisionedProperties(); |
| bool hasNotifySignals = false; |
| |
| if (relocatable && |
| (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction)) |
| return -1; |
| |
| // Create the main QMetaObject structure at the start of the buffer. |
| QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf); |
| size += sizeof(QMetaObject); |
| ALIGN(size, int); |
| if (buf) { |
| if (!relocatable) meta->d.superdata = d->superClass; |
| meta->d.relatedMetaObjects = 0; |
| meta->d.extradata = 0; |
| meta->d.static_metacall = d->staticMetacallFunction; |
| } |
| |
| // Populate the QMetaObjectPrivate structure. |
| QMetaObjectPrivate *pmeta |
| = reinterpret_cast<QMetaObjectPrivate *>(buf + size); |
| int pmetaSize = size; |
| dataIndex = MetaObjectPrivateFieldCount; |
| for (const auto &property : d->properties) { |
| if (property.notifySignal != -1) { |
| hasNotifySignals = true; |
| break; |
| } |
| } |
| int methodParametersDataSize = |
| ((aggregateParameterCount(d->methods) |
| + aggregateParameterCount(d->constructors)) * 2) // types and parameter names |
| - int(d->methods.size()) // return "parameters" don't have names |
| - int(d->constructors.size()); // "this" parameters don't have names |
| if (buf) { |
| Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QMetaObjectBuilder should generate the same version as moc"); |
| pmeta->revision = QMetaObjectPrivate::OutputRevision; |
| pmeta->flags = d->flags; |
| pmeta->className = 0; // Class name is always the first string. |
| //pmeta->signalCount is handled in the "output method loop" as an optimization. |
| |
| pmeta->classInfoCount = d->classInfoNames.size(); |
| pmeta->classInfoData = dataIndex; |
| dataIndex += 2 * d->classInfoNames.size(); |
| |
| pmeta->methodCount = int(d->methods.size()); |
| pmeta->methodData = dataIndex; |
| dataIndex += 5 * int(d->methods.size()); |
| if (hasRevisionedMethods) |
| dataIndex += int(d->methods.size()); |
| paramsIndex = dataIndex; |
| dataIndex += methodParametersDataSize; |
| |
| pmeta->propertyCount = int(d->properties.size()); |
| pmeta->propertyData = dataIndex; |
| dataIndex += 3 * int(d->properties.size()); |
| if (hasNotifySignals) |
| dataIndex += int(d->properties.size()); |
| if (hasRevisionedProperties) |
| dataIndex += int(d->properties.size()); |
| |
| pmeta->enumeratorCount = int(d->enumerators.size()); |
| pmeta->enumeratorData = dataIndex; |
| dataIndex += 5 * int(d->enumerators.size()); |
| |
| pmeta->constructorCount = int(d->constructors.size()); |
| pmeta->constructorData = dataIndex; |
| dataIndex += 5 * int(d->constructors.size()); |
| } else { |
| dataIndex += 2 * int(d->classInfoNames.size()); |
| dataIndex += 5 * int(d->methods.size()); |
| if (hasRevisionedMethods) |
| dataIndex += int(d->methods.size()); |
| paramsIndex = dataIndex; |
| dataIndex += methodParametersDataSize; |
| dataIndex += 3 * int(d->properties.size()); |
| if (hasNotifySignals) |
| dataIndex += int(d->properties.size()); |
| if (hasRevisionedProperties) |
| dataIndex += int(d->properties.size()); |
| dataIndex += 5 * int(d->enumerators.size()); |
| dataIndex += 5 * int(d->constructors.size()); |
| } |
| |
| // Allocate space for the enumerator key names and values. |
| enumIndex = dataIndex; |
| for (const auto &enumerator : d->enumerators) |
| dataIndex += 2 * enumerator.keys.size(); |
| |
| // Zero terminator at the end of the data offset table. |
| ++dataIndex; |
| |
| // Find the start of the data and string tables. |
| int *data = reinterpret_cast<int *>(pmeta); |
| size += dataIndex * sizeof(int); |
| ALIGN(size, void *); |
| char *str = reinterpret_cast<char *>(buf + size); |
| if (buf) { |
| if (relocatable) { |
| meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size); |
| meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize); |
| } else { |
| meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str); |
| meta->d.data = reinterpret_cast<uint *>(data); |
| } |
| } |
| |
| // Reset the current data position to just past the QMetaObjectPrivate. |
| dataIndex = MetaObjectPrivateFieldCount; |
| |
| QMetaStringTable strings(d->className); |
| |
| // Output the class infos, |
| Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); |
| for (index = 0; index < d->classInfoNames.size(); ++index) { |
| int name = strings.enter(d->classInfoNames[index]); |
| int value = strings.enter(d->classInfoValues[index]); |
| if (buf) { |
| data[dataIndex] = name; |
| data[dataIndex + 1] = value; |
| } |
| dataIndex += 2; |
| } |
| |
| // Output the methods in the class. |
| Q_ASSERT(!buf || dataIndex == pmeta->methodData); |
| for (const auto &method : d->methods) { |
| int name = strings.enter(method.name()); |
| int argc = method.parameterCount(); |
| int tag = strings.enter(method.tag); |
| int attrs = method.attributes; |
| if (buf) { |
| data[dataIndex] = name; |
| data[dataIndex + 1] = argc; |
| data[dataIndex + 2] = paramsIndex; |
| data[dataIndex + 3] = tag; |
| data[dataIndex + 4] = attrs; |
| if (method.methodType() == QMetaMethod::Signal) |
| pmeta->signalCount++; |
| } |
| dataIndex += 5; |
| paramsIndex += 1 + argc * 2; |
| } |
| if (hasRevisionedMethods) { |
| for (const auto &method : d->methods) { |
| if (buf) |
| data[dataIndex] = method.revision; |
| ++dataIndex; |
| } |
| } |
| |
| // Output the method parameters in the class. |
| Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * 5 |
| + (hasRevisionedMethods ? int(d->methods.size()) : 0)); |
| for (int x = 0; x < 2; ++x) { |
| const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors; |
| for (const auto &method : methods) { |
| const QList<QByteArray> paramTypeNames = method.parameterTypes(); |
| int paramCount = paramTypeNames.size(); |
| for (int i = -1; i < paramCount; ++i) { |
| const QByteArray &typeName = (i < 0) ? method.returnType : paramTypeNames.at(i); |
| int typeInfo; |
| if (QtPrivate::isBuiltinType(typeName)) |
| typeInfo = QMetaType::type(typeName); |
| else |
| typeInfo = IsUnresolvedType | strings.enter(typeName); |
| if (buf) |
| data[dataIndex] = typeInfo; |
| ++dataIndex; |
| } |
| |
| QList<QByteArray> paramNames = method.parameterNames; |
| while (paramNames.size() < paramCount) |
| paramNames.append(QByteArray()); |
| for (int i = 0; i < paramCount; ++i) { |
| int stringIndex = strings.enter(paramNames.at(i)); |
| if (buf) |
| data[dataIndex] = stringIndex; |
| ++dataIndex; |
| } |
| } |
| } |
| |
| // Output the properties in the class. |
| Q_ASSERT(!buf || dataIndex == pmeta->propertyData); |
| for (const auto &prop : d->properties) { |
| int name = strings.enter(prop.name); |
| |
| int typeInfo; |
| if (QtPrivate::isBuiltinType(prop.type)) |
| typeInfo = QMetaType::type(prop.type); |
| else |
| typeInfo = IsUnresolvedType | strings.enter(prop.type); |
| |
| int flags = prop.flags; |
| |
| if (!QtPrivate::isBuiltinType(prop.type)) |
| flags |= EnumOrFlag; |
| |
| if (buf) { |
| data[dataIndex] = name; |
| data[dataIndex + 1] = typeInfo; |
| data[dataIndex + 2] = flags; |
| } |
| dataIndex += 3; |
| } |
| if (hasNotifySignals) { |
| for (const auto &prop : d->properties) { |
| if (buf) { |
| if (prop.notifySignal != -1) |
| data[dataIndex] = prop.notifySignal; |
| else |
| data[dataIndex] = 0; |
| } |
| ++dataIndex; |
| } |
| } |
| if (hasRevisionedProperties) { |
| for (const auto &prop : d->properties) { |
| if (buf) |
| data[dataIndex] = prop.revision; |
| ++dataIndex; |
| } |
| } |
| |
| // Output the enumerators in the class. |
| Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData); |
| for (const auto &enumerator : d->enumerators) { |
| int name = strings.enter(enumerator.name); |
| int enumName = strings.enter(enumerator.enumName); |
| int isFlag = enumerator.isFlag ? EnumIsFlag : 0; |
| int isScoped = enumerator.isScoped ? EnumIsScoped : 0; |
| int count = enumerator.keys.size(); |
| int enumOffset = enumIndex; |
| if (buf) { |
| data[dataIndex] = name; |
| data[dataIndex + 1] = enumName; |
| data[dataIndex + 2] = isFlag | isScoped; |
| data[dataIndex + 3] = count; |
| data[dataIndex + 4] = enumOffset; |
| } |
| for (int key = 0; key < count; ++key) { |
| int keyIndex = strings.enter(enumerator.keys[key]); |
| if (buf) { |
| data[enumOffset++] = keyIndex; |
| data[enumOffset++] = enumerator.values[key]; |
| } |
| } |
| dataIndex += 5; |
| enumIndex += 2 * count; |
| } |
| |
| // Output the constructors in the class. |
| Q_ASSERT(!buf || dataIndex == pmeta->constructorData); |
| for (const auto &ctor : d->constructors) { |
| int name = strings.enter(ctor.name()); |
| int argc = ctor.parameterCount(); |
| int tag = strings.enter(ctor.tag); |
| int attrs = ctor.attributes; |
| if (buf) { |
| data[dataIndex] = name; |
| data[dataIndex + 1] = argc; |
| data[dataIndex + 2] = paramsIndex; |
| data[dataIndex + 3] = tag; |
| data[dataIndex + 4] = attrs; |
| } |
| dataIndex += 5; |
| paramsIndex += 1 + argc * 2; |
| } |
| |
| size += strings.blobSize(); |
| |
| if (buf) |
| strings.writeBlob(str); |
| |
| // Output the zero terminator in the data array. |
| if (buf) |
| data[enumIndex] = 0; |
| |
| // Create the relatedMetaObjects block if we need one. |
| if (d->relatedMetaObjects.size() > 0) { |
| using SuperData = QMetaObject::SuperData; |
| ALIGN(size, SuperData); |
| auto objects = reinterpret_cast<SuperData *>(buf + size); |
| if (buf) { |
| meta->d.relatedMetaObjects = objects; |
| for (index = 0; index < d->relatedMetaObjects.size(); ++index) |
| objects[index] = d->relatedMetaObjects[index]; |
| objects[index] = nullptr; |
| } |
| size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1); |
| } |
| |
| // Align the final size and return it. |
| ALIGN(size, void *); |
| Q_ASSERT(!buf || size == expectedSize); |
| return size; |
| } |
| |
| /*! |
| Converts this meta object builder into a concrete QMetaObject. |
| The return value should be deallocated using free() once it |
| is no longer needed. |
| |
| The returned meta object is a snapshot of the state of the |
| QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder |
| will not be reflected in previous meta objects returned by |
| this method. |
| */ |
| QMetaObject *QMetaObjectBuilder::toMetaObject() const |
| { |
| int size = buildMetaObject(d, 0, 0, false); |
| char *buf = reinterpret_cast<char *>(malloc(size)); |
| memset(buf, 0, size); |
| buildMetaObject(d, buf, size, false); |
| return reinterpret_cast<QMetaObject *>(buf); |
| } |
| |
| /* |
| \internal |
| |
| Converts this meta object builder into relocatable data. This data can |
| be stored, copied and later passed to fromRelocatableData() to create a |
| concrete QMetaObject. |
| |
| The data is specific to the architecture on which it was created, but is not |
| specific to the process that created it. Not all meta object builder's can |
| be converted to data in this way. If \a ok is provided, it will be set to |
| true if the conversion succeeds, and false otherwise. If a |
| staticMetacallFunction() or any relatedMetaObject()'s are specified the |
| conversion to relocatable data will fail. |
| */ |
| QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const |
| { |
| int size = buildMetaObject(d, 0, 0, true); |
| if (size == -1) { |
| if (ok) *ok = false; |
| return QByteArray(); |
| } |
| |
| QByteArray data; |
| data.resize(size); |
| char *buf = data.data(); |
| memset(buf, 0, size); |
| buildMetaObject(d, buf, size, true); |
| if (ok) *ok = true; |
| return data; |
| } |
| |
| /* |
| \internal |
| |
| Sets the \a data returned from toRelocatableData() onto a concrete |
| QMetaObject instance, \a output. As the meta object's super class is not |
| saved in the relocatable data, it must be passed as \a superClass. |
| */ |
| void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output, |
| const QMetaObject *superclass, |
| const QByteArray &data) |
| { |
| if (!output) |
| return; |
| |
| const char *buf = data.constData(); |
| const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf); |
| |
| quintptr stringdataOffset = (quintptr)dataMo->d.stringdata; |
| quintptr dataOffset = (quintptr)dataMo->d.data; |
| |
| output->d.superdata = superclass; |
| output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset); |
| output->d.data = reinterpret_cast<const uint *>(buf + dataOffset); |
| output->d.extradata = 0; |
| output->d.relatedMetaObjects = 0; |
| output->d.static_metacall = 0; |
| } |
| |
| /*! |
| \typedef QMetaObjectBuilder::StaticMetacallFunction |
| |
| Typedef for static metacall functions. The three parameters are |
| the call type value, the constructor index, and the |
| array of parameters. |
| */ |
| |
| /*! |
| Returns the static metacall function to use to construct objects |
| of this class. The default value is null. |
| |
| \sa setStaticMetacallFunction() |
| */ |
| QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const |
| { |
| return d->staticMetacallFunction; |
| } |
| |
| /*! |
| Sets the static metacall function to use to construct objects |
| of this class to \a value. The default value is null. |
| |
| \sa staticMetacallFunction() |
| */ |
| void QMetaObjectBuilder::setStaticMetacallFunction |
| (QMetaObjectBuilder::StaticMetacallFunction value) |
| { |
| d->staticMetacallFunction = value; |
| } |
| |
| #ifndef QT_NO_DATASTREAM |
| |
| /*! |
| Serializes the contents of the meta object builder onto \a stream. |
| |
| \sa deserialize() |
| */ |
| void QMetaObjectBuilder::serialize(QDataStream& stream) const |
| { |
| int index; |
| |
| // Write the class and super class names. |
| stream << d->className; |
| if (d->superClass) |
| stream << QByteArray(d->superClass->className()); |
| else |
| stream << QByteArray(); |
| |
| // Write the counts for each type of class member. |
| stream << d->classInfoNames.size(); |
| stream << int(d->methods.size()); |
| stream << int(d->properties.size()); |
| stream << int(d->enumerators.size()); |
| stream << int(d->constructors.size()); |
| stream << d->relatedMetaObjects.size(); |
| |
| // Write the items of class information. |
| for (index = 0; index < d->classInfoNames.size(); ++index) { |
| stream << d->classInfoNames[index]; |
| stream << d->classInfoValues[index]; |
| } |
| |
| // Write the methods. |
| for (const auto &method : d->methods) { |
| stream << method.signature; |
| stream << method.returnType; |
| stream << method.parameterNames; |
| stream << method.tag; |
| stream << method.attributes; |
| if (method.revision) |
| stream << method.revision; |
| } |
| |
| // Write the properties. |
| for (const auto &property : d->properties) { |
| stream << property.name; |
| stream << property.type; |
| stream << property.flags; |
| stream << property.notifySignal; |
| if (property.revision) |
| stream << property.revision; |
| } |
| |
| // Write the enumerators. |
| for (const auto &enumerator : d->enumerators) { |
| stream << enumerator.name; |
| stream << enumerator.isFlag; |
| stream << enumerator.isScoped; |
| stream << enumerator.keys; |
| stream << enumerator.values; |
| } |
| |
| // Write the constructors. |
| for (const auto &ctor : d->constructors) { |
| stream << ctor.signature; |
| stream << ctor.returnType; |
| stream << ctor.parameterNames; |
| stream << ctor.tag; |
| stream << ctor.attributes; |
| } |
| |
| // Write the related meta objects. |
| for (index = 0; index < d->relatedMetaObjects.size(); ++index) { |
| const QMetaObject *meta = d->relatedMetaObjects[index]; |
| stream << QByteArray(meta->className()); |
| } |
| |
| // Add an extra empty QByteArray for additional data in future versions. |
| // This should help maintain backwards compatibility, allowing older |
| // versions to read newer data. |
| stream << QByteArray(); |
| } |
| |
| // Resolve a class name using the name reference map. |
| static const QMetaObject *resolveClassName |
| (const QMap<QByteArray, const QMetaObject *>& references, |
| const QByteArray& name) |
| { |
| if (name == QByteArray("QObject")) |
| return &QObject::staticMetaObject; |
| else |
| return references.value(name, 0); |
| } |
| |
| /*! |
| Deserializes a meta object builder from \a stream into |
| this meta object builder. |
| |
| The \a references parameter specifies a mapping from class names |
| to QMetaObject instances for resolving the super class name and |
| related meta objects in the object that is deserialized. |
| The meta object for QObject is implicitly added to \a references |
| and does not need to be supplied. |
| |
| The QDataStream::status() value on \a stream will be set to |
| QDataStream::ReadCorruptData if the input data is corrupt. |
| The status will be set to QDataStream::ReadPastEnd if the |
| input was exhausted before the full meta object was read. |
| |
| \sa serialize() |
| */ |
| void QMetaObjectBuilder::deserialize |
| (QDataStream& stream, |
| const QMap<QByteArray, const QMetaObject *>& references) |
| { |
| QByteArray name; |
| const QMetaObject *cl; |
| int index; |
| |
| // Clear all members in the builder to their default states. |
| d->className.clear(); |
| d->superClass = &QObject::staticMetaObject; |
| d->classInfoNames.clear(); |
| d->classInfoValues.clear(); |
| d->methods.clear(); |
| d->properties.clear(); |
| d->enumerators.clear(); |
| d->constructors.clear(); |
| d->relatedMetaObjects.clear(); |
| d->staticMetacallFunction = 0; |
| |
| // Read the class and super class names. |
| stream >> d->className; |
| stream >> name; |
| if (name.isEmpty()) { |
| d->superClass = 0; |
| } else if ((cl = resolveClassName(references, name)) != 0) { |
| d->superClass = cl; |
| } else { |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| |
| // Read the counts for each type of class member. |
| int classInfoCount, methodCount, propertyCount; |
| int enumeratorCount, constructorCount, relatedMetaObjectCount; |
| stream >> classInfoCount; |
| stream >> methodCount; |
| stream >> propertyCount; |
| stream >> enumeratorCount; |
| stream >> constructorCount; |
| stream >> relatedMetaObjectCount; |
| if (classInfoCount < 0 || methodCount < 0 || |
| propertyCount < 0 || enumeratorCount < 0 || |
| constructorCount < 0 || relatedMetaObjectCount < 0) { |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| |
| // Read the items of class information. |
| for (index = 0; index < classInfoCount; ++index) { |
| if (stream.status() != QDataStream::Ok) |
| return; |
| QByteArray value; |
| stream >> name; |
| stream >> value; |
| addClassInfo(name, value); |
| } |
| |
| // Read the member methods. |
| for (index = 0; index < methodCount; ++index) { |
| if (stream.status() != QDataStream::Ok) |
| return; |
| stream >> name; |
| addMethod(name); |
| QMetaMethodBuilderPrivate &method = d->methods[index]; |
| stream >> method.returnType; |
| stream >> method.parameterNames; |
| stream >> method.tag; |
| stream >> method.attributes; |
| if (method.attributes & MethodRevisioned) |
| stream >> method.revision; |
| if (method.methodType() == QMetaMethod::Constructor) { |
| // Cannot add a constructor in this set of methods. |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| } |
| |
| // Read the properties. |
| for (index = 0; index < propertyCount; ++index) { |
| if (stream.status() != QDataStream::Ok) |
| return; |
| QByteArray type; |
| stream >> name; |
| stream >> type; |
| addProperty(name, type); |
| QMetaPropertyBuilderPrivate &property = d->properties[index]; |
| stream >> property.flags; |
| stream >> property.notifySignal; |
| if (property.notifySignal < -1 || |
| property.notifySignal >= int(d->methods.size())) { |
| // Notify signal method index is out of range. |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| if (property.notifySignal >= 0 && |
| d->methods[property.notifySignal].methodType() != QMetaMethod::Signal) { |
| // Notify signal method index does not refer to a signal. |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| if (property.flags & Revisioned) |
| stream >> property.revision; |
| } |
| |
| // Read the enumerators. |
| for (index = 0; index < enumeratorCount; ++index) { |
| if (stream.status() != QDataStream::Ok) |
| return; |
| stream >> name; |
| addEnumerator(name); |
| QMetaEnumBuilderPrivate &enumerator = d->enumerators[index]; |
| stream >> enumerator.isFlag; |
| stream >> enumerator.isScoped; |
| stream >> enumerator.keys; |
| stream >> enumerator.values; |
| if (enumerator.keys.size() != enumerator.values.size()) { |
| // Mismatch between number of keys and number of values. |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| } |
| |
| // Read the constructor methods. |
| for (index = 0; index < constructorCount; ++index) { |
| if (stream.status() != QDataStream::Ok) |
| return; |
| stream >> name; |
| addConstructor(name); |
| QMetaMethodBuilderPrivate &method = d->constructors[index]; |
| stream >> method.returnType; |
| stream >> method.parameterNames; |
| stream >> method.tag; |
| stream >> method.attributes; |
| if (method.methodType() != QMetaMethod::Constructor) { |
| // The type must be Constructor. |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| } |
| |
| // Read the related meta objects. |
| for (index = 0; index < relatedMetaObjectCount; ++index) { |
| if (stream.status() != QDataStream::Ok) |
| return; |
| stream >> name; |
| cl = resolveClassName(references, name); |
| if (!cl) { |
| stream.setStatus(QDataStream::ReadCorruptData); |
| return; |
| } |
| addRelatedMetaObject(cl); |
| } |
| |
| // Read the extra data block, which is reserved for future use. |
| stream >> name; |
| } |
| |
| #endif // !QT_NO_DATASTREAM |
| |
| /*! |
| \class QMetaMethodBuilder |
| \inmodule QtCore |
| \internal |
| \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder. |
| */ |
| |
| QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const |
| { |
| // Positive indices indicate methods, negative indices indicate constructors. |
| if (_mobj && _index >= 0 && _index < int(_mobj->d->methods.size())) |
| return &(_mobj->d->methods[_index]); |
| else if (_mobj && -_index >= 1 && -_index <= int(_mobj->d->constructors.size())) |
| return &(_mobj->d->constructors[(-_index) - 1]); |
| else |
| return 0; |
| } |
| |
| /*! |
| \fn QMetaMethodBuilder::QMetaMethodBuilder() |
| \internal |
| */ |
| |
| /*! |
| Returns the index of this method within its QMetaObjectBuilder. |
| */ |
| int QMetaMethodBuilder::index() const |
| { |
| if (_index >= 0) |
| return _index; // Method, signal, or slot |
| else |
| return (-_index) - 1; // Constructor |
| } |
| |
| /*! |
| Returns the type of this method (signal, slot, method, or constructor). |
| */ |
| QMetaMethod::MethodType QMetaMethodBuilder::methodType() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->methodType(); |
| else |
| return QMetaMethod::Method; |
| } |
| |
| /*! |
| Returns the signature of this method. |
| |
| \sa parameterNames(), returnType() |
| */ |
| QByteArray QMetaMethodBuilder::signature() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->signature; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Returns the return type for this method; empty if the method's |
| return type is \c{void}. |
| |
| \sa setReturnType(), signature() |
| */ |
| QByteArray QMetaMethodBuilder::returnType() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->returnType; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Sets the return type for this method to \a value. If \a value |
| is empty, then the method's return type is \c{void}. The \a value |
| will be normalized before it is added to the method. |
| |
| \sa returnType(), parameterTypes(), signature() |
| */ |
| void QMetaMethodBuilder::setReturnType(const QByteArray& value) |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| d->returnType = QMetaObject::normalizedType(value); |
| } |
| |
| /*! |
| Returns the list of parameter types for this method. |
| |
| \sa returnType(), parameterNames() |
| */ |
| QList<QByteArray> QMetaMethodBuilder::parameterTypes() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->parameterTypes(); |
| else |
| return QList<QByteArray>(); |
| } |
| |
| /*! |
| Returns the list of parameter names for this method. |
| |
| \sa setParameterNames() |
| */ |
| QList<QByteArray> QMetaMethodBuilder::parameterNames() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->parameterNames; |
| else |
| return QList<QByteArray>(); |
| } |
| |
| /*! |
| Sets the list of parameter names for this method to \a value. |
| |
| \sa parameterNames() |
| */ |
| void QMetaMethodBuilder::setParameterNames(const QList<QByteArray>& value) |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| d->parameterNames = value; |
| } |
| |
| /*! |
| Returns the tag associated with this method. |
| |
| \sa setTag() |
| */ |
| QByteArray QMetaMethodBuilder::tag() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->tag; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Sets the tag associated with this method to \a value. |
| |
| \sa setTag() |
| */ |
| void QMetaMethodBuilder::setTag(const QByteArray& value) |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| d->tag = value; |
| } |
| |
| /*! |
| Returns the access specification of this method (private, protected, |
| or public). The default value is QMetaMethod::Public for methods, |
| slots, signals and constructors. |
| |
| \sa setAccess() |
| */ |
| QMetaMethod::Access QMetaMethodBuilder::access() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->access(); |
| else |
| return QMetaMethod::Public; |
| } |
| |
| /*! |
| Sets the access specification of this method (private, protected, |
| or public) to \a value. If the method is a signal, this function |
| will be ignored. |
| |
| \sa access() |
| */ |
| void QMetaMethodBuilder::setAccess(QMetaMethod::Access value) |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d && d->methodType() != QMetaMethod::Signal) |
| d->setAccess(value); |
| } |
| |
| /*! |
| Returns the additional attributes for this method. |
| |
| \sa setAttributes() |
| */ |
| int QMetaMethodBuilder::attributes() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return (d->attributes >> 4); |
| else |
| return 0; |
| } |
| |
| /*! |
| Sets the additional attributes for this method to \a value. |
| |
| \sa attributes() |
| */ |
| void QMetaMethodBuilder::setAttributes(int value) |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| d->attributes = ((d->attributes & 0x0f) | (value << 4)); |
| } |
| |
| /*! |
| Returns the revision of this method. |
| |
| \sa setRevision() |
| */ |
| int QMetaMethodBuilder::revision() const |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) |
| return d->revision; |
| return 0; |
| |
| } |
| |
| /*! |
| Sets the \a revision of this method. |
| |
| \sa revision() |
| */ |
| void QMetaMethodBuilder::setRevision(int revision) |
| { |
| QMetaMethodBuilderPrivate *d = d_func(); |
| if (d) { |
| d->revision = revision; |
| if (revision) |
| d->attributes |= MethodRevisioned; |
| else |
| d->attributes &= ~MethodRevisioned; |
| } |
| } |
| |
| /*! |
| \class QMetaPropertyBuilder |
| \inmodule QtCore |
| \internal |
| \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder. |
| */ |
| |
| QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const |
| { |
| if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size())) |
| return &(_mobj->d->properties[_index]); |
| else |
| return 0; |
| } |
| |
| /*! |
| \fn QMetaPropertyBuilder::QMetaPropertyBuilder() |
| \internal |
| */ |
| |
| /*! |
| \fn int QMetaPropertyBuilder::index() const |
| |
| Returns the index of this property within its QMetaObjectBuilder. |
| */ |
| |
| /*! |
| Returns the name associated with this property. |
| |
| \sa type() |
| */ |
| QByteArray QMetaPropertyBuilder::name() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->name; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Returns the type associated with this property. |
| |
| \sa name() |
| */ |
| QByteArray QMetaPropertyBuilder::type() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->type; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Returns \c true if this property has a notify signal; false otherwise. |
| |
| \sa notifySignal(), setNotifySignal(), removeNotifySignal() |
| */ |
| bool QMetaPropertyBuilder::hasNotifySignal() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Notify); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns the notify signal associated with this property. |
| |
| \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal() |
| */ |
| QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d && d->notifySignal >= 0) |
| return QMetaMethodBuilder(_mobj, d->notifySignal); |
| else |
| return QMetaMethodBuilder(); |
| } |
| |
| /*! |
| Sets the notify signal associated with this property to \a value. |
| |
| \sa hasNotifySignal(), notifySignal(), removeNotifySignal() |
| */ |
| void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder& value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) { |
| if (value._mobj) { |
| d->notifySignal = value._index; |
| d->setFlag(Notify, true); |
| } else { |
| d->notifySignal = -1; |
| d->setFlag(Notify, false); |
| } |
| } |
| } |
| |
| /*! |
| Removes the notify signal from this property. |
| |
| \sa hasNotifySignal(), notifySignal(), setNotifySignal() |
| */ |
| void QMetaPropertyBuilder::removeNotifySignal() |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) { |
| d->notifySignal = -1; |
| d->setFlag(Notify, false); |
| } |
| } |
| |
| /*! |
| Returns \c true if this property is readable; otherwise returns \c false. |
| The default value is true. |
| |
| \sa setReadable(), isWritable() |
| */ |
| bool QMetaPropertyBuilder::isReadable() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Readable); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if this property is writable; otherwise returns \c false. |
| The default value is true. |
| |
| \sa setWritable(), isReadable() |
| */ |
| bool QMetaPropertyBuilder::isWritable() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Writable); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if this property can be reset to a default value; otherwise |
| returns \c false. The default value is false. |
| |
| \sa setResettable() |
| */ |
| bool QMetaPropertyBuilder::isResettable() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Resettable); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if this property is designable; otherwise returns \c false. |
| This default value is false. |
| |
| \sa setDesignable(), isScriptable(), isStored() |
| */ |
| bool QMetaPropertyBuilder::isDesignable() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Designable); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property is scriptable; otherwise returns \c false. |
| This default value is true. |
| |
| \sa setScriptable(), isDesignable(), isStored() |
| */ |
| bool QMetaPropertyBuilder::isScriptable() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Scriptable); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property is stored; otherwise returns \c false. |
| This default value is false. |
| |
| \sa setStored(), isDesignable(), isScriptable() |
| */ |
| bool QMetaPropertyBuilder::isStored() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Stored); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property is editable; otherwise returns \c false. |
| This default value is false. |
| |
| \sa setEditable(), isDesignable(), isScriptable(), isStored() |
| */ |
| bool QMetaPropertyBuilder::isEditable() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Editable); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if this property is designated as the \c USER |
| property, i.e., the one that the user can edit or that is |
| significant in some other way. Otherwise it returns |
| false. This default value is false. |
| |
| \sa setUser(), isDesignable(), isScriptable() |
| */ |
| bool QMetaPropertyBuilder::isUser() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(User); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property has a C++ setter function that |
| follows Qt's standard "name" / "setName" pattern. Designer and uic |
| query hasStdCppSet() in order to avoid expensive |
| QObject::setProperty() calls. All properties in Qt [should] follow |
| this pattern. The default value is false. |
| |
| \sa setStdCppSet() |
| */ |
| bool QMetaPropertyBuilder::hasStdCppSet() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(StdCppSet); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property is an enumerator or flag type; |
| otherwise returns \c false. This default value is false. |
| |
| \sa setEnumOrFlag() |
| */ |
| bool QMetaPropertyBuilder::isEnumOrFlag() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(EnumOrFlag); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property is constant; otherwise returns \c false. |
| The default value is false. |
| */ |
| bool QMetaPropertyBuilder::isConstant() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Constant); |
| else |
| return false; |
| } |
| |
| /*! |
| Returns \c true if the property is final; otherwise returns \c false. |
| The default value is false. |
| */ |
| bool QMetaPropertyBuilder::isFinal() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->flag(Final); |
| else |
| return false; |
| } |
| |
| /*! |
| Sets this property to readable if \a value is true. |
| |
| \sa isReadable(), setWritable() |
| */ |
| void QMetaPropertyBuilder::setReadable(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Readable, value); |
| } |
| |
| /*! |
| Sets this property to writable if \a value is true. |
| |
| \sa isWritable(), setReadable() |
| */ |
| void QMetaPropertyBuilder::setWritable(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Writable, value); |
| } |
| |
| /*! |
| Sets this property to resettable if \a value is true. |
| |
| \sa isResettable() |
| */ |
| void QMetaPropertyBuilder::setResettable(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Resettable, value); |
| } |
| |
| /*! |
| Sets this property to designable if \a value is true. |
| |
| \sa isDesignable(), setScriptable(), setStored() |
| */ |
| void QMetaPropertyBuilder::setDesignable(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Designable, value); |
| } |
| |
| /*! |
| Sets this property to scriptable if \a value is true. |
| |
| \sa isScriptable(), setDesignable(), setStored() |
| */ |
| void QMetaPropertyBuilder::setScriptable(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Scriptable, value); |
| } |
| |
| /*! |
| Sets this property to storable if \a value is true. |
| |
| \sa isStored(), setDesignable(), setScriptable() |
| */ |
| void QMetaPropertyBuilder::setStored(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Stored, value); |
| } |
| |
| /*! |
| Sets this property to editable if \a value is true. |
| |
| \sa isEditable(), setDesignable(), setScriptable(), setStored() |
| */ |
| void QMetaPropertyBuilder::setEditable(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Editable, value); |
| } |
| |
| /*! |
| Sets the \c USER flag on this property to \a value. |
| |
| \sa isUser(), setDesignable(), setScriptable() |
| */ |
| void QMetaPropertyBuilder::setUser(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(User, value); |
| } |
| |
| /*! |
| Sets the C++ setter flag on this property to \a value, which is |
| true if the property has a C++ setter function that follows Qt's |
| standard "name" / "setName" pattern. |
| |
| \sa hasStdCppSet() |
| */ |
| void QMetaPropertyBuilder::setStdCppSet(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(StdCppSet, value); |
| } |
| |
| /*! |
| Sets this property to be of an enumerator or flag type if |
| \a value is true. |
| |
| \sa isEnumOrFlag() |
| */ |
| void QMetaPropertyBuilder::setEnumOrFlag(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(EnumOrFlag, value); |
| } |
| |
| /*! |
| Sets the \c CONSTANT flag on this property to \a value. |
| |
| \sa isConstant() |
| */ |
| void QMetaPropertyBuilder::setConstant(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Constant, value); |
| } |
| |
| /*! |
| Sets the \c FINAL flag on this property to \a value. |
| |
| \sa isFinal() |
| */ |
| void QMetaPropertyBuilder::setFinal(bool value) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| d->setFlag(Final, value); |
| } |
| |
| /*! |
| Returns the revision of this property. |
| |
| \sa setRevision() |
| */ |
| int QMetaPropertyBuilder::revision() const |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) |
| return d->revision; |
| return 0; |
| |
| } |
| |
| /*! |
| Sets the \a revision of this property. |
| |
| \sa revision() |
| */ |
| void QMetaPropertyBuilder::setRevision(int revision) |
| { |
| QMetaPropertyBuilderPrivate *d = d_func(); |
| if (d) { |
| d->revision = revision; |
| d->setFlag(Revisioned, revision != 0); |
| } |
| } |
| |
| |
| /*! |
| \class QMetaEnumBuilder |
| \inmodule QtCore |
| \internal |
| \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder. |
| */ |
| |
| QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const |
| { |
| if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size())) |
| return &(_mobj->d->enumerators[_index]); |
| else |
| return 0; |
| } |
| |
| /*! |
| \fn QMetaEnumBuilder::QMetaEnumBuilder() |
| \internal |
| */ |
| |
| /*! |
| \fn int QMetaEnumBuilder::index() const |
| |
| Returns the index of this enumerator within its QMetaObjectBuilder. |
| */ |
| |
| /*! |
| Returns the type name of the enumerator (without the scope). |
| */ |
| QByteArray QMetaEnumBuilder::name() const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| return d->name; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Returns the enum name of the enumerator (without the scope). |
| |
| \since 5.12 |
| */ |
| QByteArray QMetaEnumBuilder::enumName() const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| return d->enumName; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Sets this enumerator to have the enum name \c alias. |
| |
| \since 5.12 |
| \sa isFlag(), enumName() |
| */ |
| void QMetaEnumBuilder::setEnumName(const QByteArray &alias) |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| d->enumName = alias; |
| } |
| |
| /*! |
| Returns \c true if this enumerator is used as a flag; otherwise returns |
| false. |
| |
| \sa setIsFlag() |
| */ |
| bool QMetaEnumBuilder::isFlag() const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| return d->isFlag; |
| else |
| return false; |
| } |
| |
| /*! |
| Sets this enumerator to be used as a flag if \a value is true. |
| |
| \sa isFlag() |
| */ |
| void QMetaEnumBuilder::setIsFlag(bool value) |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| d->isFlag = value; |
| } |
| |
| /*! |
| Return \c true if this enumerator should be considered scoped (C++11 enum class). |
| |
| \sa setIsScoped() |
| */ |
| bool QMetaEnumBuilder::isScoped() const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| return d->isScoped; |
| return false; |
| } |
| |
| /*! |
| Sets this enumerator to be a scoped enum if \value is true |
| |
| \sa isScoped() |
| */ |
| void QMetaEnumBuilder::setIsScoped(bool value) |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| d->isScoped = value; |
| } |
| |
| /*! |
| Returns the number of keys. |
| |
| \sa key(), addKey() |
| */ |
| int QMetaEnumBuilder::keyCount() const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) |
| return d->keys.size(); |
| else |
| return 0; |
| } |
| |
| /*! |
| Returns the key with the given \a index, or an empty QByteArray |
| if no such key exists. |
| |
| \sa keyCount(), addKey(), value() |
| */ |
| QByteArray QMetaEnumBuilder::key(int index) const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d && index >= 0 && index < d->keys.size()) |
| return d->keys[index]; |
| else |
| return QByteArray(); |
| } |
| |
| /*! |
| Returns the value with the given \a index; or returns -1 if there |
| is no such value. |
| |
| \sa keyCount(), addKey(), key() |
| */ |
| int QMetaEnumBuilder::value(int index) const |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d && index >= 0 && index < d->keys.size()) |
| return d->values[index]; |
| else |
| return -1; |
| } |
| |
| /*! |
| Adds a new key called \a name to this enumerator, associated |
| with \a value. Returns the index of the new key. |
| |
| \sa keyCount(), key(), value(), removeKey() |
| */ |
| int QMetaEnumBuilder::addKey(const QByteArray& name, int value) |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d) { |
| int index = d->keys.size(); |
| d->keys += name; |
| d->values += value; |
| return index; |
| } else { |
| return -1; |
| } |
| } |
| |
| /*! |
| Removes the key at \a index from this enumerator. |
| |
| \sa addKey() |
| */ |
| void QMetaEnumBuilder::removeKey(int index) |
| { |
| QMetaEnumBuilderPrivate *d = d_func(); |
| if (d && index >= 0 && index < d->keys.size()) { |
| d->keys.removeAt(index); |
| d->values.removeAt(index); |
| } |
| } |
| |
| QT_END_NAMESPACE |