📄 qdbusxml2cpp.cpp
字号:
for (int i = 0; i < inputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = inputArgs.at(i); QString name = arg.name; if (name.isEmpty()) name = QString( QLatin1String("in%1") ).arg(i); while (retval.contains(name)) name += QLatin1String("_"); retval << name; } for (int i = 0; i < outputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = outputArgs.at(i); QString name = arg.name; if (name.isEmpty()) name = QString( QLatin1String("out%1") ).arg(i); while (retval.contains(name)) name += QLatin1String("_"); retval << name; } return retval;}static void writeArgList(QTextStream &ts, const QStringList &argNames, const QDBusIntrospection::Annotations &annotations, const QDBusIntrospection::Arguments &inputArgs, const QDBusIntrospection::Arguments &outputArgs = QDBusIntrospection::Arguments()){ // input args: bool first = true; int argPos = 0; for (int i = 0; i < inputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = inputArgs.at(i); QString type = constRefArg(qtTypeName(arg.type, annotations, i, "In")); if (!first) ts << ", "; ts << type << argNames.at(argPos++); first = false; } argPos++; // output args // yes, starting from 1 for (int i = 1; i < outputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = outputArgs.at(i); QString name = arg.name; if (!first) ts << ", "; ts << nonConstRefArg(qtTypeName(arg.type, annotations, i, "Out")) << argNames.at(argPos++); first = false; }}static QString propertyGetter(const QDBusIntrospection::Property &property){ QString getter = property.annotations.value(QLatin1String("com.trolltech.QtDBus.propertyGetter")); if (getter.isEmpty()) { getter = property.name; getter[0] = getter[0].toLower(); } return getter;}static QString propertySetter(const QDBusIntrospection::Property &property){ QString setter = property.annotations.value(QLatin1String("com.trolltech.QtDBus.propertySetter")); if (setter.isEmpty()) { setter = QLatin1String("set") + property.name; setter[3] = setter[3].toUpper(); } return setter;}static QString stringify(const QString &data){ QString retval; int i; for (i = 0; i < data.length(); ++i) { retval += QLatin1Char('\"'); for ( ; i < data.length() && data[i] != QLatin1Char('\n'); ++i) if (data[i] == QLatin1Char('\"')) retval += QLatin1String("\\\""); else retval += data[i]; retval += QLatin1String("\\n\"\n"); } return retval;}static void openFile(const QString &fileName, QFile &file){ if (fileName.isEmpty()) return; bool isOk = false; if (fileName == QLatin1String("-")) { isOk = file.open(stdout, QIODevice::WriteOnly | QIODevice::Text); } else { file.setFileName(fileName); isOk = file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text); } if (!isOk) fprintf(stderr, "Unable to open '%s': %s\n", qPrintable(fileName), qPrintable(file.errorString()));}static void writeProxy(const QString &filename, const QDBusIntrospection::Interfaces &interfaces){ // open the file QString headerName = header(filename); QByteArray headerData; QTextStream hs(&headerData); QString cppName = cpp(filename); QByteArray cppData; QTextStream cs(&cppData); // write the header: writeHeader(hs, true); if (cppName != headerName) writeHeader(cs, false); // include guards: QString includeGuard; if (!headerName.isEmpty() && headerName != QLatin1String("-")) { includeGuard = headerName.toUpper().replace(QLatin1Char('.'), QLatin1Char('_')); int pos = includeGuard.lastIndexOf(QLatin1Char('/')); if (pos != -1) includeGuard = includeGuard.mid(pos + 1); } else { includeGuard = QLatin1String("QDBUSXML2CPP_PROXY"); } includeGuard = QString(QLatin1String("%1_%2")) .arg(includeGuard) .arg(QDateTime::currentDateTime().toTime_t()); hs << "#ifndef " << includeGuard << endl << "#define " << includeGuard << endl << endl; // include our stuff: hs << "#include <QtCore/QObject>" << endl << includeList << "#include <QtDBus/QtDBus>" << endl; foreach (QString include, includes) { hs << "#include \"" << include << "\"" << endl; if (headerName.isEmpty()) cs << "#include \"" << include << "\"" << endl; } hs << endl; if (cppName != headerName) { if (!headerName.isEmpty() && headerName != QLatin1String("-")) cs << "#include \"" << headerName << "\"" << endl << endl; } foreach (const QDBusIntrospection::Interface *interface, interfaces) { QString className = classNameForInterface(interface->name, Proxy); // comment: hs << "/*" << endl << " * Proxy class for interface " << interface->name << endl << " */" << endl; cs << "/*" << endl << " * Implementation of interface class " << className << endl << " */" << endl << endl; // class header: hs << "class " << className << ": public QDBusAbstractInterface" << endl << "{" << endl << " Q_OBJECT" << endl; // the interface name hs << "public:" << endl << " static inline const char *staticInterfaceName()" << endl << " { return \"" << interface->name << "\"; }" << endl << endl; // constructors/destructors: hs << "public:" << endl << " " << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);" << endl << endl << " ~" << className << "();" << endl << endl; cs << className << "::" << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)" << endl << " : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)" << endl << "{" << endl << "}" << endl << endl << className << "::~" << className << "()" << endl << "{" << endl << "}" << endl << endl; // properties: foreach (const QDBusIntrospection::Property &property, interface->properties) { QByteArray type = qtTypeName(property.type, property.annotations); QString templateType = templateArg(type); QString constRefType = constRefArg(type); QString getter = propertyGetter(property); QString setter = propertySetter(property); hs << " Q_PROPERTY(" << type << " " << property.name; // getter: if (property.access != QDBusIntrospection::Property::Write) // it's readble hs << " READ " << getter; // setter if (property.access != QDBusIntrospection::Property::Read) // it's writeable hs << " WRITE " << setter; hs << ")" << endl; // getter: if (property.access != QDBusIntrospection::Property::Write) { hs << " inline " << type << " " << getter << "() const" << endl; if (type != "QVariant") hs << " { return qvariant_cast< " << type << " >(internalPropGet(\"" << property.name << "\")); }" << endl; else hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl; } // setter: if (property.access != QDBusIntrospection::Property::Read) { hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl << " { internalPropSet(\"" << property.name << "\", qVariantFromValue(value)); }" << endl; } hs << endl; } // methods: hs << "public Q_SLOTS: // METHODS" << endl; foreach (const QDBusIntrospection::Method &method, interface->methods) { bool isNoReply = method.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true"); if (isNoReply && !method.outputArgs.isEmpty()) { fprintf(stderr, "warning: method %s in interface %s is marked 'no-reply' but has output arguments.\n", qPrintable(method.name), qPrintable(interface->name)); continue; } hs << " inline "; if (method.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) == QLatin1String("true")) hs << "Q_DECL_DEPRECATED "; if (isNoReply) hs << "Q_NOREPLY void "; else if (method.outputArgs.isEmpty()) hs << "QDBusReply<void> "; else { hs << "QDBusReply<" << templateArg(qtTypeName(method.outputArgs.first().type, method.annotations, 0, "Out")) << "> "; } hs << method.name << "("; QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs); writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs); hs << ")" << endl << " {" << endl << " QList<QVariant> argumentList;" << endl; int argPos = 0; if (!method.inputArgs.isEmpty()) { hs << " argumentList"; for (argPos = 0; argPos < method.inputArgs.count(); ++argPos) hs << " << qVariantFromValue(" << argNames.at(argPos) << ')'; hs << ";" << endl; } if (method.outputArgs.count() > 1) hs << " QDBusMessage reply = callWithArgumentList(QDBus::Block, " << "QLatin1String(\"" << method.name << "\"), argumentList);" << endl; else if (!isNoReply) hs << " return callWithArgumentList(QDBus::Block, " << "QLatin1String(\"" << method.name << "\"), argumentList);" << endl; else hs << " callWithArgumentList(QDBus::NoBlock, " << "QLatin1String(\"" << method.name << "\"), argumentList);" << endl; argPos++; if (method.outputArgs.count() > 1) { hs << " if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == " << method.outputArgs.count() << ") {" << endl; // yes, starting from 1 for (int i = 1; i < method.outputArgs.count(); ++i) hs << " " << argNames.at(argPos++) << " = qdbus_cast<" << templateArg(qtTypeName(method.outputArgs.at(i).type, method.annotations, i, "Out")) << ">(reply.arguments().at(" << i << "));" << endl; hs << " }" << endl << " return reply;" << endl; } // close the function: hs << " }" << endl << endl; } hs << "Q_SIGNALS: // SIGNALS" << endl; foreach (const QDBusIntrospection::Signal &signal, interface->signals_) { hs << " "; if (signal.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) == QLatin1String("true")) hs << "Q_DECL_DEPRECATED "; hs << "void " << signal.name << "("; QStringList argNames = makeArgNames(signal.outputArgs); writeArgList(hs, argNames, signal.annotations, signal.outputArgs); hs << ");" << endl; // finished for header } // close the class: hs << "};" << endl << endl; } if (!skipNamespaces) { QStringList last; QDBusIntrospection::Interfaces::ConstIterator it = interfaces.constBegin(); do { QStringList current; QString name; if (it != interfaces.constEnd()) { current = it->constData()->name.split(QLatin1Char('.')); name = current.takeLast(); } int i = 0; while (i < current.count() && i < last.count() && current.at(i) == last.at(i)) ++i; // i parts matched // close last.arguments().count() - i namespaces: for (int j = i; j < last.count(); ++j) hs << QString((last.count() - j - 1 + i) * 2, QLatin1Char(' ')) << "}" << endl; // open current.arguments().count() - i namespaces for (int j = i; j < current.count(); ++j) hs << QString(j * 2, QLatin1Char(' ')) << "namespace " << current.at(j) << " {" << endl; // add this class: if (!name.isEmpty()) { hs << QString(current.count() * 2, QLatin1Char(' ')) << "typedef ::" << classNameForInterface(it->constData()->name, Proxy) << " " << name << ";" << endl; } if (it == interfaces.constEnd()) break; ++it; last = current;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -