void DecorationShadowTest::testPadding() { using namespace KDecoration2; DecorationShadow shadow; QFETCH(QByteArray, propertyName); const int propertyIndex = shadow.metaObject()->indexOfProperty(propertyName.constData()); QVERIFY(propertyIndex != -1); QMetaProperty metaProperty = shadow.metaObject()->property(propertyIndex); QCOMPARE(metaProperty.isReadable(), true); QCOMPARE(metaProperty.hasNotifySignal(), true); QCOMPARE(metaProperty.type(), QVariant::Int); QSignalSpy changedSpy(&shadow, SIGNAL(paddingChanged())); QVERIFY(changedSpy.isValid()); QCOMPARE(shadow.property(propertyName.constData()).isValid(), true); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 0); QFETCH(QMargins, padding); shadow.setPadding(padding); QCOMPARE(shadow.padding(), padding); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 10); QCOMPARE(changedSpy.count(), 1); // trying to set to same value shouldn't emit the signal shadow.setPadding(padding); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 10); QCOMPARE(changedSpy.count(), 1); // changing to different value should emit signal padding += 1; shadow.setPadding(padding); QCOMPARE(shadow.padding(), padding); QCOMPARE(shadow.property(propertyName.constData()).toInt(), 11); QCOMPARE(changedSpy.count(), 2); }
QVariantMap qobject2qvariant( const QObject* object ) { #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) QVariantMap map; if ( object == NULL ) { return map; } const QMetaObject* metaObject = object->metaObject(); for ( int i = 0; i < metaObject->propertyCount(); ++i ) { QMetaProperty metaproperty = metaObject->property( i ); if ( metaproperty.isReadable() ) { map[ QLatin1String( metaproperty.name() ) ] = object->property( metaproperty.name() ); } } return map; #else return QJson::QObjectHelper::qobject2qvariant( object ); #endif }
int Dialog::showDialog(const QString& view, QObject* viewModel, int type) { QDialog* dialog = NULL; QMainWindow* mainWindow = NULL; QWidget* windowWidget = NULL; QWidget* layoutWidget = NULL; switch (type) { case Dialog::MainWindow: mainWindow = new QMainWindow(); windowWidget = mainWindow; layoutWidget = new QWidget(windowWidget); mainWindow->setCentralWidget(layoutWidget); break; case Dialog::ModalDialog: dialog = new QDialog(QApplication::activeWindow()); windowWidget = dialog; layoutWidget = dialog; break; default: dialog = new QDialog(); windowWidget = dialog; layoutWidget = dialog; break; } QGridLayout* layout = new QGridLayout(layoutWidget); // Create view QDeclarativeView* v = new QDeclarativeView(layoutWidget); if (viewModel) { int count = viewModel->metaObject()->propertyCount(); for (int i = 0; i < count; ++i) { QMetaProperty p = viewModel->metaObject()->property(i); if (p.isReadable() && p.typeName() == QString("QDeclarativeImageProvider*")) { QString name = p.name(); QDeclarativeImageProvider* value = p.read(viewModel).value<QDeclarativeImageProvider*>(); v->engine()->addImageProvider(name.toLatin1(), new ProxyImageProvider(value)); } } v->rootContext()->setContextProperty("dataContext", viewModel); } QString path; foreach (path, importPaths) v->engine()->addImportPath(path); foreach (path, pluginPaths) v->engine()->addPluginPath(path); v->setSource(QUrl(view)); v->setResizeMode(QDeclarativeView::SizeRootObjectToView); // Initialize dialog QGraphicsObject* root = v->rootObject(); QVariant property = root->property("dialogTitle"); if (property.isValid()) windowWidget->setWindowTitle(property.toString()); property = root->property("dialogMinWidth"); if (property.isValid()) layoutWidget->setMinimumWidth(property.toInt()); property = root->property("dialogMinHeight"); if (property.isValid()) layoutWidget->setMinimumHeight(property.toInt()); property = root->property("dialogMaxWidth"); if (property.isValid()) layoutWidget->setMaximumWidth(property.toInt()); property = root->property("dialogMaxHeight"); if (property.isValid()) layoutWidget->setMaximumHeight(property.toInt()); property = root->property("dialogResizable"); if (property.isValid() && !property.toBool()) layout->setSizeConstraint(QLayout::SetFixedSize); Qt::WindowStates states = windowWidget->windowState(); Qt::WindowFlags flags = windowWidget->windowFlags(); property = root->property("dialogMinimizeButton"); if (property.isValid()) flags = property.toBool() ? flags | Qt::WindowMinimizeButtonHint : flags & ~Qt::WindowMinimizeButtonHint; property = root->property("dialogMaximizeButton"); if (property.isValid()) flags = property.toBool() ? flags | Qt::WindowMaximizeButtonHint : flags & ~Qt::WindowMaximizeButtonHint; property = root->property("dialogCloseButton"); if (property.isValid()) flags = property.toBool() ? flags | Qt::WindowCloseButtonHint : flags & ~Qt::WindowCloseButtonHint; property = root->property("dialogFullScreen"); if (property.isValid()) states = property.toBool() ? states | Qt::WindowFullScreen : states & ~Qt::WindowFullScreen; flags = flags & ~Qt::WindowContextHelpButtonHint; windowWidget->setWindowFlags(flags); windowWidget->setWindowState(states); property = root->property("dialogToolBar"); if (type == Dialog::MainWindow && property.isValid() && property.typeName() == QString("QDeclarativeListProperty<QDeclarativeItem>")) { QToolBar* toolbar = new QToolBar(mainWindow); toolbar->setMovable(false); toolbar->setFloatable(false); toolbar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); toolbar->setAllowedAreas(Qt::TopToolBarArea); QDeclarativeListProperty<QDeclarativeItem> btnList = property.value< QDeclarativeListProperty<QDeclarativeItem> >(); int btnCount = btnList.count(&btnList); for (int i = 0; i < btnCount; ++i) { QDeclarativeItem* item = btnList.at(&btnList, i); if (!item->property("text").isValid()) continue; QString itemText = item->property("text").toString(); QString itemTooltip = item->property("tooltip").isValid() ? item->property("tooltip").toString() : ""; QString itemIconSource = item->property("iconSource").isValid() ? item->property("iconSource").toString() : ""; int itemIconSize = item->property("iconSize").isValid() ? item->property("iconSize").toInt() : -1; if (itemText == "|") { toolbar->addSeparator(); } else if (itemText == "-") { QWidget* spacer = new QWidget(); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); toolbar->addWidget(spacer); } else { QAction* action = new QAction(mainWindow); action->setText(itemText); action->setToolTip(itemTooltip); action->setIcon(QIcon(itemIconSource)); QObject::connect(action, SIGNAL(triggered()), item, SLOT(trigger())); if (item->property("enabled").isValid()) new PropertyBinding(action, "enabled", item, "enabled", PropertyBinding::OneWay, NULL, this); if (item->property("visible").isValid()) new PropertyBinding(action, "visible", item, "visible", PropertyBinding::OneWay, NULL, this); toolbar->addAction(action); } if (itemIconSize != -1) toolbar->setIconSize(QSize(itemIconSize, itemIconSize)); } mainWindow->setUnifiedTitleAndToolBarOnMac(true); mainWindow->addToolBar(toolbar); } property = root->property("dialogMenu"); if (type == Dialog::MainWindow && property.isValid() && property.typeName() == QString("QDeclarativeListProperty<QDeclarativeItem>")) { QDeclarativeListProperty<QDeclarativeItem> list = property.value< QDeclarativeListProperty<QDeclarativeItem> >(); int count = list.count(&list); for (int i = 0; i < count; ++i) { QDeclarativeItem* item = list.at(&list, i); if (!item->property("text").isValid()) continue; QString itemText = item->property("text").toString(); QMenu * menuItem = mainWindow->menuBar()->addMenu(itemText); if (!item->property("submenu").isValid() || item->property("submenu").typeName() != QString("QDeclarativeListProperty<QDeclarativeItem>")) continue; QDeclarativeListProperty<QDeclarativeItem> innerList = item->property("submenu").value< QDeclarativeListProperty<QDeclarativeItem> >(); int innerCount = innerList.count(&innerList); for (int j = 0; j < innerCount; ++j) { QDeclarativeItem* innerItem = innerList.at(&innerList, j); if (!innerItem->property("text").isValid()) continue; QString innerItemText = innerItem->property("text").toString(); QString innerItemShortcut = innerItem->property("shortcut").isValid() ? innerItem->property("shortcut").toString() : ""; QString innerItemIconSource = innerItem->property("iconSource").isValid() ? innerItem->property("iconSource").toString() : ""; if (innerItemText == "-") { menuItem->addSeparator(); } else { QAction * action = menuItem->addAction(QIcon(innerItemIconSource), innerItemText); action->setShortcut(QKeySequence(innerItemShortcut)); QObject::connect(action, SIGNAL(triggered()), innerItem, SLOT(trigger())); if (innerItem->property("enabled").isValid()) new PropertyBinding(action, "enabled", innerItem, "enabled", PropertyBinding::OneWay, NULL, this); if (innerItem->property("visible").isValid()) new PropertyBinding(action, "visible", innerItem, "visible", PropertyBinding::OneWay, NULL, this); } } } } new DialogCallbacks(windowWidget, v, root); // Initialize layout layout->setMargin(0); layout->addWidget(v, 0, 0); // Execute switch (type) { case Dialog::ModalDialog: dialog->exec(); break; case Dialog::MainWindow: { if (mainWindowGeometry.isEmpty()) { mainWindow->adjustSize(); mainWindow->move(QApplication::desktop()->screen()->rect().center() - mainWindow->rect().center()); } else mainWindow->restoreGeometry(mainWindowGeometry); } default: windowWidget->setAttribute(Qt::WA_DeleteOnClose); windowWidget->show(); break; } int result = 0; property = root->property("dialogResult"); if (property.isValid()) result = property.toInt(); if (type == Dialog::ModalDialog) delete dialog; return result; }
void ObjectControllerPrivate::addClassProperties(const QMetaObject *metaObject) { if (!metaObject) return; addClassProperties(metaObject->superClass()); QtProperty *classProperty = m_classToProperty.value(metaObject); if (!classProperty) { QString className = QLatin1String(metaObject->className()); classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className); m_classToProperty[metaObject] = classProperty; m_propertyToClass[classProperty] = metaObject; for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { QMetaProperty metaProperty = metaObject->property(idx); int type = metaProperty.userType(); QtVariantProperty *subProperty = 0; if (!metaProperty.isReadable()) { subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name())); subProperty->setValue(QLatin1String("< Non Readable >")); } else if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), QLatin1String(metaProperty.name())); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; QStringList flagNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value) && isPowerOf2(value)) { valueMap[value] = true; flagNames.append(QLatin1String(metaEnum.key(i))); } subProperty->setAttribute(QLatin1String("flagNames"), flagNames); subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else { subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), QLatin1String(metaProperty.name())); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; // dont show multiple enum values which have the same values QStringList enumNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value)) { valueMap[value] = true; enumNames.append(QLatin1String(metaEnum.key(i))); } } subProperty->setAttribute(QLatin1String("enumNames"), enumNames); subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else if (m_manager->isPropertyTypeSupported(type)) { if (!metaProperty.isWritable()) subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Writable)")); if (!metaProperty.isDesignable()) subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Designable)")); else subProperty = m_manager->addProperty(type, QLatin1String(metaProperty.name())); subProperty->setValue(metaProperty.read(m_object)); } else { subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name())); subProperty->setValue(QLatin1String("< Unknown Type >")); subProperty->setEnabled(false); } classProperty->addSubProperty(subProperty); m_propertyToIndex[subProperty] = idx; m_classToIndexToProperty[metaObject][idx] = subProperty; } } else { updateClassProperties(metaObject, false); } m_topLevelProperties.append(classProperty); m_browser->addProperty(classProperty); }
static QString generateInterfaceXml(const QMetaObject *mo, int flags, int methodOffset, int propOffset) { QString retval; // start with properties: if (flags & (QDBusConnection::ExportScriptableProperties | QDBusConnection::ExportNonScriptableProperties)) { for (int i = propOffset; i < mo->propertyCount(); ++i) { static const char *accessvalues[] = {0, "read", "write", "readwrite"}; QMetaProperty mp = mo->property(i); if (!((mp.isScriptable() && (flags & QDBusConnection::ExportScriptableProperties)) || (!mp.isScriptable() && (flags & QDBusConnection::ExportNonScriptableProperties)))) continue; int access = 0; if (mp.isReadable()) access |= 1; if (mp.isWritable()) access |= 2; int typeId = qDBusNameToTypeId(mp.typeName()); if (!typeId) continue; const char *signature = QDBusMetaType::typeToSignature(typeId); if (!signature) continue; retval += QString::fromLatin1(" <property name=\"%1\" type=\"%2\" access=\"%3\"") .arg(QLatin1String(mp.name())) .arg(QLatin1String(signature)) .arg(QLatin1String(accessvalues[access])); if (QDBusMetaType::signatureToType(signature) == QVariant::Invalid) { const char *typeName = QVariant::typeToName(QVariant::Type(typeId)); retval += QString::fromLatin1(">\n <annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"%3\"/>\n </property>\n") .arg(typeNameToXml(typeName)); } else { retval += QLatin1String("/>\n"); } } } // now add methods: for (int i = methodOffset; i < mo->methodCount(); ++i) { QMetaMethod mm = mo->method(i); QByteArray signature = mm.signature(); int paren = signature.indexOf('('); bool isSignal; if (mm.methodType() == QMetaMethod::Signal) // adding a signal isSignal = true; else if (mm.methodType() == QMetaMethod::Slot && mm.access() == QMetaMethod::Public) isSignal = false; else continue; // neither signal nor public slot if (isSignal && !(flags & (QDBusConnection::ExportScriptableSignals | QDBusConnection::ExportNonScriptableSignals))) continue; // we're not exporting any signals if (!isSignal && !(flags & (QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportNonScriptableSlots))) continue; // we're not exporting any slots QString xml = QString::fromLatin1(" <%1 name=\"%2\">\n") .arg(isSignal ? QLatin1String("signal") : QLatin1String("method")) .arg(QLatin1String(signature.left(paren))); // check the return type first int typeId = qDBusNameToTypeId(mm.typeName()); if (typeId) { const char *typeName = QDBusMetaType::typeToSignature(typeId); if (typeName) { xml += QString::fromLatin1(" <arg type=\"%1\" direction=\"out\"/>\n") .arg(typeNameToXml(typeName)); // do we need to describe this argument? if (QDBusMetaType::signatureToType(typeName) == QVariant::Invalid) xml += QString::fromLatin1(" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"%1\"/>\n") .arg(typeNameToXml(mm.typeName())); } else continue; } else if (*mm.typeName()) continue; // wasn't a valid type QList<QByteArray> names = mm.parameterNames(); QList<int> types; int inputCount = qDBusParametersForMethod(mm, types); if (inputCount == -1) continue; // invalid form if (isSignal && inputCount + 1 != types.count()) continue; // signal with output arguments? if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message) continue; // signal with QDBusMessage argument? if (isSignal && mm.attributes() & QMetaMethod::Cloned) continue; // cloned signal? int j; bool isScriptable = mm.attributes() & QMetaMethod::Scriptable; for (j = 1; j < types.count(); ++j) { // input parameter for a slot or output for a signal if (types.at(j) == QDBusMetaTypeId::message) { isScriptable = true; continue; } QString name; if (!names.at(j - 1).isEmpty()) name = QString::fromLatin1("name=\"%1\" ").arg(QLatin1String(names.at(j - 1))); bool isOutput = isSignal || j > inputCount; const char *signature = QDBusMetaType::typeToSignature(types.at(j)); xml += QString::fromLatin1(" <arg %1type=\"%2\" direction=\"%3\"/>\n") .arg(name) .arg(QLatin1String(signature)) .arg(isOutput ? QLatin1String("out") : QLatin1String("in")); // do we need to describe this argument? if (QDBusMetaType::signatureToType(signature) == QVariant::Invalid) { const char *typeName = QVariant::typeToName( QVariant::Type(types.at(j)) ); xml += QString::fromLatin1(" <annotation name=\"com.trolltech.QtDBus.QtTypeName.%1%2\" value=\"%3\"/>\n") .arg(isOutput ? QLatin1String("Out") : QLatin1String("In")) .arg(isOutput ? j - 1 : j - inputCount) .arg(typeNameToXml(typeName)); } } int wantedMask; if (isScriptable) wantedMask = isSignal ? QDBusConnection::ExportScriptableSignals : QDBusConnection::ExportScriptableSlots; else wantedMask = isSignal ? QDBusConnection::ExportNonScriptableSignals : QDBusConnection::ExportNonScriptableSlots; if ((flags & wantedMask) != wantedMask) continue; if (qDBusCheckAsyncTag(mm.tag())) // add the no-reply annotation xml += QLatin1String(" <annotation name=\"" ANNOTATION_NO_WAIT "\"" " value=\"true\"/>\n"); retval += xml; retval += QString::fromLatin1(" </%1>\n") .arg(isSignal ? QLatin1String("signal") : QLatin1String("method")); } return retval; }
void QJnextMainLoop::introspect(QObject *object, QVariantList& args, QByteArray* retval) { const QMetaObject * meta = object->metaObject(); QVariantMap data; QVariantList properties; for (int i = 0; i < meta->propertyCount(); ++i) { QVariantMap propData; QMetaProperty prop = meta->property(i); propData["name"] = prop.name(); propData["type"] = prop.typeName(); if (!prop.isReadable()) { if (!prop.isWritable()) continue; propData["writeOnly"] = true; } if (!prop.isWritable()) propData["readOnly"] = true; if (prop.hasNotifySignal()) propData["notifySignal"] = getMethodName(prop.notifySignal()); if (prop.isEnumType()) propData["enumeration"] = true; properties.append(QVariant::fromValue(propData)); } data["properties"] = properties; QVariantList methods; QVariantList sigs; for (int i = 0; i < meta->methodCount(); ++i) { QVariantMap methodData; QMetaMethod method = meta->method(i); QByteArray name = getMethodName(method); if (method.access() == QMetaMethod::Private || name.startsWith("_") || name == "deleteLater" || name == "destroyed" || name == "creationCompleted") continue; else if (method.access() == QMetaMethod::Protected && method.methodType() != QMetaMethod::Signal) continue; methodData["name"] = name; QByteArray rType(method.typeName()); if (!rType.isEmpty()) methodData["type"] = rType; QList<QByteArray> pTypes = method.parameterTypes(); QList<QByteArray> pNames = method.parameterNames(); QVariantList params; for (int i = 0; i < pTypes.count(); ++i) { QVariantMap tp; tp["type"] = pTypes.at(i); tp["name"] = pNames.value(i); params.append(tp); } if (params.size() > 0) methodData["parameters"] = params; switch (method.methodType()) { case QMetaMethod::Method: //qDebug() << "=== METHOD ===" << methodData << method.signature(); methods.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Signal: sigs.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Constructor: methodData["constructor"] = true; methods.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Slot: methods.append(QVariant::fromValue(methodData)); break; } } if (methods.size() > 0) data["methods"] = methods; if (sigs.size() > 0) data["signals"] = sigs; data["id"] = args.takeFirst(); bridge->json()->saveToBuffer(QVariant::fromValue(data), retval); #ifdef DEBUG_QJnextMainLoop qDebug() << "[QJnextMainLoop]\t[INTROSPECT]" << retval; #endif }
QString qax_generateDocumentation(QAxBase *that) { that->metaObject(); if (that->isNull()) return QString(); ITypeInfo *typeInfo = 0; IDispatch *dispatch = 0; that->queryInterface(IID_IDispatch, (void**)&dispatch); if (dispatch) dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo); QString docu; QTextStream stream(&docu, QIODevice::WriteOnly); const QMetaObject *mo = that->metaObject(); QString coClass = QLatin1String(mo->classInfo(mo->indexOfClassInfo("CoClass")).value()); stream << "<h1 align=center>" << coClass << " Reference</h1>" << endl; stream << "<p>The " << coClass << " COM object is a " << that->qObject()->metaObject()->className(); stream << " with the CLSID " << that->control() << ".</p>" << endl; stream << "<h3>Interfaces</h3>" << endl; stream << "<ul>" << endl; const char *inter = 0; int interCount = 1; while ((inter = mo->classInfo(mo->indexOfClassInfo("Interface " + QByteArray::number(interCount))).value())) { stream << "<li>" << inter << endl; interCount++; } stream << "</ul>" << endl; stream << "<h3>Event Interfaces</h3>" << endl; stream << "<ul>" << endl; interCount = 1; while ((inter = mo->classInfo(mo->indexOfClassInfo("Event Interface " + QByteArray::number(interCount))).value())) { stream << "<li>" << inter << endl; interCount++; } stream << "</ul>" << endl; QList<QString> methodDetails, propDetails; const int slotCount = mo->methodCount(); if (slotCount) { stream << "<h2>Public Slots:</h2>" << endl; stream << "<ul>" << endl; int defArgCount = 0; for (int islot = mo->methodOffset(); islot < slotCount; ++islot) { const QMetaMethod slot = mo->method(islot); if (slot.methodType() != QMetaMethod::Slot) continue; if (slot.attributes() & QMetaMethod::Cloned) { ++defArgCount; continue; } QByteArray returntype(slot.typeName()); if (returntype.isEmpty()) returntype = "void"; QByteArray prototype = namedPrototype(slot.parameterTypes(), slot.parameterNames(), defArgCount); QByteArray signature = slot.methodSignature(); QByteArray name = signature.left(signature.indexOf('(')); stream << "<li>" << returntype << " <a href=\"#" << name << "\"><b>" << name << "</b></a>" << prototype << ";</li>" << endl; prototype = namedPrototype(slot.parameterTypes(), slot.parameterNames()); QString detail = QString::fromLatin1("<h3><a name=") + QString::fromLatin1(name.constData()) + QLatin1String("></a>") + QLatin1String(returntype.constData()) + QLatin1Char(' ') + QLatin1String(name.constData()) + QLatin1Char(' ') + QString::fromLatin1(prototype.constData()) + QLatin1String("<tt> [slot]</tt></h3>\n"); prototype = namedPrototype(slot.parameterTypes(), QList<QByteArray>()); detail += docuFromName(typeInfo, QString::fromLatin1(name.constData())); detail += QLatin1String("<p>Connect a signal to this slot:<pre>\n"); detail += QString::fromLatin1("\tQObject::connect(sender, SIGNAL(someSignal") + QString::fromLatin1(prototype.constData()) + QLatin1String("), object, SLOT(") + QString::fromLatin1(name.constData()) + QString::fromLatin1(prototype.constData()) + QLatin1String("));"); detail += QLatin1String("</pre>\n"); if (1) { detail += QLatin1String("<p>Or call the function directly:<pre>\n"); bool hasParams = slot.parameterTypes().count() != 0; if (hasParams) detail += QLatin1String("\tQVariantList params = ...\n"); detail += QLatin1String("\t"); QByteArray functionToCall = "dynamicCall"; if (returntype == "IDispatch*" || returntype == "IUnknown*") { functionToCall = "querySubObject"; returntype = "QAxObject *"; } if (returntype != "void") detail += QLatin1String(returntype.constData()) + QLatin1String(" result = "); detail += QLatin1String("object->") + QLatin1String(functionToCall.constData()) + QLatin1String("(\"" + name + prototype + '\"'); if (hasParams) detail += QLatin1String(", params"); detail += QLatin1Char(')'); if (returntype != "void" && returntype != "QAxObject *" && returntype != "QVariant") detail += QLatin1Char('.') + QLatin1String(toType(returntype)); detail += QLatin1String(";</pre>\n"); } else { detail += QLatin1String("<p>This function has parameters of unsupported types and cannot be called directly."); } methodDetails << detail; defArgCount = 0; } stream << "</ul>" << endl; } int signalCount = mo->methodCount(); if (signalCount) { ITypeLib *typeLib = 0; if (typeInfo) { UINT index = 0; typeInfo->GetContainingTypeLib(&typeLib, &index); typeInfo->Release(); } typeInfo = 0; stream << "<h2>Signals:</h2>" << endl; stream << "<ul>" << endl; for (int isignal = mo->methodOffset(); isignal < signalCount; ++isignal) { const QMetaMethod signal(mo->method(isignal)); if (signal.methodType() != QMetaMethod::Signal) continue; QByteArray prototype = namedPrototype(signal.parameterTypes(), signal.parameterNames()); QByteArray signature = signal.methodSignature(); QByteArray name = signature.left(signature.indexOf('(')); stream << "<li>void <a href=\"#" << name << "\"><b>" << name << "</b></a>" << prototype << ";</li>" << endl; QString detail = QLatin1String("<h3><a name=") + QLatin1String(name.constData()) + QLatin1String("></a>void ") + QLatin1String(name.constData()) + QLatin1Char(' ') + QLatin1String(prototype.constData()) + QLatin1String("<tt> [signal]</tt></h3>\n"); if (typeLib) { interCount = 0; do { if (typeInfo) typeInfo->Release(); typeInfo = 0; typeLib->GetTypeInfo(++interCount, &typeInfo); QString typeLibDocu = docuFromName(typeInfo, QString::fromLatin1(name.constData())); if (!typeLibDocu.isEmpty()) { detail += typeLibDocu; break; } } while (typeInfo); } prototype = namedPrototype(signal.parameterTypes(), QList<QByteArray>()); detail += QLatin1String("<p>Connect a slot to this signal:<pre>\n"); detail += QLatin1String("\tQObject::connect(object, SIGNAL(") + QString::fromLatin1(name.constData()) + QString::fromLatin1(prototype.constData()) + QLatin1String("), receiver, SLOT(someSlot") + QString::fromLatin1(prototype.constData()) + QLatin1String("));"); detail += QLatin1String("</pre>\n"); methodDetails << detail; if (typeInfo) typeInfo->Release(); typeInfo = 0; } stream << "</ul>" << endl; if (typeLib) typeLib->Release(); } const int propCount = mo->propertyCount(); if (propCount) { if (dispatch) dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo); stream << "<h2>Properties:</h2>" << endl; stream << "<ul>" << endl; for (int iprop = 0; iprop < propCount; ++iprop) { const QMetaProperty prop = mo->property(iprop); QByteArray name(prop.name()); QByteArray type(prop.typeName()); stream << "<li>" << type << " <a href=\"#" << name << "\"><b>" << name << "</b></a>;</li>" << endl; QString detail = QLatin1String("<h3><a name=") + QString::fromLatin1(name.constData()) + QLatin1String("></a>") + QLatin1String(type.constData()) + QLatin1Char(' ') + QLatin1String(name.constData()) + QLatin1String("</h3>\n"); detail += docuFromName(typeInfo, QString::fromLatin1(name)); QVariant::Type vartype = QVariant::nameToType(type); if (!prop.isReadable()) continue; if (prop.isEnumType()) vartype = QVariant::Int; if (vartype != QVariant::Invalid) { detail += QLatin1String("<p>Read this property's value using QObject::property:<pre>\n"); if (prop.isEnumType()) detail += QLatin1String("\tint val = "); else detail += QLatin1Char('\t') + QLatin1String(type.constData()) + QLatin1String(" val = "); detail += QLatin1String("object->property(\"") + QLatin1String(name.constData()) + QLatin1String("\").") + QLatin1String(toType(type).constData()) + QLatin1String(";\n"); detail += QLatin1String("</pre>\n"); } else if (type == "IDispatch*" || type == "IUnknown*") { detail += QLatin1String("<p>Get the subobject using querySubObject:<pre>\n"); detail += QLatin1String("\tQAxObject *") + QLatin1String(name.constData()) + QLatin1String(" = object->querySubObject(\"") + QLatin1String(name.constData()) + QLatin1String("\");\n"); detail += QLatin1String("</pre>\n"); } else { detail += QLatin1String("<p>This property is of an unsupported type.\n"); } if (prop.isWritable()) { detail += QLatin1String("Set this property' value using QObject::setProperty:<pre>\n"); if (prop.isEnumType()) { detail += QLatin1String("\tint newValue = ... // string representation of values also supported\n"); } else { detail += QLatin1String("\t") + QString::fromLatin1(type.constData()) + QLatin1String(" newValue = ...\n"); } detail += QLatin1String("\tobject->setProperty(\"") + QString::fromLatin1(name) + QLatin1String("\", newValue);\n"); detail += QLatin1String("</pre>\n"); detail += QLatin1String("Or using the "); QByteArray setterSlot; if (isupper(name.at(0))) { setterSlot = "Set" + name; } else { QByteArray nameUp = name; nameUp[0] = toupper(nameUp.at(0)); setterSlot = "set" + nameUp; } detail += QLatin1String("<a href=\"#") + QString::fromLatin1(setterSlot) + QLatin1String("\">") + QString::fromLatin1(setterSlot.constData()) + QLatin1String("</a> slot.\n"); } if (prop.isEnumType()) { detail += QLatin1String("<p>See also <a href=\"#") + QString::fromLatin1(type) + QLatin1String("\">") + QString::fromLatin1(type) + QLatin1String("</a>.\n"); } propDetails << detail; } stream << "</ul>" << endl; } const int enumCount = mo->enumeratorCount(); if (enumCount) { stream << "<hr><h2>Member Type Documentation</h2>" << endl; for (int i = 0; i < enumCount; ++i) { const QMetaEnum enumdata = mo->enumerator(i); stream << "<h3><a name=" << enumdata.name() << "></a>" << enumdata.name() << "</h3>" << endl; stream << "<ul>" << endl; for (int e = 0; e < enumdata.keyCount(); ++e) { stream << "<li>" << enumdata.key(e) << "\t=" << enumdata.value(e) << "</li>" << endl; } stream << "</ul>" << endl; } } if (methodDetails.count()) { stream << "<hr><h2>Member Function Documentation</h2>" << endl; for (int i = 0; i < methodDetails.count(); ++i) stream << methodDetails.at(i) << endl; } if (propDetails.count()) { stream << "<hr><h2>Property Documentation</h2>" << endl; for (int i = 0; i < propDetails.count(); ++i) stream << propDetails.at(i) << endl; } if (typeInfo) typeInfo->Release(); if (dispatch) dispatch->Release(); return docu; }
void ObjectControllerPrivate::addClassProperties(const QMetaObject *inmetaObject, bool subGroup) { if (!inmetaObject) return; // Collect a list of all sub classes in the object QList< const QMetaObject *> metaObjectsList; metaObjectsList.clear(); metaObjectsList << inmetaObject; const QMetaObject *tmpObj = inmetaObject->superClass(); metaObjectsList << tmpObj; while (tmpObj) { tmpObj = tmpObj->superClass(); if (tmpObj) metaObjectsList << tmpObj; } const QMetaObject *metaObject; for (int i = 0; i < metaObjectsList.count(); i++) { metaObject = metaObjectsList[i]; QtProperty *classProperty = m_classToProperty.value(metaObject); if (!classProperty) { QString className = QLatin1String(metaObject->className()); // Note: Skip class QObject from the property views if (className == QLatin1String("QObject")) return; // Process Class name into a user friendly view // Strip prefix C_ and process all _ to spaces QString prefix("C_"); // String to replace. QString replaceprefix(""); // Replacement string. className.replace(className.indexOf(prefix), prefix.size(), replaceprefix); className.replace(QString("_"), QString(" ")); classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className); m_classToProperty[metaObject] = classProperty; m_propertyToClass[classProperty] = metaObject; for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { QMetaProperty metaProperty = metaObject->property(idx); int type = metaProperty.userType(); QtVariantProperty *subProperty = 0; // Note: Get the var member name and check if we want it to be writable (Enabled) QString memberVarName = QLatin1String(metaProperty.name()); bool b_SetEnabled = true; // Special case for enabling or disabling editing QString ememberVarName = "e" + QLatin1String(metaProperty.name()); QByteArray array = ememberVarName.toLocal8Bit(); char* buffer = array.data(); QVariant set = m_object->property(buffer); if (set.type() == QVariant::Bool) { b_SetEnabled = (bool &)set; } // qDebug() << "Member Name :" << memberVarName; // Note: process the first char if it contains _ then the var is read only and remove the _ char if (memberVarName.at(0) == "_") { b_SetEnabled = false; memberVarName.remove(0, 1); } // after that replace all occurance of _ with space char for display memberVarName.replace(QString("_"), QString(" ")); if (!metaProperty.isReadable()) { subProperty = m_readOnlyManager->addProperty(QVariant::String, memberVarName); subProperty->setValue(QLatin1String("< Non Readable >")); } else if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), memberVarName); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; QStringList flagNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value) && isPowerOf2(value)) { valueMap[value] = true; flagNames.append(QLatin1String(metaEnum.key(i))); } subProperty->setAttribute(QLatin1String("flagNames"), flagNames); subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else { subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), memberVarName); QMetaEnum metaEnum = metaProperty.enumerator(); QMap<int, bool> valueMap; // dont show multiple enum values which have the same values QStringList enumNames; for (int i = 0; i < metaEnum.keyCount(); i++) { int value = metaEnum.value(i); if (!valueMap.contains(value)) { valueMap[value] = true; enumNames.append(QLatin1String(metaEnum.key(i))); } } subProperty->setAttribute(QLatin1String("enumNames"), enumNames); subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt())); } } else if (m_manager->isPropertyTypeSupported(type)) { if (!metaProperty.isWritable()) subProperty = m_readOnlyManager->addProperty(type, memberVarName + QLatin1String(" (Non Writable)")); if (!metaProperty.isDesignable()) subProperty = m_readOnlyManager->addProperty(type, memberVarName + QLatin1String(" (Non Designable)")); else subProperty = m_manager->addProperty(type, memberVarName); subProperty->setValue(metaProperty.read(m_object)); } else { subProperty = m_readOnlyManager->addProperty(QVariant::String, memberVarName); subProperty->setValue(QLatin1String("< Unknown Type >")); b_SetEnabled = false; } // Notes: QtVariantProperty *priority = variantManager->addProperty(QVariant::Int, "Priority"); if (subProperty) subProperty->setEnabled(b_SetEnabled); m_propertyToIndex[subProperty] = idx; m_classToIndexToProperty[metaObject][idx] = subProperty; if (subGroup) classProperty->addSubProperty(subProperty); else m_browser->addProperty(subProperty); } } else { updateClassProperties(metaObject, false); } m_topLevelProperties.append(classProperty); if (subGroup) m_browser->addProperty(classProperty); } // Loop i }
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 QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) { Q_Q(QDBusInterface); if (c == QMetaObject::InvokeMetaMethod) { int offset = metaObject->methodOffset(); QMetaMethod mm = metaObject->method(id + offset); if (mm.methodType() == QMetaMethod::Signal) { // signal relay from D-Bus world to Qt world QMetaObject::activate(q, metaObject, id, argv); } else if (mm.methodType() == QMetaMethod::Slot) { // method call relay from Qt world to D-Bus world // get D-Bus equivalent signature QString methodName = QLatin1String(metaObject->dbusNameForMethod(id)); const int *inputTypes = metaObject->inputTypesForMethod(id); int inputTypesCount = *inputTypes; // we will assume that the input arguments were passed correctly QVariantList args; for (int i = 1; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); // make the call QPointer<QDBusInterface> qq = q; QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args); args.clear(); // we ignore return values // access to "this" or to "q" below this point must check for "qq" // we may have been deleted! if (!qq.isNull()) lastError = reply; // done return -1; } } else if (c == QMetaObject::ReadProperty) { // Qt doesn't support non-readable properties // we have to re-check QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); if (!mp.isReadable()) return -1; // don't read QVariant *value = reinterpret_cast<QVariant*>(argv[1]); argv[1] = 0; *value = property(mp); return -1; // handled, error or not } else if (c == QMetaObject::WriteProperty) { // QMetaProperty::write has already checked that we're writable // it has also checked that the type is right QVariant *value = reinterpret_cast<QVariant *>(argv[1]); QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); setProperty(mp, *value); return -1; } return id; }
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 ); }