diff options
-rw-r--r-- | autotests/kconfig_compiler/CMakeLists.txt | 11 | ||||
-rw-r--r-- | autotests/kconfig_compiler/kconfigcompiler_test.cpp | 2 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test13.cpp.ref | 34 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test13.h.ref | 70 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test13.kcfg | 11 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test13.kcfgc | 3 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test13main.cpp | 28 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test_signal.cpp.ref | 11 | ||||
-rw-r--r-- | autotests/kconfig_compiler/test_signal.h.ref | 18 | ||||
-rw-r--r-- | src/kconfig_compiler/kconfig_compiler.cpp | 162 |
10 files changed, 289 insertions, 61 deletions
diff --git a/autotests/kconfig_compiler/CMakeLists.txt b/autotests/kconfig_compiler/CMakeLists.txt index 0cca6052..5aa960ae 100644 --- a/autotests/kconfig_compiler/CMakeLists.txt +++ b/autotests/kconfig_compiler/CMakeLists.txt @@ -192,6 +192,17 @@ target_link_libraries(test12 KF5::ConfigGui) ########### next target ############### +set(test13_SRCS test13main.cpp ) + +gen_kcfg_test_source(test13 test13_SRCS) + +add_executable(test13 ${test13_SRCS}) +ecm_mark_as_test(test13) +target_link_libraries(test13 KF5::ConfigGui) + + +########### next target ############### + set(test_dpointer_SRCS test_dpointer_main.cpp ) gen_kcfg_test_source(test_dpointer test_dpointer_SRCS) diff --git a/autotests/kconfig_compiler/kconfigcompiler_test.cpp b/autotests/kconfig_compiler/kconfigcompiler_test.cpp index 43623cef..aaf2d025 100644 --- a/autotests/kconfig_compiler/kconfigcompiler_test.cpp +++ b/autotests/kconfig_compiler/kconfigcompiler_test.cpp @@ -43,6 +43,7 @@ static CompilerTestSet testCases = { "test11.h", "test11.cpp", "test11a.h", "test11a.cpp", "test12.h", "test12.cpp", + "test13.h", "test13.cpp", "test_dpointer.cpp", "test_dpointer.h", "test_signal.cpp", "test_signal.h", "test_qdebugcategory.cpp", "test_qdebugcategory.h", @@ -63,6 +64,7 @@ static CompilerTestSet testCasesToRun = { "test10", "test11", "test12", + "test13", "test_dpointer", "test_signal", "test_qdebugcategory", diff --git a/autotests/kconfig_compiler/test13.cpp.ref b/autotests/kconfig_compiler/test13.cpp.ref new file mode 100644 index 00000000..4eac1034 --- /dev/null +++ b/autotests/kconfig_compiler/test13.cpp.ref @@ -0,0 +1,34 @@ +// This file is generated by kconfig_compiler_kf5 from test13.kcfg. +// All changes you do to this file will be lost. + +#include "test13.h" + +Test13::Test13( ) + : KConfigSkeleton( QLatin1String( "muondatasourcesrc" ) ) +{ + KConfigCompilerSignallingItem::NotifyFunction notifyFunction = static_cast<KConfigCompilerSignallingItem::NotifyFunction>(&Test13::itemChanged); + + setCurrentGroup( QLatin1String( "kamoso" ) ); + + KConfigSkeleton::ItemUrl *itemPicturesDir; + itemPicturesDir = new KConfigSkeleton::ItemUrl( currentGroup(), QLatin1String( "picturesDir" ), mPicturesDir ); + addItem( itemPicturesDir, QLatin1String( "picturesDir" ) ); + KConfigCompilerSignallingItem *itemBrightness; + itemBrightness = new KConfigCompilerSignallingItem(new KConfigSkeleton::ItemDouble( currentGroup(), QLatin1String( "brightness" ), mBrightness ), this, notifyFunction, signalBrightnessChanged); + addItem( itemBrightness, QLatin1String( "brightness" ) ); +} + +Test13::~Test13() +{ +} + + +void Test13::itemChanged(quint64 flags) { + + if ( flags & signalBrightnessChanged ) { + Q_EMIT brightnessChanged(); + } +} + +#include "test13.moc" + diff --git a/autotests/kconfig_compiler/test13.h.ref b/autotests/kconfig_compiler/test13.h.ref new file mode 100644 index 00000000..0636ad2f --- /dev/null +++ b/autotests/kconfig_compiler/test13.h.ref @@ -0,0 +1,70 @@ +// This file is generated by kconfig_compiler_kf5 from test13.kcfg. +// All changes you do to this file will be lost. +#ifndef TEST13_H +#define TEST13_H + +#include <qglobal.h> +#include <kconfigskeleton.h> +#include <QCoreApplication> +#include <QDebug> + +class Test13 : public KConfigSkeleton +{ + Q_OBJECT + public: + + Test13( ); + ~Test13(); + + + Q_PROPERTY(QUrl picturesDir READ picturesDir CONSTANT) + /** + Get picturesDir + */ + QUrl picturesDir() const + { + return mPicturesDir; + } + + /** + Set brightness + */ + void setBrightness( double v ) + { + if (v != mBrightness && !isImmutable( QString::fromLatin1( "brightness" ) )) { + mBrightness = v; + Q_EMIT brightnessChanged(); + } + } + + Q_PROPERTY(double brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged) + /** + Get brightness + */ + double brightness() const + { + return mBrightness; + } + + + enum { + signalBrightnessChanged = 0x1 + }; + + Q_SIGNALS: + void brightnessChanged(); + + private: + void itemChanged(quint64 flags); + + protected: + + // kamoso + QUrl mPicturesDir; + double mBrightness; + + private: +}; + +#endif + diff --git a/autotests/kconfig_compiler/test13.kcfg b/autotests/kconfig_compiler/test13.kcfg new file mode 100644 index 00000000..c4d36350 --- /dev/null +++ b/autotests/kconfig_compiler/test13.kcfg @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + <kcfgfile name="muondatasourcesrc"/> + <group name="kamoso"> + <entry name="picturesDir" type="Url" /> + <entry name="brightness" type="double" /> + </group> +</kcfg> diff --git a/autotests/kconfig_compiler/test13.kcfgc b/autotests/kconfig_compiler/test13.kcfgc new file mode 100644 index 00000000..340b8cae --- /dev/null +++ b/autotests/kconfig_compiler/test13.kcfgc @@ -0,0 +1,3 @@ +ClassName=Test13 +GenerateProperties=true +Mutators=brightness diff --git a/autotests/kconfig_compiler/test13main.cpp b/autotests/kconfig_compiler/test13main.cpp new file mode 100644 index 00000000..e732c17c --- /dev/null +++ b/autotests/kconfig_compiler/test13main.cpp @@ -0,0 +1,28 @@ +/* +Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#include "test13.h" + +int main(int, char **) +{ + Test13 *t = new Test13(); + delete t; + return 0; +} diff --git a/autotests/kconfig_compiler/test_signal.cpp.ref b/autotests/kconfig_compiler/test_signal.cpp.ref index 58e73efd..6faf8bd1 100644 --- a/autotests/kconfig_compiler/test_signal.cpp.ref +++ b/autotests/kconfig_compiler/test_signal.cpp.ref @@ -61,18 +61,17 @@ bool TestSignal::usrWriteConfig() const bool res = KConfigSkeleton::usrWriteConfig(); if (!res) return false; - if ( mSettingsChanged & signalEmoticonSettingsChanged ) - emit emoticonSettingsChanged(); - - if ( mSettingsChanged & signalStyleChanged ) - emit styleChanged(mStylePath, mStyleCSSVariant); - + if ( mSettingsChanged & signalEmoticonSettingsChanged ) + Q_EMIT emoticonSettingsChanged(); + if ( mSettingsChanged & signalStyleChanged ) + Q_EMIT styleChanged(mStylePath, mStyleCSSVariant); mSettingsChanged = 0; return true; } void TestSignal::itemChanged(quint64 flags) { mSettingsChanged |= flags; + } #include "test_signal.moc" diff --git a/autotests/kconfig_compiler/test_signal.h.ref b/autotests/kconfig_compiler/test_signal.h.ref index 19b8b400..e9f9c94c 100644 --- a/autotests/kconfig_compiler/test_signal.h.ref +++ b/autotests/kconfig_compiler/test_signal.h.ref @@ -12,11 +12,6 @@ class TestSignal : public KConfigSkeleton Q_OBJECT public: - enum { - signalEmoticonSettingsChanged = 0x1, - signalStyleChanged = 0x2 - }; - static TestSignal *self(); ~TestSignal(); @@ -26,7 +21,7 @@ class TestSignal : public KConfigSkeleton static void setEmoticonTheme( const QString & v ) { - if (!self()->isImmutable( QString::fromLatin1( "emoticonTheme" ) )) { + if (v != self()->mEmoticonTheme && !self()->isImmutable( QString::fromLatin1( "emoticonTheme" ) )) { self()->mEmoticonTheme = v; self()->mSettingsChanged |= signalEmoticonSettingsChanged; } @@ -47,7 +42,7 @@ class TestSignal : public KConfigSkeleton static void setUseEmoticon( bool v ) { - if (!self()->isImmutable( QString::fromLatin1( "useEmoticon" ) )) { + if (v != self()->mUseEmoticon && !self()->isImmutable( QString::fromLatin1( "useEmoticon" ) )) { self()->mUseEmoticon = v; self()->mSettingsChanged |= signalEmoticonSettingsChanged; } @@ -68,7 +63,7 @@ class TestSignal : public KConfigSkeleton static void setEmoticonRequireSpace( bool v ) { - if (!self()->isImmutable( QString::fromLatin1( "emoticonRequireSpace" ) )) { + if (v != self()->mEmoticonRequireSpace && !self()->isImmutable( QString::fromLatin1( "emoticonRequireSpace" ) )) { self()->mEmoticonRequireSpace = v; self()->mSettingsChanged |= signalEmoticonSettingsChanged; } @@ -89,7 +84,7 @@ class TestSignal : public KConfigSkeleton static void setStylePath( const QString & v ) { - if (!self()->isImmutable( QString::fromLatin1( "stylePath" ) )) { + if (v != self()->mStylePath && !self()->isImmutable( QString::fromLatin1( "stylePath" ) )) { self()->mStylePath = v; self()->mSettingsChanged |= signalStyleChanged; } @@ -124,6 +119,11 @@ class TestSignal : public KConfigSkeleton } + enum { + signalEmoticonSettingsChanged = 0x1, + signalStyleChanged = 0x2 + }; + Q_SIGNALS: void emoticonSettingsChanged(); diff --git a/src/kconfig_compiler/kconfig_compiler.cpp b/src/kconfig_compiler/kconfig_compiler.cpp index 5aae3404..7160bb57 100644 --- a/src/kconfig_compiler/kconfig_compiler.cpp +++ b/src/kconfig_compiler/kconfig_compiler.cpp @@ -97,6 +97,7 @@ public: globalEnums = codegenConfig.value("GlobalEnums", false).toBool(); useEnumTypes = codegenConfig.value("UseEnumTypes", false).toBool(); const QString trString = codegenConfig.value("TranslationSystem").toString().toLower(); + generateProperties = codegenConfig.value("GenerateProperties", false).toBool(); if (trString == "kde") { translationSystem = KdeTranslation; } else { @@ -137,6 +138,7 @@ public: bool useEnumTypes; bool itemAccessors; TranslationSystem translationSystem; + bool generateProperties; }; struct SignalArguments { @@ -147,9 +149,12 @@ struct SignalArguments { class Signal { public: + Signal() : modify(false) {} + QString name; QString label; QList<SignalArguments> arguments; + bool modify; }; class CfgEntry @@ -549,6 +554,11 @@ static QString setFunction(const QString &n, const QString &className = QString( return result; } +static QString changeSignalName(const QString &n) +{ + return n+QStringLiteral("Changed"); +} + static QString getDefaultFunction(const QString &n, const QString &className = QString()) { QString result = QString::fromLatin1("default") + n + QString::fromLatin1("Value"); @@ -844,6 +854,13 @@ CfgEntry *parseEntry(const QString &group, const QDomElement &element, const Cfg } } + if (cfg.generateProperties && (cfg.allMutators || cfg.mutators.contains(name))) { + Signal s; + s.name = changeSignalName(name); + s.modify = true; + signalList.append(s); + } + bool nameIsEmpty = name.isEmpty(); if (nameIsEmpty && key.isEmpty()) { cerr << "Entry must have a name or a key: " << dumpNode(element) << endl; @@ -1404,7 +1421,14 @@ QString memberMutatorBody(CfgEntry *e, const CfgConfig &cfg) out << "}" << endl << endl; } - out << "if (!" << This << "isImmutable( QString::fromLatin1( \""; + const QString varExpression = This + varPath(n, cfg) + (e->param().isEmpty() ? QString() : "[i]"); + + const bool hasBody = !e->signalList().empty() || cfg.generateProperties; + out << "if ("; + if (hasBody) { + out << "v != " << varExpression << " && "; + } + out << "!" << This << "isImmutable( QString::fromLatin1( \""; if (!e->param().isEmpty()) { out << e->paramName().replace("$(" + e->param() + ")", "%1") << "\" ).arg( "; if (e->paramType() == "Enum") { @@ -1424,17 +1448,17 @@ QString memberMutatorBody(CfgEntry *e, const CfgConfig &cfg) } else { out << n << "\" )"; } - out << " ))" << (!e->signalList().empty() ? " {" : "") << endl; - out << " " << This << varPath(n, cfg); - if (!e->param().isEmpty()) { - out << "[i]"; - } - out << " = v;" << endl; + out << " ))" << (hasBody ? " {" : "") << endl; + out << " " << varExpression << " = v;" << endl; - if (!e->signalList().empty()) { - Q_FOREACH (const Signal &signal, e->signalList()) { + Q_FOREACH (const Signal &signal, e->signalList()) { + if (signal.modify) { + out << " Q_EMIT " << This << signal.name << "();" << endl; + } else { out << " " << This << varPath("settingsChanged", cfg) << " |= " << signalEnumName(signal.name) << ";" << endl; } + } + if (hasBody) { out << "}" << endl; } @@ -1619,7 +1643,6 @@ int main(int argc, char **argv) QList<Param> parameters; QList<Signal> signalList; QStringList includes; - bool hasSignals = false; QList<CfgEntry *> entries; @@ -1718,7 +1741,6 @@ int main(int argc, char **argv) } #endif - hasSignals = !signalList.empty(); QString headerFileName = baseName + ".h"; QString implementationFileName = baseName + ".cpp"; QString mocFileName = baseName + ".moc"; @@ -1788,7 +1810,7 @@ int main(int argc, char **argv) h << "{" << endl; // Add Q_OBJECT macro if the config need signals. - if (hasSignals) { + if (!signalList.isEmpty() || cfg.generateProperties) { h << " Q_OBJECT" << endl; } h << " public:" << endl; @@ -1842,25 +1864,9 @@ int main(int argc, char **argv) } } } - if (hasSignals) { - h << "\n enum {" << endl; - unsigned val = 1; - QList<Signal>::ConstIterator it, itEnd = signalList.constEnd(); - for (it = signalList.constBegin(); it != itEnd; val <<= 1) { - if (!val) { - cerr << "Too many signals to create unique bit masks" << endl; - exit(1); - } - Signal signal = *it; - h << " " << signalEnumName(signal.name) << " = 0x" << hex << val; - if (++it != itEnd) { - h << ","; - } - h << endl; - } - h << " };" << dec << endl; - } h << endl; + + // Constructor or singleton accessor if (!cfg.singleton) { h << " " << cfg.className << "("; @@ -1930,6 +1936,33 @@ int main(int argc, char **argv) } } h << endl; + + QString returnType; + if (cfg.useEnumTypes && t == "Enum") { + returnType = enumType(*itEntry, cfg.globalEnums); + } else { + returnType = cppType(t); + } + + if (cfg.generateProperties) { + h << " Q_PROPERTY(" << returnType << ' ' << n; + h << " READ " << n; + if (cfg.allMutators || cfg.mutators.contains(n)) { + const QString signal = changeSignalName(n); + h << " WRITE " << setFunction(n); + h << " NOTIFY " << signal; + + //If we have the modified signal, we'll also need + //the changed signal as well + Signal s; + s.name = signal; + s.modify = true; + signalList.append(s); + } else { + h << " CONSTANT"; + } + h << ")" << endl; + } // Accessor h << " /**" << endl; h << " Get " << (*itEntry)->label() << endl; @@ -1938,11 +1971,7 @@ int main(int argc, char **argv) h << " static" << endl; } h << " "; - if (cfg.useEnumTypes && t == "Enum") { - h << enumType(*itEntry, cfg.globalEnums); - } else { - h << cppType(t); - } + h << returnType; h << " " << getFunction(n) << "("; if (!(*itEntry)->param().isEmpty()) { h << " " << cppType((*itEntry)->paramType()) << " i "; @@ -2021,8 +2050,27 @@ int main(int argc, char **argv) } // Signal definition. + const bool hasSignals = !signalList.isEmpty(); + bool hasNonModifySignals = false; if (hasSignals) { - h << endl; + h << "\n enum {" << endl; + unsigned val = 1; + QList<Signal>::ConstIterator it, itEnd = signalList.constEnd(); + for (it = signalList.constBegin(); it != itEnd; val <<= 1) { + hasNonModifySignals |= !it->modify; + if (!val) { + cerr << "Too many signals to create unique bit masks" << endl; + exit(1); + } + Signal signal = *it; + h << " " << signalEnumName(signal.name) << " = 0x" << hex << val; + if (++it != itEnd) { + h << ","; + } + h << endl; + } + h << " };" << dec << endl << endl; + h << " Q_SIGNALS:"; Q_FOREACH (const Signal &signal, signalList) { h << endl; @@ -2070,7 +2118,7 @@ int main(int argc, char **argv) h << " friend class " << cfg.className << "Helper;" << endl << endl; } - if (hasSignals) { + if (hasNonModifySignals) { h << " virtual bool usrWriteConfig();" << endl; } @@ -2122,7 +2170,7 @@ int main(int argc, char **argv) h << ";" << endl; } } - if (hasSignals) { + if (hasNonModifySignals) { h << " uint " << varName("settingsChanged", cfg) << ";" << endl; } @@ -2231,7 +2279,7 @@ int main(int argc, char **argv) } cpp << ";" << endl; } - if (hasSignals) { + if (hasNonModifySignals) { cpp << " uint " << varName("settingsChanged", cfg) << ";" << endl; } @@ -2321,7 +2369,7 @@ int main(int argc, char **argv) cpp << " , mParam" << (*it).name << "(" << (*it).name << ")" << endl; } - if (hasSignals && !cfg.dpointer) { + if (hasNonModifySignals && !cfg.dpointer) { cpp << " , " << varName("settingsChanged", cfg) << "(0)" << endl; } @@ -2329,7 +2377,7 @@ int main(int argc, char **argv) if (cfg.dpointer) { cpp << " d = new " + cfg.className + "Private;" << endl; - if (hasSignals) { + if (hasNonModifySignals) { cpp << " " << varPath("settingsChanged", cfg) << " = 0;" << endl; } } @@ -2550,14 +2598,18 @@ int main(int argc, char **argv) } cpp << "}" << endl << endl; - if (hasSignals) { + if (hasNonModifySignals) { cpp << "bool " << cfg.className << "::" << "usrWriteConfig()" << endl; cpp << "{" << endl; cpp << " const bool res = " << cfg.inherits << "::usrWriteConfig();" << endl; cpp << " if (!res) return false;" << endl << endl; Q_FOREACH (const Signal &signal, signalList) { - cpp << " if ( " << varPath("settingsChanged", cfg) << " & " << signalEnumName(signal.name) << " ) " << endl; - cpp << " emit " << signal.name << "("; + if (signal.modify) { + continue; + } + + cpp << " if ( " << varPath("settingsChanged", cfg) << " & " << signalEnumName(signal.name) << " )" << endl; + cpp << " Q_EMIT " << signal.name << "("; QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); for (it = signal.arguments.constBegin(); it != itEnd;) { SignalArguments argument = *it; @@ -2579,17 +2631,35 @@ int main(int argc, char **argv) cpp << ", "; } } - cpp << ");" << endl << endl; + cpp << ");" << endl; } + cpp << " " << varPath("settingsChanged", cfg) << " = 0;" << endl; cpp << " return true;" << endl; cpp << "}" << endl; + } + if (hasSignals) { cpp << endl; cpp << "void " << cfg.className << "::" << "itemChanged(quint64 flags) {" << endl; - cpp << " " << varPath("settingsChanged", cfg) << " |= flags;" << endl; + if (hasNonModifySignals) + cpp << " " << varPath("settingsChanged", cfg) << " |= flags;" << endl; + + if (!signalList.isEmpty()) + cpp << endl; + + Q_FOREACH (const Signal &signal, signalList) { + if (signal.modify) { + cpp << " if ( flags & " << signalEnumName(signal.name) << " ) {" << endl; + cpp << " Q_EMIT " << signal.name << "();" << endl; + cpp << " }" << endl; + } + } + cpp << "}" << endl; + } + if (hasSignals || cfg.generateProperties) { // Add includemoc if they are signals defined. cpp << endl; cpp << "#include \"" << mocFileName << "\"" << endl; |