void tst_QMetaProperty::isFinal() { const QMetaObject *mo = metaObject(); QMetaProperty prop = mo->property(mo->indexOfProperty("value10")); QVERIFY(prop.isValid()); QVERIFY(prop.isFinal()); prop = mo->property(mo->indexOfProperty("value9")); QVERIFY(prop.isValid()); QVERIFY(!prop.isFinal()); }
void tst_QMetaProperty::hasStdCppSet() { QSKIP("Not supported by W_PROPERTY"); const QMetaObject *mo = metaObject(); QMetaProperty prop = mo->property(mo->indexOfProperty("value")); QVERIFY(prop.isValid()); QVERIFY(prop.hasStdCppSet()); prop = mo->property(mo->indexOfProperty("value2")); QVERIFY(prop.isValid()); QVERIFY(!prop.hasStdCppSet()); }
void AppSettings::keyChanged(const QString &key, const QVariant &value) { QMultiHash<QString,QObject*>::Iterator it = trackingKeyMap.find(key); for (; it != trackingKeyMap.end() && it.key() == key; ++it) { if (*it == keyChangeSource) continue; QMultiHash<QObject*,QPair<QString,int> >::Iterator objit = trackingObjectMap.find(*it); while (objit != trackingObjectMap.end() && objit->first != key) ++objit; int propid = (objit == trackingObjectMap.end()) ? -1 : objit->second; if (propid < 0) continue; QMetaProperty property = (*it)->metaObject()->property(propid); if (!property.isValid()) continue; /* Temporarily clear the property ID from this trackingObjectMap entry, used to ignore * the notification signal that may result from this property write */ objit->second = -1; bool ok = property.write(*it, value); objit->second = propid; if (!ok) { qWarning() << "AppSettings: Property write failed for object" << (*it)->objectName() << "of class" << (*it)->metaObject()->className() << "with key" << key; } } }
// --------------------------------------------------------------------------- // PosSettingsPushButtonItem:::restore // --------------------------------------------------------------------------- // void PosSettingsPushButtonItem::restore() { HbDataFormViewItem::restore(); if (mWidget) { HbDataFormModelItem::DataItemType itemType = static_cast<HbDataFormModelItem::DataItemType>( modelIndex().data(HbDataFormModelItem::ItemTypeRole).toInt()); if(itemType == PushButtonItem) { QModelIndex itemIndex = modelIndex(); HbDataFormModel *model = static_cast<HbDataFormModel*>(itemView()->model());; HbDataFormModelItem *modelItem = static_cast<HbDataFormModelItem*>( model->itemFromIndex(itemIndex)); const QMetaObject *metaObj = mWidget->metaObject(); int count = metaObj->propertyCount(); for (int i = 0; i < count; i++) { QMetaProperty metaProperty = metaObj->property(i); if (metaProperty.isValid() && metaProperty.isWritable()) { metaProperty.write(mWidget,modelItem->contentWidgetData(metaProperty.name())); } } } } }
void AppSettings::objectChanged(QObject *object, int index) { QMultiHash<QObject*,QPair<QString,int> >::Iterator it = trackingObjectMap.find(object), itstart = it; if (it == trackingObjectMap.end()) return; /* Index is the index of this property among the properties connected from this object. * In the QMultiHash, these are stored from the most-recently inserted to the least recently * inserted, so we need to invert the number and get the entry at that offset. */ int propCount = 0; for (; it != trackingObjectMap.end() && it.key() == object; ++it, ++propCount) ; /* First connection (index=0) is the last in the map (propCount-1) */ index = propCount - 1 - index; it = itstart + index; if (it->second < 0) return; QMetaProperty property = object->metaObject()->property(it->second); if (!property.isValid()) return; QObject *old = keyChangeSource; keyChangeSource = object; setValue(it->first, property.read(object)); keyChangeSource = old; }
bool UiExtractor::checkProperty(QObject *obj, const QString &prop) const { const QMetaObject *mo = obj->metaObject(); const QMetaProperty mp = mo->property(mo->indexOfProperty(prop.toLatin1())); // TODO come up with some more aggressive filtering if (mp.isValid() && mp.isDesignable(obj) && mp.isStored(obj) && mp.isWritable()) { const QVariant value = mp.read(obj); // try to figure out the default by resetting to it if (mp.isResettable()) { mp.reset(obj); if (mp.read(obj) == value) { return false; } mp.write(obj, value); return true; } // some guessing for non-resettable properties if (value.isNull() || !value.isValid()) { return false; } if (value.type() == QVariant::String) { return !value.toString().isEmpty(); } else if (value.type() == QVariant::Locale) { return value.value<QLocale>() != QLocale::system(); } return true; } return false; }
void ObjectEndPoint::propertyCall(const QServicePackage& p) { if(p.d->responseType == QServicePackage::NotAResponse) { //service side Q_ASSERT(d->endPointType == ObjectEndPoint::Service); QByteArray data = p.d->payload.toByteArray(); QDataStream stream(&data, QIODevice::ReadOnly); int metaIndex = -1; QVariant arg; int callType; stream >> metaIndex; stream >> arg; stream >> callType; const QMetaObject::Call c = (QMetaObject::Call) callType; QVariant result; QMetaProperty property = service->metaObject()->property(metaIndex); if (property.isValid()) { switch(c) { case QMetaObject::ReadProperty: result = property.read(service); break; case QMetaObject::WriteProperty: property.write(service, arg); break; case QMetaObject::ResetProperty: property.reset(service); break; default: break; } } if (c == QMetaObject::ReadProperty) { QServicePackage response = p.createResponse(); if (property.isValid()) { response.d->responseType = QServicePackage::Success; response.d->payload = result; } else { response.d->responseType = QServicePackage::Failed; } dispatch->writePackage(response); } } else {
void DataWidgetMapper::addMapping(QWidget *widget, int section) { QMetaProperty property = widget->metaObject()->userProperty(); Q_ASSERT(property.isValid()); QMetaMethod notifySignal = property.notifySignal(); Q_ASSERT(notifySignal.isValid()); connect(widget, notifySignal, this, QMetaMethod::fromSignal(&DataWidgetMapper::dataChanged)); QDataWidgetMapper::addMapping(widget, section); }
const char* getpropertytype(QObject* obj, const char* propname, bool includesuper) { const QMetaObject* objmeta = obj->metaObject(); int i = objmeta->indexOfProperty(propname); if (i == -1) return NULL; QMetaProperty propmeta = objmeta->property(i); if (!propmeta.isValid()) return NULL; const char* type = propmeta.typeName(); return type; }
void updateVisible() { bool newVisible = false; if (visibleProperty.isValid()) { Q_ASSERT(dialog.data()); newVisible = visibleProperty.read(dialog.data()).toBool(); } if (newVisible != visible) { visible = newVisible; emit q_ptr->visibleChanged(visible); } }
void tst_QMetaProperty::gadget() { const QMetaObject *mo = &MyGadget::staticMetaObject; QMetaProperty valueProp = mo->property(mo->indexOfProperty("value")); QVERIFY(valueProp.isValid()); { MyGadget g; QString hello = QLatin1Literal("hello"); QVERIFY(valueProp.writeOnGadget(&g, hello)); QCOMPARE(g.m_value, QLatin1String("hello")); QCOMPARE(valueProp.readOnGadget(&g), QVariant(hello)); QVERIFY(valueProp.resetOnGadget(&g)); QCOMPARE(valueProp.readOnGadget(&g), QVariant(QLatin1String("reset"))); } }
void SaxsviewProperty::setValue(QObject *obj) { if (!mProperty) { // // Find the meta-property information; the passed object must // provide the Q_PROPERTY name passed to the constructor. // int indexOfProperty = obj->metaObject()->indexOfProperty(qPrintable(mPropertyName)); QMetaProperty metaProperty = obj->metaObject()->property(indexOfProperty); if (metaProperty.isValid()) { // // Create an editor factory if and only if the property is writeable. // if (metaProperty.isWritable()) { mBrowser->setFactoryForManager(mManager, new QtVariantEditorFactory(this)); connect(mManager, SIGNAL(valueChanged(QtProperty*, const QVariant&)), this, SLOT(valueChanged(QtProperty*, const QVariant&))); } if (!mManager->isPropertyTypeSupported(metaProperty.type())) qFatal("internal error: property '%s', property type not supported: '%s'", metaProperty.name(), metaProperty.typeName()); // // Check if this is an enum and handle it specially if yes. // if (metaProperty.isEnumType()) { QStringList enumNames; QMetaEnum metaEnum = metaProperty.enumerator(); // // WARNING: This only builds a list of names in the order // as defined. The combobox to display these names // provides the selected index, not the actual enum // value. // for (int i = 0; i < metaEnum.keyCount(); ++i) enumNames << metaEnum.key(i); setEnumNames(enumNames); } if (mAttributes.contains("enumNames")) mProperty = mManager->addProperty(mManager->enumTypeId(), mPropertyLabel); else mProperty = mManager->addProperty(metaProperty.type(), mPropertyLabel); } else if (obj->dynamicPropertyNames().contains(qPrintable(mPropertyName))) {
QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name) { Q_ASSERT(value.canConvert<Enumeration>()); int propertyIndex = object()->metaObject()->indexOfProperty(name); QMetaProperty metaProperty = object()->metaObject()->property(propertyIndex); QVariant adjustedValue; Enumeration enumeration = value.value<Enumeration>(); if (metaProperty.isValid() && metaProperty.isEnumType()) { adjustedValue = metaProperty.enumerator().keyToValue(enumeration.name()); } else { QQmlExpression expression(context(), object(), enumeration.toString()); adjustedValue = expression.evaluate(); if (expression.hasError()) qDebug() << "Enumeration can not be evaluated:" << object() << name << enumeration; } return adjustedValue; }
void tst_QMetaProperty::conversion() { if (qVersion() < QByteArray("5.6.0")) QSKIP("this is a test for a bug in 5.5"); QMetaType::registerConverter<QString, CustomType>(); QMetaType::registerConverter<CustomType, QString>(); QString hello = QStringLiteral("Hello"); // Write to a QString property using a CustomType in a QVariant QMetaProperty value7P = metaObject()->property(metaObject()->indexOfProperty("value7")); QVERIFY(value7P.isValid()); QVERIFY(value7P.write(this, QVariant::fromValue(CustomType(hello)))); QCOMPARE(value7, hello); // Write to a CustomType property using a QString in a QVariant QMetaProperty customP = metaObject()->property(metaObject()->indexOfProperty("custom")); QVERIFY(customP.isValid()); QVERIFY(customP.write(this, hello)); QCOMPARE(custom.str, hello); // Something that cannot be converted should fail QVERIFY(!customP.write(this, 45)); QVERIFY(!customP.write(this, QVariant::fromValue(this))); QVERIFY(!value7P.write(this, QVariant::fromValue(this))); QVERIFY(!value7P.write(this, QVariant::fromValue<QObject*>(this))); // none of this should have changed the values QCOMPARE(value7, hello); QCOMPARE(custom.str, hello); // Empty variant should be converted to default object QVERIFY(customP.write(this, QVariant())); QCOMPARE(custom.str, QString()); // or reset resetable QVERIFY(value7P.write(this, QVariant())); QCOMPARE(value7, QLatin1Literal("reset")); }
void CDiagramItem::toXml(QDomElement &n) { QMetaObject *meta = NULL; QMetaProperty prop; QDomDocument doc; QDomElement ext, childNode; QList<QByteArray> props; QStringList filtersOut, filtersIn; CDiagramSerializable *inst = NULL; filtersIn = filterProperties(); filtersOut << "width" << "height" << "x" << "y" << "z" << "pos" << "size" << "parent" << "effect" << "children" << "layout" << "palette"; doc = n.ownerDocument(); ext = doc.createElement( QString("ext") ); childNode = doc.createElement( QString("children") ); n.setAttribute( QString("type"), interType()); n.setAttribute( QString("category"), category() ); n.setAttribute( QString("name"), name() ); n.setAttribute( QString("libCategory"), libraryCategory() ); n.setAttribute( QString("libName"), libraryName() ); n.setAttribute( QString("id"), QString::number(id()) ); meta = const_cast<QMetaObject*>(metaObject()); for (int i = 0; i < meta->propertyCount(); ++i) { QString propName; QByteArray b; QDataStream s(&b, QIODevice::WriteOnly); prop = meta->property(i); propName = QString(prop.name()); if (filtersIn.isEmpty()) { if (filtersOut.contains(propName, Qt::CaseInsensitive) || prop.userType() == 0) { continue; } } else { if (!filtersIn.contains(propName, Qt::CaseInsensitive)) { continue; } } if (prop.isValid() && prop.isReadable()) { s << prop.read(this); QDomElement e = doc.createElement(QString("property")); e.setAttribute( QString("name"), QString(prop.name()) ); e.setAttribute( QString("type"), QString(prop.typeName()) ); e.appendChild( doc.createTextNode( QString(b.toBase64() ) ) ); n.appendChild(e); // qDebug() << "save->name:" << prop.name() << " value:" << prop.read(this); } } props = dynamicPropertyNames(); for (int i = 0; i < props.length(); ++i) { inst = RS_PROPERTY(props.at(i).constData()); // inst = property(props.at(i).constData()).value<CDiagramSerializable*>(); if (inst) { QDomElement c = doc.createElement(QString("child")); c.setAttribute( QString("dynamicProperty"), QString(props.at(i).constData()) ); inst->toXml(c); childNode.appendChild(c); } } n.appendChild(childNode); extToXml( ext ); n.appendChild( ext ); }
PyObject* scribus_getproperty(PyObject* /*self*/, PyObject* args, PyObject* kw) { PyObject* objArg = NULL; char* propertyName = NULL; char* kwargs[] = {const_cast<char*>("object"), const_cast<char*>("property"), NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "Oes", kwargs, &objArg, "ascii", &propertyName)) return NULL; // Get the QObject* the object argument refers to QObject* obj = getQObjectFromPyArg(objArg); if (!obj) return NULL; objArg = NULL; // no need to decref, it's borrowed // Get the QMetaProperty for the property, so we can check // if it's a set/enum and do name/value translation. const QMetaObject* objmeta = obj->metaObject(); int i = objmeta->indexOfProperty(propertyName); if (i == -1) { PyErr_SetString(PyExc_ValueError, QObject::tr("Property not found").toLocal8Bit().data()); return NULL; } QMetaProperty propmeta = objmeta->property(i); if (!propmeta.isValid()) { PyErr_SetString(PyExc_ValueError, QObject::tr("Invalid property").toLocal8Bit().data()); return NULL; } // Get the property value as a variant type QVariant prop = obj->property(propertyName); // Convert the property to an instance of the closest matching Python type. PyObject* resultobj = NULL; // NUMERIC TYPES if (prop.type() == QVariant::Int) resultobj = PyLong_FromLong(prop.toInt()); else if (prop.type() == QVariant::Double) resultobj = PyFloat_FromDouble(prop.toDouble()); // BOOLEAN else if (prop.type() == QVariant::Bool) resultobj = PyBool_FromLong(prop.toBool()); // STRING TYPES else if (prop.type() == QVariant::ByteArray) resultobj = PyString_FromString(prop.toByteArray().data()); else if (prop.type() == QVariant::String) resultobj = PyString_FromString(prop.toString().toUtf8().data()); // HIGHER ORDER TYPES else if (prop.type() == QVariant::Point) { // Return a QPoint as an (x,y) tuple. QPoint pt = prop.toPoint(); return Py_BuildValue("(ii)", pt.x(), pt.y()); } else if (prop.type() == QVariant::Rect) { // Return a QRect as an (x,y,width,height) tuple. // FIXME: We should really construct and return an object that // matches the API of QRect and has properties to keep // left/top/right/bottom and x/y/width/height in sync. QRect r = prop.toRect(); return Py_BuildValue("(iiii)", r.x(), r.y(), r.width(), r.height()); } else if (prop.type() == QVariant::StringList) { QStringList tmp = prop.toStringList(); return convert_QStringList_to_PyListObject(tmp); } // UNHANDLED TYPE else { PyErr_SetString(PyExc_TypeError, QObject::tr("Couldn't convert result type '%1'.").arg(prop.typeName()).toLocal8Bit().constData() ); return resultobj; } // Return the resulting Python object if (resultobj == NULL) { // An exception was set while assigning to resultobj assert(PyErr_Occurred()); return NULL; } else return resultobj; }
void AcceleratorManagerPrivate::manageWidget(QWidget *w, Item *item) { // first treat the special cases QTabBar *tabBar = qobject_cast<QTabBar*>(w); if (tabBar) { manageTabBar(tabBar, item); return; } QStackedWidget *wds = qobject_cast<QStackedWidget*>( w ); if ( wds ) { QWidgetStackAccelManager::manage( wds ); // return; } QDockWidget *dock = qobject_cast<QDockWidget*>( w ); if ( dock ) { //QWidgetStackAccelManager::manage( wds ); manageDockWidget(dock, item); } QMenu *popupMenu = qobject_cast<QMenu*>(w); if (popupMenu) { // create a popup accel manager that can deal with dynamic menus PopupAccelManager::manage(popupMenu); return; } QStackedWidget *wdst = qobject_cast<QStackedWidget*>( w ); if ( wdst ) { QWidgetStackAccelManager::manage( wdst ); // return; } QMenuBar *menuBar = qobject_cast<QMenuBar*>(w); if (menuBar) { manageMenuBar(menuBar, item); return; } if (qobject_cast<QComboBox*>(w) || qobject_cast<QLineEdit*>(w) || w->inherits("Q3TextEdit") || qobject_cast<QTextEdit*>(w) || qobject_cast<QAbstractSpinBox*>(w) || w->inherits( "KMultiTabBar" ) ) return; if ( w->inherits("KUrlRequester") ) { traverseChildren(w, item); return; } if ( qobject_cast<PathRequester*>(w) ) { traverseChildren(w, item); return; } // now treat 'ordinary' widgets QLabel *label = qobject_cast<QLabel*>(w); if ( label ) { if ( !label->buddy() ) return; else { if ( label->textFormat() == Qt::RichText || ( label->textFormat() == Qt::AutoText && Qt::mightBeRichText( label->text() ) ) ) return; } } if (w->focusPolicy() != Qt::NoFocus || label || qobject_cast<QGroupBox*>(w) || qobject_cast<QRadioButton*>( w )) { QString content; QVariant variant; int tprop = w->metaObject()->indexOfProperty("text"); if (tprop != -1) { QMetaProperty p = w->metaObject()->property( tprop ); if ( p.isValid() && p.isWritable() ) variant = p.read (w); else tprop = -1; } if (tprop == -1) { tprop = w->metaObject()->indexOfProperty("title"); if (tprop != -1) { QMetaProperty p = w->metaObject()->property( tprop ); if ( p.isValid() && p.isWritable() ) variant = p.read (w); } } if (variant.isValid()) content = variant.toString(); if (!content.isEmpty()) { Item *i = new Item; i->m_widget = w; // put some more weight on the usual action elements int weight = AccelManagerAlgorithm::DEFAULT_WEIGHT; if (qobject_cast<QPushButton*>(w) || qobject_cast<QCheckBox*>(w) || qobject_cast<QRadioButton*>(w) || qobject_cast<QLabel*>(w)) weight = AccelManagerAlgorithm::ACTION_ELEMENT_WEIGHT; // don't put weight on non-checkable group boxes, // as usually the contents are more important QGroupBox *groupBox = qobject_cast<QGroupBox*>(w); if (groupBox) { if (groupBox->isCheckable()) weight = AccelManagerAlgorithm::CHECKABLE_GROUP_BOX_WEIGHT; else weight = AccelManagerAlgorithm::GROUP_BOX_WEIGHT; } i->m_content = AccelString(content, weight); item->addChild(i); } } traverseChildren(w, item); }
void tst_QQmlEngineDebugService::recursiveObjectTest( QObject *o, const QmlDebugObjectReference &oref, bool recursive) const { const QMetaObject *meta = o->metaObject(); QQmlType *type = QQmlMetaType::qmlType(meta); QString className = type ? QString(type->qmlTypeName()) : QString(meta->className()); className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1); QCOMPARE(oref.debugId, QQmlDebugService::idForObject(o)); QCOMPARE(oref.name, o->objectName()); QCOMPARE(oref.className, className); QCOMPARE(oref.contextDebugId, QQmlDebugService::idForObject( qmlContext(o))); const QObjectList &children = o->children(); for (int i=0; i<children.count(); i++) { QObject *child = children[i]; if (!qmlContext(child)) continue; int debugId = QQmlDebugService::idForObject(child); QVERIFY(debugId >= 0); QmlDebugObjectReference cref; foreach (const QmlDebugObjectReference &ref, oref.children) { if (ref.debugId == debugId) { cref = ref; break; } } QVERIFY(cref.debugId >= 0); if (recursive) recursiveObjectTest(child, cref, true); } foreach (const QmlDebugPropertyReference &p, oref.properties) { QCOMPARE(p.objectDebugId, QQmlDebugService::idForObject(o)); // signal properties are fake - they are generated from QQmlAbstractBoundSignal children if (p.name.startsWith("on") && p.name.length() > 2 && p.name[2].isUpper()) { QString signal = p.value.toString(); QQmlBoundSignalExpression *expr = QQmlPropertyPrivate::signalExpression(QQmlProperty(o, p.name)); QVERIFY(expr && expr->expression() == signal); QVERIFY(p.valueTypeName.isEmpty()); QVERIFY(p.binding.isEmpty()); QVERIFY(!p.hasNotifySignal); continue; } QMetaProperty pmeta = meta->property(meta->indexOfProperty(p.name.toUtf8().constData())); QCOMPARE(p.name, QString::fromUtf8(pmeta.name())); if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) // TODO test complex types QCOMPARE(p.value , pmeta.read(o)); if (p.name == "parent") QVERIFY(p.valueTypeName == "QGraphicsObject*" || p.valueTypeName == "QQuickItem*"); else QCOMPARE(p.valueTypeName, QString::fromUtf8(pmeta.typeName())); QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding( QQmlProperty(o, p.name)); if (binding) QCOMPARE(binding->expression(), p.binding); QCOMPARE(p.hasNotifySignal, pmeta.hasNotifySignal()); QVERIFY(pmeta.isValid()); } }
int QServiceProxy::qt_metacall(QMetaObject::Call c, int id, void **a) { id = QServiceProxyBase::qt_metacall(c, id, a); if (id < 0 || !d->meta) return id; if (c == QMetaObject::InvokeMetaMethod) { const int mcount = d->meta->methodCount() - d->meta->methodOffset(); const int metaIndex = id + d->meta->methodOffset(); QMetaMethod method = d->meta->method(metaIndex); const int returnType = method.returnType(); //process arguments const QList<QByteArray> pTypes = method.parameterTypes(); const int pTypesCount = pTypes.count(); QVariantList args ; if (pTypesCount > 10) { qWarning() << "Cannot call" << method.methodSignature() << ". More than 10 parameter."; return id; } for (int i=0; i < pTypesCount; i++) { const QByteArray& t = pTypes[i]; int variantType = QMetaType::type(t); if (variantType == QMetaType::QVariant) { //ignore whether QVariant is declared as metatype args << *reinterpret_cast<const QVariant(*)>(a[i+1]); } else if ( variantType == 0 ){ qWarning("%s: argument %s has unknown type. Use qRegisterMetaType to register it.", method.methodSignature().constData(), t.data()); return id; } else { args << QVariant(variantType, a[i+1]); } } if (returnType == QMetaType::Void) { qServiceLog() << "event" << "nonblocking void call" << "method" << QString::fromLatin1(method.methodSignature()) << "endpoint" << d->endPoint->objectName(); d->endPoint->invokeRemote(d->localToRemote[metaIndex], args, returnType); } else { //TODO: invokeRemote() parameter list needs review qServiceLog() << "event" << "nonblocking call" << "method" << QString::fromLatin1(method.methodSignature()) << "endpoint" << d->endPoint->objectName(); QVariant result = d->endPoint->invokeRemote(d->localToRemote[metaIndex], args, returnType); if (result.type() != QVariant::Invalid){ if (returnType != QMetaType::QVariant) { QByteArray buffer; QDataStream stream(&buffer, QIODevice::ReadWrite); QMetaType::save(stream, returnType, result.constData()); stream.device()->seek(0); QMetaType::load(stream, returnType, a[0]); } else { if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result; } } } id-=mcount; } else if ( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty ) { const int pCount = d->meta->propertyCount() - d->meta->propertyOffset(); const int metaIndex = id + d->meta->propertyOffset(); QMetaProperty property = d->meta->property(metaIndex); if (property.isValid()) { int pType = property.userType(); QVariant arg; if ( c == QMetaObject::WriteProperty ) { qServiceLog() << "event" << "property write" << "property" << property.name() << "endpoint" << d->endPoint->objectName(); if (pType == QMetaType::QVariant) arg = *reinterpret_cast<const QVariant(*)>(a[0]); else if (pType == 0) { qWarning("%s: property %s has unkown type", property.name(), property.typeName()); return id; } else { arg = QVariant(pType, a[0]); } } QVariant result; if (c == QMetaObject::ReadProperty) { qServiceLog() << "event" << "property read" << "property" << property.name() << "endpoint" << d->endPoint->objectName(); result = d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c); //wrap result for client if (pType != 0) { QByteArray buffer; QDataStream stream(&buffer, QIODevice::ReadWrite); QMetaType::save(stream, pType, result.constData()); stream.device()->seek(0); QMetaType::load(stream, pType, a[0]); } else { if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result; } } else { d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c); } } id-=pCount; } else if ( c == QMetaObject::QueryPropertyDesignable || c == QMetaObject::QueryPropertyScriptable || c == QMetaObject::QueryPropertyStored || c == QMetaObject::QueryPropertyEditable || c == QMetaObject::QueryPropertyUser ) { //Nothing to do? //These values are part of the transferred meta object already } else { //TODO qWarning() << "MetaCall type" << c << "not yet handled"; } return id; }
void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) { Q_ASSERT(m->as<QQmlValueTypeWrapper>()); ExecutionEngine *v4 = static_cast<QQmlValueTypeWrapper *>(m)->engine(); Scope scope(v4); if (scope.hasException()) return; Scoped<QQmlValueTypeWrapper> r(scope, static_cast<QQmlValueTypeWrapper *>(m)); Scoped<QQmlValueTypeReference> reference(scope, m->d()); int writeBackPropertyType = -1; if (reference) { QMetaProperty writebackProperty = reference->d()->object->metaObject()->property(reference->d()->property); if (!writebackProperty.isWritable() || !reference->readReferenceValue()) return; writeBackPropertyType = writebackProperty.userType(); } const QMetaObject *metaObject = r->d()->propertyCache->metaObject(); const QQmlPropertyData *pd = r->d()->propertyCache->property(name, 0, 0); if (!pd) return; QMetaProperty property = metaObject->property(pd->coreIndex); Q_ASSERT(property.isValid()); QQmlBinding *newBinding = 0; QV4::ScopedFunctionObject f(scope, value); if (reference && f) { if (!f->isBinding()) { // assigning a JS function to a non-var-property is not allowed. QString error = QStringLiteral("Cannot assign JavaScript function to value-type property"); ScopedString e(scope, v4->newString(error)); v4->throwError(e); return; } QQmlContextData *context = QmlContextWrapper::callingContext(v4); QQmlPropertyData cacheData; cacheData.setFlags(QQmlPropertyData::IsWritable | QQmlPropertyData::IsValueTypeVirtual); cacheData.propType = writeBackPropertyType; cacheData.coreIndex = reference->d()->property; cacheData.valueTypeFlags = 0; cacheData.valueTypeCoreIndex = pd->coreIndex; cacheData.valueTypePropType = property.userType(); QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f); bindingFunction->initBindingLocation(); newBinding = new QQmlBinding(value, reference->d()->object, context); newBinding->setTarget(reference->d()->object, cacheData, context); } if (reference) { QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(reference->d()->object, reference->d()->property, pd->coreIndex, newBinding); if (oldBinding) oldBinding->destroy(); } if (newBinding) return; QVariant v = v4->toVariant(value, property.userType()); if (property.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) v = v.toInt(); void *gadget = r->d()->gadgetPtr; property.writeOnGadget(gadget, v); if (reference) { if (writeBackPropertyType == QMetaType::QVariant) { QVariant variantReferenceValue = r->d()->toVariant(); int flags = 0; int status = -1; void *a[] = { &variantReferenceValue, 0, &status, &flags }; QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a); } else { int flags = 0; int status = -1; void *a[] = { r->d()->gadgetPtr, 0, &status, &flags }; QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a); } } }
bool AppSettings::addTrackingProperty(const QString &key, QObject *object, const char *propname) { const QMetaObject *metaObject = object->metaObject(); /* Get the meta-property */ QMetaProperty property; if (propname) property = metaObject->property(metaObject->indexOfProperty(propname)); else property = metaObject->userProperty(); if (!property.isValid()) { qWarning() << "AppSettings: Unknown property" << propname << "for object" << object->objectName() << "of class" << metaObject->className() << "with key" << key; return false; } #ifdef QT_DEBUG /* Check for duplicates */ QMultiHash<QObject*,QPair<QString,int> >::Iterator it = trackingObjectMap.find(object); for (; it != trackingObjectMap.end() && it.key() == object; ++it) { if (it->first == key && it->second == metaObject->indexOfProperty(propname)) { qWarning() << "AppSettings: Duplicate tracking of key" << key << "by object" << object->objectName() << "of class" << metaObject->className() << "for property" << property.name(); break; } } #endif /* Connect to the notify signal of that property */ if (property.hasNotifySignal()) { /* See the comment in the header for why this hack is necessary; what we're doing here is * determining how many properties are connected from this object, and choosing one of the * five available slots based on that. Because the order in QMultiHash is based on insertion * order, we can map this back in the slot. */ char slot[] = { "1objectChanged?()" }; int propsForObject = trackingObjectMap.count(object); if (propsForObject >= 5) { qWarning() << "AppSettings: Too many properties tracked from object" << object->objectName() << "of class" << metaObject->className(); return false; } /* Cheap conversion from a single-digit number to ASCII */ slot[14] = (char)propsForObject + 48; QByteArray notify(property.notifySignal().methodSignature()); notify.prepend('2'); bool ok = connect(object, notify.constData(), this, slot); if (!ok) { qWarning() << "AppSettings: Signal connection failed for property" << property.name() << "of object" << object->objectName() << "of class" << metaObject->className() << "with key" << key; return false; } } if (!trackingObjectMap.contains(object)) connect(object, SIGNAL(destroyed(QObject*)), SLOT(removeTrackingProperty(QObject*))); /* Insert key/object mappings */ trackingKeyMap.insertMulti(key, object); trackingObjectMap.insertMulti(object, qMakePair(key, metaObject->indexOfProperty(propname))); return true; }
void tst_QQmlMetaObject::property() { QFETCH(QString, testFile); QFETCH(QByteArray, cppTypeName); QFETCH(int, cppType); QFETCH(bool, isDefault); QFETCH(QVariant, expectedValue); QFETCH(bool, isWritable); QFETCH(QVariant, newValue); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl(testFile)); QObject *object = component.create(); QVERIFY(object != 0); const QMetaObject *mo = object->metaObject(); QVERIFY(mo->superClass() != 0); QVERIFY(QByteArray(mo->className()).contains("_QML_")); QCOMPARE(mo->propertyOffset(), mo->superClass()->propertyCount()); QCOMPARE(mo->propertyCount(), mo->superClass()->propertyCount() + 1); QMetaProperty prop = mo->property(mo->propertyOffset()); QCOMPARE(prop.name(), "test"); QCOMPARE(QByteArray(prop.typeName()), cppTypeName); if (prop.userType() < QMetaType::User) QCOMPARE(prop.type(), QVariant::Type(cppType)); else QCOMPARE(prop.type(), QVariant::UserType); QCOMPARE(prop.userType(), cppType); QVERIFY(!prop.isConstant()); QVERIFY(!prop.isDesignable()); QVERIFY(!prop.isEnumType()); QVERIFY(!prop.isFinal()); QVERIFY(!prop.isFlagType()); QVERIFY(prop.isReadable()); QVERIFY(!prop.isResettable()); QVERIFY(prop.isScriptable()); QVERIFY(!prop.isStored()); QVERIFY(!prop.isUser()); QVERIFY(prop.isValid()); QCOMPARE(prop.isWritable(), isWritable); QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount()); QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0)); if (isDefault) { QMetaClassInfo info = mo->classInfo(mo->classInfoOffset()); QCOMPARE(info.name(), "DefaultProperty"); QCOMPARE(info.value(), "test"); } QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount()); QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal QVERIFY(prop.notifySignalIndex() != -1); QMetaMethod signal = prop.notifySignal(); QCOMPARE(signal.methodType(), QMetaMethod::Signal); QCOMPARE(signal.name(), QByteArray("testChanged")); QCOMPARE(signal.methodSignature(), QByteArray("testChanged()")); QCOMPARE(signal.access(), QMetaMethod::Public); QCOMPARE(signal.parameterCount(), 0); QCOMPARE(signal.parameterTypes(), QList<QByteArray>()); QCOMPARE(signal.parameterNames(), QList<QByteArray>()); QCOMPARE(signal.tag(), ""); QCOMPARE(signal.typeName(), "void"); QCOMPARE(signal.returnType(), int(QMetaType::Void)); QSignalSpy changedSpy(object, SIGNAL(testChanged())); QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater())); if (expectedValue.isValid()) QCOMPARE(prop.read(object), expectedValue); else QVERIFY(prop.read(object).isValid()); QCOMPARE(changedSpy.count(), 0); if (isWritable) { QVERIFY(prop.write(object, newValue)); QCOMPARE(changedSpy.count(), 1); QCOMPARE(prop.read(object), newValue); } else { QVERIFY(!prop.write(object, prop.read(object))); QCOMPARE(changedSpy.count(), 0); } delete object; }
int QServiceProxy::qt_metacall(QMetaObject::Call c, int id, void **a) { #ifdef QT_SFW_ENDPOINT_DEBUG qDebug() << "QServiceProxy::qt_metacall: Start"; #endif id = QObject::qt_metacall(c, id, a); if (id < 0 || !d->meta) return id; //Let the object endpoint monitor keep track of the usage... #ifdef Q_OS_SYMBIAN ObjectEndPointMonitor aOem(d->endPoint); #endif //End Q_OS_SYMBIAN if(localSignals.at(id)){ QMetaObject::activate(this, d->meta, id, a); return id; } if (c == QMetaObject::InvokeMetaMethod) { const int mcount = d->meta->methodCount() - d->meta->methodOffset(); const int metaIndex = id + d->meta->methodOffset(); QMetaMethod method = d->meta->method(metaIndex); const int returnType = QMetaType::type(method.typeName()); //process arguments const QList<QByteArray> pTypes = method.parameterTypes(); const int pTypesCount = pTypes.count(); QVariantList args ; if (pTypesCount > 10) { qWarning() << "Cannot call" << method.signature() << ". More than 10 parameter."; return id; } for (int i=0; i < pTypesCount; i++) { const QByteArray& t = pTypes[i]; int variantType = QVariant::nameToType(t); if (variantType == QVariant::UserType) variantType = QMetaType::type(t); if (t == "QVariant") { //ignore whether QVariant is declared as metatype args << *reinterpret_cast<const QVariant(*)>(a[i+1]); } else if ( variantType == 0 ){ qWarning("%s: argument %s has unknown type. Use qRegisterMetaType to register it.", method.signature(), t.data()); return id; } else { args << QVariant(variantType, a[i+1]); } } //QVariant looks the same as Void type. we need to distinguish them if (returnType == QMetaType::Void && strcmp(method.typeName(),"QVariant") ) { d->endPoint->invokeRemote(metaIndex, args, returnType); } else { //TODO: ugly but works //add +1 if we have a variant return type to avoid triggering of void //code path //invokeRemote() parameter list needs review QVariant result = d->endPoint->invokeRemote(metaIndex, args, returnType==0 ? returnType+1: returnType); if(result.type() != QVariant::Invalid){ if (returnType != 0 && strcmp(method.typeName(),"QVariant")) { QByteArray buffer; QDataStream stream(&buffer, QIODevice::ReadWrite); QMetaType::save(stream, returnType, result.constData()); stream.device()->seek(0); QMetaType::load(stream, returnType, a[0]); } else { if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result; } } } id-=mcount; } else if ( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty ) { const int pCount = d->meta->propertyCount() - d->meta->propertyOffset(); const int metaIndex = id + d->meta->propertyOffset(); QMetaProperty property = d->meta->property(metaIndex); if (property.isValid()) { int pType = property.type(); if (pType == QVariant::UserType) pType = QMetaType::type(property.typeName()); QVariant arg; if ( c == QMetaObject::WriteProperty ) { if (pType == QVariant::Invalid && QByteArray(property.typeName()) == "QVariant") arg = *reinterpret_cast<const QVariant(*)>(a[0]); else if (pType == 0) { qWarning("%s: property %s has unknown type", property.name(), property.typeName()); return id; } else { arg = QVariant(pType, a[0]); } } QVariant result; if (c == QMetaObject::ReadProperty) { result = d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c); //wrap result for client if (pType != 0) { QByteArray buffer; QDataStream stream(&buffer, QIODevice::ReadWrite); QMetaType::save(stream, pType, result.constData()); stream.device()->seek(0); QMetaType::load(stream, pType, a[0]); } else { if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result; } } else { d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c); } } id-=pCount; } else if ( c == QMetaObject::QueryPropertyDesignable || c == QMetaObject::QueryPropertyScriptable || c == QMetaObject::QueryPropertyStored || c == QMetaObject::QueryPropertyEditable || c == QMetaObject::QueryPropertyUser ) { //Nothing to do? //These values are part of the transferred meta object already } else { //TODO qWarning() << "MetaCall type" << c << "not yet handled"; } #ifdef QT_SFW_ENDPOINT_DEBUG qDebug() << "QServiceProxy::qt_metacall: End"; #endif return id; }
void DataWidgetMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) { QMetaProperty property; for (int i=0; i<widget->metaObject()->propertyCount(); ++i) { if (QString(widget->metaObject()->property(i).name()) == propertyName) { property = widget->metaObject()->property(i); break; } } Q_ASSERT(property.isValid()); QMetaMethod notifySignal = property.notifySignal(); Q_ASSERT(notifySignal.isValid()); connect(widget, notifySignal, this, QMetaMethod::fromSignal(&DataWidgetMapper::dataChanged)); QDataWidgetMapper::addMapping(widget, section, propertyName); }