QVariant ObjectEnumModel::metaData(const QModelIndex &index, const QMetaEnum &enumerator, int role) const { if (role == Qt::DisplayRole) { if (index.column() == 0) { return QString::fromLatin1(enumerator.name()); } if (index.column() == 1) { return tr("%n element(s)", "", enumerator.keyCount()); } } return QVariant(); }
void MetaInfoPrivate::parseProperties(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const { Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject"); Q_ASSERT_X(nodeMetaInfo.isValid(), Q_FUNC_INFO, "invalid NodeMetaInfo"); for (int i = qMetaObject->propertyOffset(); i < qMetaObject->propertyCount(); ++i) { QMetaProperty qProperty = qMetaObject->property(i); PropertyMetaInfo propertyInfo; propertyInfo.setName(QLatin1String(qProperty.name())); QString typeName(qProperty.typeName()); QString noStar = typeName; bool star = false; while (noStar.contains('*')) {//strip star noStar.chop(1); star = true; } if (m_QtTypesToQmlTypes.contains(noStar)) { typeName = star ? m_QtTypesToQmlTypes.value(noStar) + '*' : m_QtTypesToQmlTypes.value(noStar); //### versions } propertyInfo.setType(typeName); propertyInfo.setValid(true); propertyInfo.setReadable(qProperty.isReadable()); propertyInfo.setWritable(qProperty.isWritable()); propertyInfo.setResettable(qProperty.isResettable()); propertyInfo.setEnumType(qProperty.isEnumType()); propertyInfo.setFlagType(qProperty.isFlagType()); if (propertyInfo.isEnumType()) { EnumeratorMetaInfo enumerator; QMetaEnum qEnumerator = qProperty.enumerator(); enumerator.setValid(qEnumerator.isValid()); enumerator.setIsFlagType(qEnumerator.isFlag()); enumerator.setScope(qEnumerator.scope()); enumerator.setName(qEnumerator.name()); for (int i = 0 ;i < qEnumerator.keyCount(); i++) { enumerator.addElement(qEnumerator.valueToKey(i), i); } propertyInfo.setEnumerator(enumerator); } nodeMetaInfo.addProperty(propertyInfo); } }
QString RemoteArchiveModel::networkErrorToString(QNetworkReply::NetworkError error) { QString errorValue; QMetaObject meta = QNetworkReply::staticMetaObject; for (int i = 0; i < meta.enumeratorCount(); ++i) { QMetaEnum m = meta.enumerator(i); if (m.name() == QLatin1String("NetworkError")) { errorValue = QLatin1String(m.valueToKey(error)); break; } } return errorValue; }
void QtScriptEngine::copyEnumsToScriptObject( QScriptEngine *engine, const QMetaObject *metaObject, QScriptValue *object) { for (int enumIndex = 0; enumIndex < metaObject->enumeratorCount(); enumIndex++) { QMetaEnum metaEnum = metaObject->enumerator(enumIndex); QScriptValue enumClass = engine->newObject(); for (int keyIndex = 0; keyIndex < metaEnum.keyCount(); keyIndex++) { enumClass.setProperty(metaEnum.key(keyIndex), metaEnum.value(keyIndex)); } object->setProperty(metaEnum.name(), enumClass); } }
int QDeclarativeObjectMethodScriptClass::enumType(const QMetaObject *meta, const QString &strname) { QByteArray str = strname.toUtf8(); QByteArray scope; QByteArray name; int scopeIdx = str.lastIndexOf("::"); if (scopeIdx != -1) { scope = str.left(scopeIdx); name = str.mid(scopeIdx + 2); } else { name = str; } for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { QMetaEnum m = meta->enumerator(i); if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) return QVariant::Int; } return QVariant::Invalid; }
//! Displays a QMessageBox with the connection error void NameFinderWidget::displayError(QNetworkReply::NetworkError error) { QMessageBox errorBox; errorBox.setIcon(QMessageBox::Critical); errorBox.setWindowTitle(tr("Error!")); if (error == QNetworkReply::AuthenticationRequiredError) { errorBox.setText(tr("Name finder service requires authentication.")); } else { QMetaObject meta = QNetworkReply::staticMetaObject; for (int i=0; i < meta.enumeratorCount(); ++i) { QMetaEnum m = meta.enumerator(i); if (m.name() == QLatin1String("NetworkError")) { errorBox.setText(QLatin1String(m.valueToKey(error))); break; } } } errorBox.exec(); emit done(); }
//writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC! bool QDeclarativePropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags) { if (!object || !prop.isWritable()) return false; QVariant v = value; if (prop.isEnumType()) { QMetaEnum menum = prop.enumerator(); if (v.userType() == QVariant::String #ifdef QT3_SUPPORT || v.userType() == QVariant::CString #endif ) { if (prop.isFlagType()) v = QVariant(menum.keysToValue(value.toByteArray())); else v = QVariant(menum.keyToValue(value.toByteArray())); } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) { int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope()) + "::" + menum.name()); if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData()) return false; v = QVariant(*reinterpret_cast<const int *>(v.constData())); } v.convert(QVariant::Int); } // the status variable is changed by qt_metacall to indicate what it did // this feature is currently only used by QtDBus and should not be depended // upon. Don't change it without looking into QDBusAbstractInterface first // -1 (unchanged): normal qt_metacall, result stored in argv[0] // changed: result stored directly in value, return the value of status int status = -1; void *argv[] = { v.data(), &v, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, idx, argv); return status; }
void QSAEditor::completeQMetaObject( const QMetaObject *meta, const QString &, QVector<CompletionEntry> &res, int flags, QSObject &obj ) { QMap<QString, bool> propMap; bool includeSuperClass = (flags & IncludeSuperClass) == IncludeSuperClass; // properties const QMetaObject *m = meta; int num = m->propertyCount(); for ( int j = 0; j < num; ++j ) { const QMetaProperty mp = m->property( j ); if ( propMap.find( QString::fromLatin1(mp.name()) ) != propMap.end() ) continue; CompletionEntry c; propMap[QLatin1String(mp.name())] = false; c.type = QLatin1String("property"); c.text = mp.name(); c.prefix = QString(); c.postfix2 = mp.typeName(); QuickInterpreter::cleanType( c.postfix2 ); if ( !c.postfix2.isEmpty() ) c.postfix2.prepend( QLatin1String(" : ") ); res.append( c ); } if ( includeSuperClass && obj.isValid() && !obj.isUndefined() ) { QStringList vars = interpreter()->variablesOf( obj, true ); QStringList::iterator it; for ( it = vars.begin(); it != vars.end(); ++it ) { CompletionEntry c; c.type = QLatin1String("variable"); c.text = *it; c.prefix = QString(); c.postfix2 = QString(); res << c; } } // functions QList<Property> lst; QList<Property>::Iterator pit; getSlots( meta, lst, includeSuperClass, false, false ); for ( pit = lst.begin(); pit != lst.end(); ++pit ) { CompletionEntry c; c.type = QLatin1String("function"); c.text = (*pit).name; c.postfix = QLatin1String("()"); c.postfix2 = (*pit).type; if ( !c.postfix2.isEmpty() ) c.postfix2.prepend( QString::fromLatin1(" : ") ); res << c; } if ( includeSuperClass && obj.isValid() && !obj.isUndefined() ) { QStringList funcs = interpreter()->functionsOf( obj, true, true, true ); QStringList::Iterator it; for ( it = funcs.begin(); it != funcs.end(); ++it ) { CompletionEntry c; c.type = QLatin1String("function"); c.text = *it; c.prefix = QString(); c.postfix2 = QString(); res << c; } } // enum values m = meta; for (int k=0; k<m->enumeratorCount(); ++k) { QMetaEnum me = m->enumerator(k); for (int l=0; l<me.keyCount(); ++l) { CompletionEntry c; c.type = QLatin1String("enum"); c.text = QLatin1String(me.key(l)); c.prefix = QString(); c.postfix2 = QLatin1String(me.name()); if (!c.postfix2.isEmpty()) c.postfix2.prepend( QString::fromLatin1(" : ") ); res << c; } } if ( includeSuperClass && obj.isValid() && !obj.isUndefined() ) { QStringList classes = interpreter()->classesOf( obj ); QStringList::Iterator it; for ( it = classes.begin(); it != classes.end(); ++it ) { CompletionEntry c; c.type = QLatin1String("class"); c.text = *it; c.prefix = QString(); c.postfix2 = QString(); res << c; } } }
QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object) { QJsonObject data; if (!object) { qWarning("null object given to MetaObjectPublisher - bad API usage?"); return data; } QJsonArray qtSignals; QJsonArray qtMethods; QJsonArray qtProperties; QJsonObject qtEnums; const QMetaObject *metaObject = object->metaObject(); QSet<int> notifySignals; QSet<QString> identifiers; for (int i = 0; i < metaObject->propertyCount(); ++i) { const QMetaProperty &prop = metaObject->property(i); QJsonArray propertyInfo; const QString &propertyName = QString::fromLatin1(prop.name()); propertyInfo.append(i); propertyInfo.append(propertyName); identifiers << propertyName; QJsonArray signalInfo; if (prop.hasNotifySignal()) { notifySignals << prop.notifySignalIndex(); const int numParams = prop.notifySignal().parameterCount(); if (numParams > 1) { qWarning("Notify signal for property '%s' has %d parameters, expected zero or one.", prop.name(), numParams); } // optimize: compress the common propertyChanged notification names, just send a 1 const QByteArray ¬ifySignal = prop.notifySignal().name(); static const QByteArray changedSuffix = QByteArrayLiteral("Changed"); if (notifySignal.length() == changedSuffix.length() + propertyName.length() && notifySignal.endsWith(changedSuffix) && notifySignal.startsWith(prop.name())) { signalInfo.append(1); } else { signalInfo.append(QString::fromLatin1(notifySignal)); } signalInfo.append(prop.notifySignalIndex()); } else if (!prop.isConstant()) { qWarning("Property '%s'' of object '%s' has no notify signal and is not constant, " "value updates in HTML will be broken!", prop.name(), object->metaObject()->className()); } propertyInfo.append(signalInfo); propertyInfo.append(wrapResult(prop.read(object))); qtProperties.append(propertyInfo); } for (int i = 0; i < metaObject->methodCount(); ++i) { if (notifySignals.contains(i)) { continue; } const QMetaMethod &method = metaObject->method(i); //NOTE: this must be a string, otherwise it will be converted to '{}' in QML const QString &name = QString::fromLatin1(method.name()); // optimize: skip overloaded methods/signals or property getters, on the JS side we can only // call one of them anyways // TODO: basic support for overloaded signals, methods if (identifiers.contains(name)) { continue; } identifiers << name; // send data as array to client with format: [name, index] QJsonArray data; data.append(name); data.append(i); if (method.methodType() == QMetaMethod::Signal) { qtSignals.append(data); } else if (method.access() == QMetaMethod::Public) { qtMethods.append(data); } } for (int i = 0; i < metaObject->enumeratorCount(); ++i) { QMetaEnum enumerator = metaObject->enumerator(i); QJsonObject values; for (int k = 0; k < enumerator.keyCount(); ++k) { values[QString::fromLatin1(enumerator.key(k))] = enumerator.value(k); } qtEnums[QString::fromLatin1(enumerator.name())] = values; } data[KEY_SIGNALS] = qtSignals; data[KEY_METHODS] = qtMethods; data[KEY_PROPERTIES] = qtProperties; if (!qtEnums.isEmpty()) { data[KEY_ENUMS] = qtEnums; } return data; }
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; }
static HRESULT classIDL(QObject *o, const QMetaObject *mo, const QString &className, bool isBindable, QTextStream &out) { int id = 1; int i = 0; if (!mo) return 3; QString topclass = qAxFactory()->exposeToSuperClass(className); if (topclass.isEmpty()) topclass = QLatin1String("QObject"); bool hasStockEvents = qAxFactory()->hasStockEvents(className); const QMetaObject *pmo = mo; do { pmo = pmo->superClass(); } while (pmo && topclass != QString::fromLatin1(pmo->className())); int enumoff = pmo ? pmo->enumeratorOffset() : mo->enumeratorOffset(); int methodoff = pmo ? pmo->methodOffset() : mo->methodOffset(); int propoff = pmo ? pmo->propertyOffset() : mo->propertyOffset(); int qtProps = 0; int qtSlots = 0; bool control = false; if (o && o->isWidgetType()) { qtProps = QWidget::staticMetaObject.propertyCount(); qtSlots = QWidget::staticMetaObject.methodCount(); control = true; } const QString classID = stripCurlyBraces(qAxFactory()->classID(className)); if (classID.isEmpty()) return 4; const QString interfaceID = stripCurlyBraces(qAxFactory()->interfaceID(className)); if (interfaceID.isEmpty()) return 5; const QString eventsID = stripCurlyBraces(qAxFactory()->eventsID(className)); const bool hasEvents = !eventsID.isEmpty(); QString cleanClassName = qax_clean_type(className, mo); QString defProp(QLatin1String(mo->classInfo(mo->indexOfClassInfo("DefaultProperty")).value())); QString defSignal(QLatin1String(mo->classInfo(mo->indexOfClassInfo("DefaultSignal")).value())); for (i = enumoff; i < mo->enumeratorCount(); ++i) { const QMetaEnum enumerator = mo->enumerator(i); if (enums.contains(enumerator.name())) continue; enums.append(enumerator.name()); out << "\tenum " << enumerator.name() << " {" << endl; for (int j = 0; j < enumerator.keyCount(); ++j) { QByteArray key(enumerator.key(j)); while (enumValues.contains(key)) { key += '_'; } enumValues.append(key); const uint value = uint(enumerator.value(j)); key = key.leftJustified(20); out << "\t\t" << key << "\t= "; if (enumerator.isFlag()) out << "0x" << QByteArray::number(value, 16).rightJustified(8, '0'); else out << value; if (j < enumerator.keyCount()-1) out << ", "; out << endl; } out << "\t};" << endl << endl; } // mouse cursor enum for QCursor support if (!enums.contains("MousePointer")) { enums.append("MousePointer"); out << "\tenum MousePointer {" << endl; out << "\t\tArrowCursor = " << Qt::ArrowCursor << ',' << endl; out << "\t\tUpArrowCursor = " << Qt::UpArrowCursor << ',' << endl; out << "\t\tCrossCursor = " << Qt::CrossCursor << ',' << endl; out << "\t\tWaitCursor = " << Qt::WaitCursor << ',' << endl; out << "\t\tIBeamCursor = " << Qt::IBeamCursor << ',' << endl; out << "\t\tSizeVerCursor = " << Qt::SizeVerCursor << ',' << endl; out << "\t\tSizeHorCursor = " << Qt::SizeHorCursor << ',' << endl; out << "\t\tSizeBDiagCursor = " << Qt::SizeBDiagCursor << ',' << endl; out << "\t\tSizeFDiagCursor = " << Qt::SizeFDiagCursor << ',' << endl; out << "\t\tSizeAllCursor = " << Qt::SizeAllCursor << ',' << endl; out << "\t\tBlankCursor = " << Qt::BlankCursor << ',' << endl; out << "\t\tSplitVCursor = " << Qt::SplitVCursor << ',' << endl; out << "\t\tSplitHCursor = " << Qt::SplitHCursor << ',' << endl; out << "\t\tPointingHandCursor = " << Qt::PointingHandCursor << ',' << endl; out << "\t\tForbiddenCursor = " << Qt::ForbiddenCursor << ',' << endl; out << "\t\tWhatsThisCursor = " << Qt::WhatsThisCursor << ',' << endl; out << "\t\tBusyCursor\t= " << Qt::BusyCursor << endl; out << "\t};" << endl << endl; } if (!enums.contains("FocusPolicy")) { enums.append("FocusPolicy"); out << "\tenum FocusPolicy {" << endl; out << "\t\tNoFocus = " << Qt::NoFocus << ',' << endl; out << "\t\tTabFocus = " << Qt::TabFocus << ',' << endl; out << "\t\tClickFocus = " << Qt::ClickFocus << ',' << endl; out << "\t\tStrongFocus = " << Qt::StrongFocus << ',' << endl; out << "\t\tWheelFocus = " << Qt::WheelFocus << endl; out << "\t};" << endl << endl; } out << endl; out << "\t[" << endl; out << "\t\tuuid(" << interfaceID << ")," << endl; out << "\t\thelpstring(\"" << cleanClassName << " Interface\")" << endl; out << "\t]" << endl; out << "\tdispinterface I" << cleanClassName << endl; out << "\t{" << endl; out << "\tproperties:" << endl; for (i = propoff; i < mo->propertyCount(); ++i) { const QMetaProperty property = mo->property(i); /* if (property.testFlags(QMetaProperty::Override)) continue;*/ if (i <= qtProps && ignoreProps(property.name())) continue; if (!property.name() || mo->indexOfProperty(property.name()) > i) continue; bool ok = true; QByteArray type(convertTypes(property.typeName(), &ok)); QByteArray name(replaceKeyword(property.name())); if (!ok) out << "\t/****** Property is of unsupported datatype" << endl; out << "\t\t[id(" << id << ')'; if (!property.isWritable()) out << ", readonly"; if (isBindable && property.isScriptable(o)) out << ", bindable"; if (!property.isDesignable(o)) out << ", nonbrowsable"; if (isBindable) out << ", requestedit"; if (defProp == QLatin1String(name)) out << ", uidefault"; out << "] " << type << ' ' << name << ';' << endl; if (!ok) out << "\t******/" << endl; ++id; } out << endl; out << "\tmethods:" << endl; int numDefArgs = 0; QByteArray outBuffer; for (i = methodoff; i < mo->methodCount(); ++i) { const QMetaMethod slot = mo->method(i); if (slot.access() != QMetaMethod::Public || slot.methodType() == QMetaMethod::Signal) continue; if (slot.attributes() & QMetaMethod::Cloned) { ++numDefArgs; continue; } if (!outBuffer.isEmpty()) { outBuffer = addDefaultArguments(outBuffer, numDefArgs); numDefArgs = 0; out << outBuffer; outBuffer = QByteArray(); } QByteArray signature(slot.methodSignature()); QByteArray name(signature.left(signature.indexOf('('))); if (i <= qtSlots && ignoreSlots(name)) continue; signature.remove(0, name.length() + 1); signature.truncate(signature.length() - 1); name = renameOverloads(replaceKeyword(name)); if (ignoreSlots(name)) continue; QList<QByteArray> parameterTypes(slot.parameterTypes()); QList<QByteArray> parameterNames(slot.parameterNames()); bool ok = true; QByteArray type = slot.typeName(); if (type.isEmpty()) type = "void"; else type = convertTypes(type, &ok); QByteArray ptype(prototype(parameterTypes, parameterNames, &ok)); if (!ok) outBuffer += "\t/****** Slot parameter uses unsupported datatype\n"; outBuffer += "\t\t[id(" + QByteArray::number(id) + ")] " + type + ' ' + name + '(' + ptype + ");\n"; if (!ok) outBuffer += "\t******/\n"; ++id; } if (!outBuffer.isEmpty()) { outBuffer = addDefaultArguments(outBuffer, numDefArgs); numDefArgs = 0; out << outBuffer; outBuffer = QByteArray(); } out << "\t};" << endl << endl; mapping.clear(); id = 1; if (hasEvents) { out << "\t[" << endl; out << "\t\tuuid(" << eventsID << ")," << endl; out << "\t\thelpstring(\"" << cleanClassName << " Events Interface\")" << endl; out << "\t]" << endl; out << "\tdispinterface I" << cleanClassName << "Events" << endl; out << "\t{" << endl; out << "\tproperties:" << endl; out << "\tmethods:" << endl; if (hasStockEvents) { out << "\t/****** Stock events ******/" << endl; out << "\t\t[id(DISPID_CLICK)] void Click();" << endl; out << "\t\t[id(DISPID_DBLCLICK)] void DblClick();" << endl; out << "\t\t[id(DISPID_KEYDOWN)] void KeyDown(short* KeyCode, short Shift);" << endl; out << "\t\t[id(DISPID_KEYPRESS)] void KeyPress(short* KeyAscii);" << endl; out << "\t\t[id(DISPID_KEYUP)] void KeyUp(short* KeyCode, short Shift);" << endl; out << "\t\t[id(DISPID_MOUSEDOWN)] void MouseDown(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);" << endl; out << "\t\t[id(DISPID_MOUSEMOVE)] void MouseMove(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);" << endl; out << "\t\t[id(DISPID_MOUSEUP)] void MouseUp(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);" << endl << endl; } for (i = methodoff; i < mo->methodCount(); ++i) { const QMetaMethod signal = mo->method(i); if (signal.methodType() != QMetaMethod::Signal) continue; QByteArray signature(signal.methodSignature()); QByteArray name(signature.left(signature.indexOf('('))); signature.remove(0, name.length() + 1); signature.truncate(signature.length() - 1); QList<QByteArray> parameterTypes(signal.parameterTypes()); QList<QByteArray> parameterNames(signal.parameterNames()); bool isDefault = defSignal == QLatin1String(name); name = renameOverloads(replaceKeyword(name)); bool ok = true; QByteArray type = signal.typeName(); if (!type.isEmpty() && type != "void") // signals with return value not supported continue; QByteArray ptype(prototype(parameterTypes, parameterNames, &ok)); if (!ok) out << "\t/****** Signal parameter uses unsupported datatype" << endl; out << "\t\t[id(" << id << ')'; if (isDefault) out << ", uidefault"; out << "] void " << name << '(' << ptype << ");" << endl; if (!ok) out << "\t******/" << endl; ++id; } out << "\t};" << endl << endl; } out << "\t[" << endl; if (qstricmp(mo->classInfo(mo->indexOfClassInfo("Aggregatable")).value(), "no")) out << "\t\taggregatable," << endl; if (!qstricmp(mo->classInfo(mo->indexOfClassInfo("RegisterObject")).value(), "yes")) out << "\t\tappobject," << endl; if (mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value()) out << "\t\tlicensed," << endl; const char *helpString = mo->classInfo(mo->indexOfClassInfo("Description")).value(); if (helpString) out << "\t\thelpstring(\"" << helpString << "\")," << endl; else out << "\t\thelpstring(\"" << cleanClassName << " Class\")," << endl; const char *classVersion = mo->classInfo(mo->indexOfClassInfo("Version")).value(); if (classVersion) out << "\t\tversion(" << classVersion << ")," << endl; out << "\t\tuuid(" << classID << ')'; if (control) { out << ", " << endl; out << "\t\tcontrol"; } else if (!o) { out << ", " << endl; out << "\t\tnoncreatable"; } out << endl; out << "\t]" << endl; out << "\tcoclass " << cleanClassName << endl; out << "\t{" << endl; out << "\t\t[default] dispinterface I" << cleanClassName << ';' << endl; if (hasEvents) out << "\t\t[default, source] dispinterface I" << cleanClassName << "Events;" << endl; out << "\t};" << endl; return S_OK; }
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd) { // Set classname builder.setClassName(ignoreEnd->className()); // Clone Q_CLASSINFO for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) { QMetaClassInfo info = mo->classInfo(ii); int otherIndex = ignoreEnd->indexOfClassInfo(info.name()); if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) { // Skip } else { builder.addClassInfo(info.name(), info.value()); } } // Clone Q_PROPERTY for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) { QMetaProperty property = mo->property(ii); int otherIndex = ignoreEnd->indexOfProperty(property.name()); if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) { builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void")); // Skip } else { builder.addProperty(property); } } // Clone Q_METHODS for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) { QMetaMethod method = mo->method(ii); // More complex - need to search name QByteArray name = method.name(); bool found = false; for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount(); !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) { QMetaMethod other = ignoreEnd->method(ii); found = name == other.name(); } QMetaMethodBuilder m = builder.addMethod(method); if (found) // SKIP m.setAccess(QMetaMethod::Private); } // Clone Q_ENUMS for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) { QMetaEnum enumerator = mo->enumerator(ii); int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name()); if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) { // Skip } else { builder.addEnumerator(enumerator); } } }
QString AsemanQtTools::exportItem(const QString &module, int major, int minor, const QString &component, bool store) { QString result; aseman_qt_tools_indexCache << component; QMetaObject meta = T::staticMetaObject; QString inherits = fixType(meta.superClass()? meta.superClass()->className() : ""); bool isModel = component.toLower().contains("model"); result += QString("# %1\n\n").arg(component); QString headers; headers += QString(" * [Component details](#component-details)\n"); QString details = QString("\n### Component details:\n\n"); details += QString("|Detail|Value|\n" "|------|-----|\n"); details += QString("|%1|%2 %3.%4|\n").arg("Import").arg(module).arg(major).arg(minor); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("Component").arg(component); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("C++ class").arg(meta.className()); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("Inherits").arg(inherits); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("Model").arg(isModel?"Yes":"No"); QString resultProperties; QStringList propertiesSignals; for(int i=0; i<meta.propertyCount(); i++) { QMetaProperty property = meta.property(i); const QString &propertyName = property.name(); const QString &propertyType = fixType(property.typeName()); propertiesSignals << property.notifySignal().name(); QString text = QString("* <font color='#074885'><b>%1</b></font>: %2").arg(propertyName).arg(propertyType); if(!property.isWritable()) text += " (readOnly)"; text += "\n"; if(meta.propertyOffset()<=i) resultProperties += text; } QString enumResults; for(int i=meta.enumeratorOffset(); i<meta.enumeratorCount(); i++) { QMetaEnum enumerator = meta.enumerator(i); const QString &enumName = enumerator.name(); enumResults += QString("\n##### %1\n\n").arg(enumName); enumResults += QString("|Key|Value|\n" "|---|-----|\n"); for(int j=0; j<enumerator.keyCount(); j++) enumResults += QString("|%1|%2|\n").arg(enumerator.key(j)).arg(enumerator.value(j)); } QString resultSlots; QString resultSignals; for(int i=meta.methodOffset(); i<meta.methodCount(); i++) { QMetaMethod method = meta.method(i); if(method.access() != QMetaMethod::Public) continue; const QString &methodName = method.name(); if(propertiesSignals.contains(methodName)) continue; const QString &methodType = fixType(method.typeName()); QString args; const QList<QByteArray> ¶mNames = method.parameterNames(); const QList<QByteArray> ¶mTypes = method.parameterTypes(); for(int j=0; j<paramNames.count(); j++) { if(j != 0) args += ", "; args += fixType(paramTypes[j]) + " " + paramNames[j]; } QString text = QString(" * %1 <font color='#074885'><b>%2</b></font>(%3)\n").arg(methodType).arg(methodName).arg(args); switch(static_cast<int>(method.methodType())) { case QMetaMethod::Slot: resultSlots += text; break; case QMetaMethod::Signal: resultSignals += text; break; } } if(!resultProperties.isEmpty()) { headers += QString(" * [Normal Properties](#normal-properties)\n"); resultProperties = QString("\n### Normal Properties\n\n") + resultProperties; } if(!enumResults.isEmpty()) { headers += QString(" * [Enumerator](#enumerator)\n"); enumResults = QString("\n### Enumerator\n\n") + enumResults; } if(!resultSlots.isEmpty()) { headers += QString(" * [Methods](#methods)\n"); resultSlots = QString("\n### Methods\n\n") + resultSlots; } if(!resultSignals.isEmpty()) { headers += QString(" * [Signals](#signals)\n"); resultSignals = QString("\n### Signals\n\n") + resultSignals; } if(isModel) headers += QString(" * [Roles](#roles)\n"); result += headers + "\n"; result += details + "\n"; result += resultProperties + "\n"; result += resultSlots + "\n"; result += resultSignals + "\n"; result += enumResults + "\n"; if(!store) return result; QString path = aseman_qt_tools_destination + "/" + component.toLower() + ".md"; QFile file(path); if(!file.open(QFile::WriteOnly)) return result; file.write(result.toUtf8()); file.close(); return result; }