aboutsummaryrefslogtreecommitdiff
path: root/src/kconfig_compiler/KConfigSourceGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kconfig_compiler/KConfigSourceGenerator.cpp')
-rw-r--r--src/kconfig_compiler/KConfigSourceGenerator.cpp657
1 files changed, 657 insertions, 0 deletions
diff --git a/src/kconfig_compiler/KConfigSourceGenerator.cpp b/src/kconfig_compiler/KConfigSourceGenerator.cpp
new file mode 100644
index 00000000..f306693b
--- /dev/null
+++ b/src/kconfig_compiler/KConfigSourceGenerator.cpp
@@ -0,0 +1,657 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2020 Tomaz Cananbrava (tcanabrava@kde.org)
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
+ Copyright (c) 2003 Zack Rusin <zack@kde.org>
+ Copyright (c) 2006 Michaƫl Larouche <michael.larouche@kdemail.net>
+ Copyright (c) 2008 Allen Winter <winter@kde.org>
+ Copyright (C) 2020 Tomaz Cananbrava (tcanabrava@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "KConfigSourceGenerator.h"
+#include "KConfigCommonStructs.h"
+
+
+KConfigSourceGenerator::KConfigSourceGenerator(
+ const QString &inputFile,
+ const QString &baseDir,
+ const KConfigParameters &cfg,
+ ParseResult &result)
+ : KConfigCodeGeneratorBase(inputFile, baseDir, baseDir + cfg.baseName + QLatin1Char('.') + cfg.sourceExtension, cfg, result)
+{
+}
+
+void KConfigSourceGenerator::start()
+{
+ KConfigCodeGeneratorBase::start();
+ stream() << endl;
+ createHeaders();
+
+ if (!cfg().nameSpace.isEmpty()) {
+ stream() << "using namespace " << cfg().nameSpace << ";";
+ stream() << endl << endl;
+ }
+
+ createPrivateDPointerImplementation();
+ createSingletonImplementation();
+ createPreamble();
+ doConstructor();
+ doGetterSetterDPointerMode();
+ createDefaultValueGetterSetter();
+ createDestructor();
+ createNonModifyingSignalsHelper();
+ createSignalFlagsHandler();
+ includeMoc();
+}
+
+void KConfigSourceGenerator::createHeaders()
+{
+ QString headerName = cfg().baseName + QLatin1Char('.') + cfg().headerExtension;
+
+ // TODO: Make addQuotes return a string instead of replacing it inplace.
+ addQuotes(headerName);
+
+ addHeaders({ headerName });
+ stream() << endl;
+
+ addHeaders(cfg().sourceIncludes);
+ if (cfg().setUserTexts && cfg().translationSystem == KConfigParameters::KdeTranslation) {
+ addHeaders({QStringLiteral("klocalizedstring.h")});
+ stream() << endl;
+ }
+
+ // Header required by singleton implementation
+ if (cfg().singleton) {
+ addHeaders({QStringLiteral("qglobal.h"), QStringLiteral("QFile")});
+
+ // HACK: Add single line to fix test.
+ if (cfg().singleton && parseResult.cfgFileNameArg) {
+ stream() << endl;
+ }
+ }
+
+ if (cfg().singleton && parseResult.cfgFileNameArg) {
+ addHeaders({QStringLiteral("QDebug")});
+ }
+
+ if (cfg().singleton) {
+ stream() << endl;
+ }
+}
+
+void KConfigSourceGenerator::createPrivateDPointerImplementation()
+{
+ // private class implementation
+ if (!cfg().dpointer) {
+ return;
+ }
+
+ QString group;
+ beginNamespaces();
+ stream() << "class " << cfg().className << "Private" << endl;
+ stream() << "{" << endl;
+ stream() << " public:" << endl;
+
+ // Create Members
+ for (auto *entry : parseResult.entries) {
+ if (entry->group != group) {
+ group = entry->group;
+ stream() << endl;
+ stream() << " // " << group << endl;
+ }
+ stream() << " " << cppType(entry->type) << " " << varName(entry->name, cfg());
+ if (!entry->param.isEmpty()) {
+ stream() << QStringLiteral("[%1]").arg(entry->paramMax + 1);
+ }
+ stream() << ";" << endl;
+ }
+ stream() << endl << " // items" << endl;
+
+ // Create Items.
+ for (auto *entry : parseResult.entries) {
+ const QString declType = entry->signalList.isEmpty()
+ ? QString(cfg().inherits + QStringLiteral("::Item") + itemType(entry->type))
+ : QStringLiteral("KConfigCompilerSignallingItem");
+
+ stream() << " " << declType << " *" << itemVar( entry, cfg() );
+ if (!entry->param.isEmpty()) {
+ stream() << QStringLiteral("[%1]").arg(entry->paramMax + 1);
+ }
+ stream() << ";" << endl;
+ }
+
+ if (parseResult.hasNonModifySignals) {
+ stream() << " uint " << varName(QStringLiteral("settingsChanged"), cfg()) << ";" << endl;
+ }
+
+ stream() << "};" << endl << endl;
+ endNamespaces();
+}
+
+void KConfigSourceGenerator::createSingletonImplementation()
+{
+ // Singleton implementation
+ if (!cfg().singleton) {
+ return;
+ }
+
+ beginNamespaces();
+ stream() << "class " << cfg().className << "Helper" << endl;
+ stream() << '{' << endl;
+ stream() << " public:" << endl;
+ stream() << " " << cfg().className << "Helper() : q(nullptr) {}" << endl;
+ stream() << " ~" << cfg().className << "Helper() { delete q; }" << endl;
+ stream() << " " << cfg().className << "Helper(const " << cfg().className << "Helper&) = delete;" << endl;
+ stream() << " " << cfg().className << "Helper& operator=(const " << cfg().className << "Helper&) = delete;" << endl;
+ stream() << " " << cfg().className << " *q;" << endl;
+ stream() << "};" << endl;
+ endNamespaces();
+
+ stream() << "Q_GLOBAL_STATIC(" << cfg().className << "Helper, s_global" << cfg().className << ")" << endl;
+
+ stream() << cfg().className << " *" << cfg().className << "::self()" << endl;
+ stream() << "{" << endl;
+ if (parseResult.cfgFileNameArg) {
+ stream() << " if (!s_global" << cfg().className << "()->q)" << endl;
+ stream() << " qFatal(\"you need to call " << cfg().className << "::instance before using\");" << endl;
+ } else {
+ stream() << " if (!s_global" << cfg().className << "()->q) {" << endl;
+ stream() << " new " << cfg().className << ';' << endl;
+ stream() << " s_global" << cfg().className << "()->q->read();" << endl;
+ stream() << " }" << endl << endl;
+ }
+ stream() << " return s_global" << cfg().className << "()->q;" << endl;
+ stream() << "}" << endl << endl;
+
+ if (parseResult.cfgFileNameArg) {
+ auto instance = [this] (const QString &type, const QString &arg, bool isString) {
+ stream() << "void " << cfg().className << "::instance(" << type << " " << arg << ")" << endl;
+ stream() << "{" << endl;
+ stream() << " if (s_global" << cfg().className << "()->q) {" << endl;
+ stream() << " qDebug() << \"" << cfg().className << "::instance called after the first use - ignoring\";" << endl;
+ stream() << " return;" << endl;
+ stream() << " }" << endl;
+ stream() << " new " << cfg().className << "(";
+ if (isString) {
+ stream() << "KSharedConfig::openConfig(" << arg << ")";
+ } else {
+ stream() << "std::move(" << arg << ")";
+ }
+ stream() << ");" << endl;
+ stream() << " s_global" << cfg().className << "()->q->read();" << endl;
+ stream() << "}" << endl << endl;
+ };
+ instance(QStringLiteral("const QString&"), QStringLiteral("cfgfilename"), true);
+ instance(QStringLiteral("KSharedConfig::Ptr"), QStringLiteral("config"), false);
+ }
+}
+
+void KConfigSourceGenerator::createPreamble()
+{
+ QString cppPreamble;
+ for (const auto entry : parseResult.entries) {
+ if (entry->paramValues.isEmpty()) {
+ continue;
+ }
+
+ cppPreamble += QStringLiteral("const char* const ") + cfg().className + QStringLiteral("::") + enumName(entry->param);
+ cppPreamble += cfg().globalEnums
+ ? QStringLiteral("ToString[] = { \"") + entry->paramValues.join(QStringLiteral("\", \"")) + QStringLiteral("\" };\n")
+ : QStringLiteral("::enumToString[] = { \"") + entry->paramValues.join(QStringLiteral("\", \"")) + QStringLiteral("\" };\n");
+ }
+
+ if (!cppPreamble.isEmpty()) {
+ stream() << cppPreamble << endl;
+ }
+}
+
+void KConfigSourceGenerator::createConstructorParameterList()
+{
+ if (parseResult.cfgFileNameArg) {
+ if (!cfg().forceStringFilename) {
+ stream() << " KSharedConfig::Ptr config";
+ } else {
+ stream() << " const QString& config";
+ }
+ stream() << (parseResult.parameters.isEmpty() ? "" : ",");
+ }
+
+ for (QList<Param>::ConstIterator it = parseResult.parameters.constBegin();
+ it != parseResult.parameters.constEnd(); ++it) {
+ if (it != parseResult.parameters.constBegin()) {
+ stream() << ",";
+ }
+ stream() << " " << param((*it).type) << " " << (*it).name;
+ }
+
+ if (cfg().parentInConstructor) {
+ if (parseResult.cfgFileNameArg || !parseResult.parameters.isEmpty()) {
+ stream() << ",";
+ }
+ stream() << " QObject *parent";
+ }
+
+}
+
+void KConfigSourceGenerator::createParentConstructorCall()
+{
+ stream() << cfg().inherits << "(";
+ if (!parseResult.cfgFileName.isEmpty()) {
+ stream() << " QStringLiteral( \"" << parseResult.cfgFileName << "\" ";
+ }
+ if (parseResult.cfgFileNameArg) {
+ if (! cfg().forceStringFilename) {
+ stream() << " std::move( config ) ";
+ } else {
+ stream() << " config ";
+ }
+ }
+ if (!parseResult.cfgFileName.isEmpty()) {
+ stream() << ") ";
+ }
+ stream() << ")" << endl;
+}
+
+void KConfigSourceGenerator::createInitializerList()
+{
+ for (const auto &parameter : parseResult.parameters) {
+ stream() << " , mParam" << parameter.name << "(" << parameter.name << ")" << endl;
+ }
+
+ if (parseResult.hasNonModifySignals && !cfg().dpointer) {
+ stream() << " , " << varName(QStringLiteral("settingsChanged"), cfg()) << "(0)" << endl;
+ }
+}
+
+void KConfigSourceGenerator::createEnums(const CfgEntry *entry)
+{
+ if (entry->type != QLatin1String("Enum")) {
+ return;
+ }
+ stream() << " QList<" << cfg().inherits << "::ItemEnum::Choice> values" << entry->name << ";" << endl;
+
+ for (const auto &choice : qAsConst(entry->choices.choices)) {
+ stream() << " {" << endl;
+ stream() << " " << cfg().inherits << "::ItemEnum::Choice choice;" << endl;
+ stream() << " choice.name = QStringLiteral(\"" << choice.name << "\");" << endl;
+ if (cfg().setUserTexts) {
+ if (!choice.label.isEmpty()) {
+ stream() << " choice.label = "
+ << translatedString(cfg(), choice.label, choice.context)
+ << ";" << endl;
+ }
+ if (!choice.toolTip.isEmpty()) {
+ stream() << " choice.toolTip = "
+ << translatedString(cfg(), choice.toolTip, choice.context)
+ << ";" << endl;
+ }
+ if (!choice.whatsThis.isEmpty()) {
+ stream() << " choice.whatsThis = "
+ << translatedString(cfg(), choice.whatsThis, choice.context)
+ << ";" << endl;
+ }
+ }
+ stream() << " values" << entry->name << ".append( choice );" << endl;
+ stream() << " }" << endl;
+ }
+}
+
+void KConfigSourceGenerator::createNormalEntry(const CfgEntry *entry, const QString &key)
+{
+ stream() << " " << itemPath(entry, cfg()) << " = "
+ << newItem(entry, key, entry->defaultValue, cfg()) << endl;
+
+ if (!entry->min.isEmpty()) {
+ stream() << " " << itemPath(entry, cfg()) << "->setMinValue(" << entry->min << ");" << endl;
+ }
+ if (!entry->max.isEmpty()) {
+ stream() << " " << itemPath(entry, cfg()) << "->setMaxValue(" << entry->max << ");" << endl;
+ }
+
+ if (cfg().setUserTexts) {
+ stream() << userTextsFunctions(entry, cfg());
+ }
+
+ if (cfg().allNotifiers || cfg().notifiers.contains(entry->name)) {
+ stream() << " " << itemPath(entry, cfg()) << "->setWriteFlags(KConfigBase::Notify);" << endl;
+ }
+
+ stream() << " addItem( " << itemPath(entry, cfg());
+ QString quotedName = entry->name;
+ addQuotes(quotedName);
+ if (quotedName != key) {
+ stream() << ", QStringLiteral( \"" << entry->name << "\" )";
+ }
+ stream() << " );" << endl;
+}
+
+void KConfigSourceGenerator::createIndexedEntry(const CfgEntry *entry, const QString &key)
+{
+ for (int i = 0; i <= entry->paramMax; i++) {
+ QString itemVarStr(itemPath(entry, cfg()) + QStringLiteral("[%1]").arg(i));
+
+ QString defaultStr = !entry->paramDefaultValues[i].isEmpty() ? entry->paramDefaultValues[i]
+ : !entry->defaultValue.isEmpty() ? paramString(entry->defaultValue, entry, i)
+ : defaultValue(entry->type);
+
+ stream() << " " << itemVarStr << " = "
+ << newItem(entry, paramString(key, entry, i), defaultStr, cfg(), QStringLiteral("[%1]").arg(i)) << endl;
+
+ if (cfg().setUserTexts) {
+ stream() << userTextsFunctions(entry, cfg(), itemVarStr, entry->paramName);
+ }
+
+ // Make mutators for enum parameters work by adding them with $(..) replaced by the
+ // param name. The check for isImmutable in the set* functions doesn't have the param
+ // name available, just the corresponding enum value (int), so we need to store the
+ // param names in a separate static list!.
+ const bool isEnum = entry->paramType == QLatin1String("Enum");
+ const QString arg = isEnum ? entry->paramValues[i] : QString::number(i);
+
+ QString paramName = entry->paramName;
+
+ stream() << " addItem( " << itemVarStr << ", QStringLiteral( \"";
+ stream() << paramName.replace(QStringLiteral("$(") + entry->param + QLatin1Char(')'), QLatin1String("%1")).arg( arg );
+ stream() << "\" ) );" << endl;
+ }
+}
+
+void KConfigSourceGenerator::handleCurrentGroupChange(const CfgEntry *entry)
+{
+ if (entry->group == mCurrentGroup) {
+ return;
+ }
+
+ // HACK: This fixes one spacing line in the diff. Remove this in the future and adapt the testcases.
+ static bool first = true;
+ if (!entry->group.isEmpty()) {
+ if (!first) {
+ stream() << endl;
+ }
+ first = false;
+ }
+
+ mCurrentGroup = entry->group;
+ stream() << " setCurrentGroup( " << paramString(mCurrentGroup, parseResult.parameters) << " );";
+ stream() << endl << endl;
+}
+
+void KConfigSourceGenerator::doConstructor()
+{
+ // Constructor
+ stream() << cfg().className << "::" << cfg().className << "(";
+ createConstructorParameterList();
+ stream() << " )" << endl;
+ stream() << " : ";
+ createParentConstructorCall();
+ createInitializerList();
+
+ stream() << "{" << endl;
+
+ if (cfg().parentInConstructor) {
+ stream() << " setParent(parent);" << endl;
+ }
+
+ if (cfg().dpointer) {
+ stream() << " d = new " << cfg().className << "Private;" << endl;
+ if (parseResult.hasNonModifySignals) {
+ stream() << " " << varPath(QStringLiteral("settingsChanged"), cfg()) << " = 0;" << endl;
+ }
+ }
+
+ // Needed in case the singleton class is used as baseclass for
+ // another singleton.
+ if (cfg().singleton) {
+ stream() << " Q_ASSERT(!s_global" << cfg().className << "()->q);" << endl;
+ stream() << " s_global" << cfg().className << "()->q = this;" << endl;
+ }
+
+ if (!parseResult.signalList.isEmpty()) {
+ // this cast to base-class pointer-to-member is valid C++
+ // https://stackoverflow.com/questions/4272909/is-it-safe-to-upcast-a-method-pointer-and-use-it-with-base-class-pointer/
+ stream() << " KConfigCompilerSignallingItem::NotifyFunction notifyFunction ="
+ << " static_cast<KConfigCompilerSignallingItem::NotifyFunction>(&"
+ << cfg().className << "::itemChanged);" << endl;
+
+ stream() << endl;
+ }
+
+ for (auto *entry : parseResult.entries) {
+ handleCurrentGroupChange(entry);
+
+ const QString key = paramString(entry->key, parseResult.parameters);
+ if (!entry->code.isEmpty()) {
+ stream() << entry->code << endl;
+ }
+ createEnums(entry);
+
+ if (!cfg().dpointer) {
+ stream() << itemDeclaration(entry, cfg());
+ }
+
+ if (entry->param.isEmpty()) {
+ createNormalEntry(entry, key);
+ } else {
+ createIndexedEntry(entry, key);
+ }
+ }
+
+ stream() << "}" << endl << endl;
+}
+
+void KConfigSourceGenerator::createGetterDPointerMode(const CfgEntry *entry)
+{
+ // Accessor
+ if (cfg().useEnumTypes && entry->type == QLatin1String("Enum")) {
+ stream() << enumType(entry, cfg().globalEnums);
+ } else {
+ stream() << cppType(entry->type);
+ }
+
+ stream() << " " << getFunction(entry->name, cfg().className) << "(";
+ if (!entry->param.isEmpty()) {
+ stream() << " " << cppType(entry->paramType) << " i ";
+ }
+ stream() << ")" << Const() << endl;
+
+ // function body inline only if not using dpointer
+ // for BC mode
+ startScope();
+ // HACK: Fix memberAccessorBody
+ stream() << " " << memberAccessorBody(entry, cfg().globalEnums);
+ endScope();
+ stream() << endl;
+}
+
+void KConfigSourceGenerator::createSetterDPointerMode(const CfgEntry *entry)
+{
+ // Manipulator
+ if (!(cfg().allMutators || cfg().mutators.contains(entry->name))) {
+ return;
+ }
+
+ stream() << "void " << setFunction(entry->name, cfg().className) << "( ";
+ if (!entry->param.isEmpty()) {
+ stream() << cppType(entry->paramType) << " i, ";
+ }
+
+ if (cfg().useEnumTypes && entry->type == QLatin1String("Enum")) {
+ stream() << enumType(entry, cfg().globalEnums);
+ } else {
+ stream() << param(entry->type);
+ }
+ stream() << " v )" << endl;
+
+ // function body inline only if not using dpointer
+ // for BC mode
+ startScope();
+ memberMutatorBody(entry);
+ endScope();
+ stream() << endl;
+}
+
+void KConfigSourceGenerator::createItemGetterDPointerMode(const CfgEntry *entry)
+{
+ // Item accessor
+ if (!cfg().itemAccessors) {
+ return;
+ }
+ stream() << endl;
+ stream() << cfg().inherits << "::Item" << itemType(entry->type) << " *"
+ << getFunction(entry->name, cfg().className) << "Item(";
+ if (!entry->param.isEmpty()) {
+ stream() << " " << cppType(entry->paramType) << " i ";
+ }
+ stream() << ")" << endl;
+ startScope();
+ stream() << " " << itemAccessorBody(entry, cfg());
+ endScope();
+}
+
+void KConfigSourceGenerator::doGetterSetterDPointerMode()
+{
+ if (!cfg().dpointer) {
+ return;
+ }
+
+ // setters and getters go in Cpp if in dpointer mode
+ for (auto *entry : parseResult.entries) {
+ createSetterDPointerMode(entry);
+ createGetterDPointerMode(entry);
+ createItemGetterDPointerMode(entry);
+ stream() << endl;
+ }
+}
+
+void KConfigSourceGenerator::createDefaultValueGetterSetter()
+{
+ // default value getters always go in Cpp
+ for (auto *entry : parseResult.entries) {
+ QString n = entry->name;
+ QString t = entry->type;
+
+ // Default value Accessor, as "helper" function
+ if ((cfg().allDefaultGetters || cfg().defaultGetters.contains(n)) && !entry->defaultValue.isEmpty()) {
+ stream() << cppType(t) << " " << getDefaultFunction(n, cfg().className) << "_helper(";
+ if (!entry->param.isEmpty()) {
+ stream() << " " << cppType(entry->paramType) << " i ";
+ }
+ stream() << ")" << Const() << endl;
+ startScope();
+ stream() << memberGetDefaultBody(entry) << endl;
+ endScope();
+ stream() << endl;
+ }
+ }
+}
+
+void KConfigSourceGenerator::createDestructor()
+{
+ stream() << cfg().className << "::~" << cfg().className << "()" << endl;
+ startScope();
+ if (cfg().dpointer) {
+ stream() << " delete d;" << endl;
+ }
+ if (cfg().singleton) {
+ stream() << " s_global" << cfg().className << "()->q = nullptr;" << endl;
+ }
+ endScope();
+ stream() << endl;
+}
+
+void KConfigSourceGenerator::createNonModifyingSignalsHelper()
+{
+ if (!parseResult.hasNonModifySignals) {
+ return;
+ }
+ stream() << "bool " << cfg().className << "::" << "usrSave()" << endl;
+ startScope();
+ stream() << " const bool res = " << cfg().inherits << "::usrSave();" << endl;
+ stream() << " if (!res) return false;" << endl << endl;
+ for (const Signal &signal : parseResult.signalList) {
+ if (signal.modify) {
+ continue;
+ }
+
+ stream() << " if ( " << varPath(QStringLiteral("settingsChanged"), cfg()) << " & " << signalEnumName(signal.name) << " )" << endl;
+ stream() << " Q_EMIT " << signal.name << "(";
+ QList<Param>::ConstIterator it, itEnd = signal.arguments.constEnd();
+ for (it = signal.arguments.constBegin(); it != itEnd;) {
+ Param argument = *it;
+ bool cast = false;
+ if (cfg().useEnumTypes && argument.type == QLatin1String("Enum")) {
+ for (int i = 0, end = parseResult.entries.count(); i < end; ++i) {
+ if (parseResult.entries.at(i)->name == argument.name) {
+ stream() << "static_cast<" << enumType(parseResult.entries.at(i), cfg().globalEnums) << ">(";
+ cast = true;
+ break;
+ }
+ }
+ }
+ stream() << varPath(argument.name, cfg());
+ if (cast) {
+ stream() << ")";
+ }
+ if (++it != itEnd) {
+ stream() << ", ";
+ }
+ }
+
+ stream() << ");" << endl;
+ }
+
+ stream() << " " << varPath(QStringLiteral("settingsChanged"), cfg()) << " = 0;" << endl;
+ stream() << " return true;" << endl;
+ endScope();
+}
+
+void KConfigSourceGenerator::createSignalFlagsHandler()
+{
+ if (parseResult.signalList.isEmpty()) {
+ return;
+ }
+
+ stream() << endl;
+ stream() << "void " << cfg().className << "::" << "itemChanged(quint64 flags) {" << endl;
+ if (parseResult.hasNonModifySignals)
+ stream() << " " << varPath(QStringLiteral("settingsChanged"), cfg()) << " |= flags;" << endl;
+
+ if (!parseResult.signalList.isEmpty())
+ stream() << endl;
+
+ for (const Signal &signal : parseResult.signalList) {
+ if (signal.modify) {
+ stream() << " if ( flags & " << signalEnumName(signal.name) << " ) {" << endl;
+ stream() << " Q_EMIT " << signal.name << "();" << endl;
+ stream() << " }" << endl;
+ }
+ }
+
+ stream() << "}" << endl;
+}
+
+void KConfigSourceGenerator::includeMoc() {
+ const QString mocFileName = cfg().baseName + QStringLiteral(".moc");
+
+ if (parseResult.signalList.count() || cfg().generateProperties) {
+ // Add includemoc if they are signals defined.
+ stream() << endl;
+ stream() << "#include \"" << mocFileName << "\"" << endl;
+ stream() << endl;
+ }
+}