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; | 
