diff --git a/autotests/kconfig_compiler/test4.cpp.ref b/autotests/kconfig_compiler/test4.cpp.ref --- a/autotests/kconfig_compiler/test4.cpp.ref +++ b/autotests/kconfig_compiler/test4.cpp.ref @@ -59,6 +59,7 @@ { KConfigSkeleton::ItemEnum::Choice choice; choice.name = QStringLiteral("CrashNBurn"); + choice.val = QStringLiteral("Crash and Burn"); valuesMouseAction.append( choice ); } { diff --git a/autotests/kconfig_compiler/test4.kcfg b/autotests/kconfig_compiler/test4.kcfg --- a/autotests/kconfig_compiler/test4.kcfg +++ b/autotests/kconfig_compiler/test4.kcfg @@ -24,7 +24,7 @@ - + Decrypt diff --git a/src/core/kcoreconfigskeleton.h b/src/core/kcoreconfigskeleton.h --- a/src/core/kcoreconfigskeleton.h +++ b/src/core/kcoreconfigskeleton.h @@ -761,6 +761,12 @@ QString label; QString toolTip; QString whatsThis; + QString val; + + public: + QString value() const { + return val.isEmpty() ? name : val; + } }; /** @copydoc KConfigSkeletonGenericItem::KConfigSkeletonGenericItem diff --git a/src/core/kcoreconfigskeleton.cpp b/src/core/kcoreconfigskeleton.cpp --- a/src/core/kcoreconfigskeleton.cpp +++ b/src/core/kcoreconfigskeleton.cpp @@ -594,7 +594,7 @@ QString tmp = cg.readEntry(mKey, QString()).toLower(); for (QList::ConstIterator it = mChoices.constBegin(); it != mChoices.constEnd(); ++it, ++i) { - if ((*it).name.toLower() == tmp) { + if ((*it).value().toLower() == tmp) { mReference = i; break; } @@ -615,7 +615,7 @@ if ((mDefault == mReference) && !cg.hasDefault(mKey)) { cg.revertToDefault(mKey, writeFlags()); } else if ((mReference >= 0) && (mReference < mChoices.count())) { - cg.writeEntry(mKey, mChoices[mReference].name, writeFlags()); + cg.writeEntry(mKey, mChoices[mReference].value(), writeFlags()); } else { cg.writeEntry(mKey, mReference, writeFlags()); } diff --git a/src/kconfig_compiler/KConfigCommonStructs.h b/src/kconfig_compiler/KConfigCommonStructs.h --- a/src/kconfig_compiler/KConfigCommonStructs.h +++ b/src/kconfig_compiler/KConfigCommonStructs.h @@ -55,6 +55,12 @@ QString label; QString toolTip; QString whatsThis; + QString val; + + public: + QString value() const{ + return val.isEmpty() ? name : val; + } }; class Choices { diff --git a/src/kconfig_compiler/KConfigSourceGenerator.cpp b/src/kconfig_compiler/KConfigSourceGenerator.cpp --- a/src/kconfig_compiler/KConfigSourceGenerator.cpp +++ b/src/kconfig_compiler/KConfigSourceGenerator.cpp @@ -289,6 +289,9 @@ stream() << " {\n"; stream() << " " << cfg().inherits << "::ItemEnum::Choice choice;\n"; stream() << " choice.name = QStringLiteral(\"" << choice.name << "\");\n"; + if (!choice.val.isEmpty()) { + stream() << " choice.val = QStringLiteral(\"" << choice.val << "\");\n"; + } if (cfg().setUserTexts) { if (!choice.label.isEmpty()) { stream() << " choice.label = " diff --git a/src/kconfig_compiler/KConfigXmlParser.cpp b/src/kconfig_compiler/KConfigXmlParser.cpp --- a/src/kconfig_compiler/KConfigXmlParser.cpp +++ b/src/kconfig_compiler/KConfigXmlParser.cpp @@ -176,6 +176,7 @@ bool KConfigXmlParser::hasDefaultCode(CfgEntry &readEntry, const QDomElement &element) { + Q_UNUSED(readEntry) for (QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { if (e.attribute(QStringLiteral("param")).isEmpty()) { if (e.attribute(QStringLiteral("code")) == QLatin1String("true")) { @@ -199,6 +200,10 @@ if (choice.name.isEmpty()) { std::cerr << "Tag requires attribute 'name'." << std::endl; } + else if (choice.name.contains(QLatin1Char(' '))) { + std::cerr << "Tag attribute 'name' cannot contain a space. You can use attribute 'value' to pass any string as the choice value." << std::endl; + } + choice.val = e2.attribute(QStringLiteral("value")); for (QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement()) { if (e3.tagName() == QLatin1String("label")) { choice.label = e3.text(); diff --git a/src/kconfig_compiler/README.dox b/src/kconfig_compiler/README.dox --- a/src/kconfig_compiler/README.dox +++ b/src/kconfig_compiler/README.dox @@ -354,7 +354,7 @@ - + \endverbatim @@ -369,6 +369,9 @@ }; \endverbatim +Since 5.68, if present the value attribute will be used used as the choice value written to the backend +instead of the name, allowing to write text incompatible with enum naming. + Alternatively, if GlobalEnums is set to true, all Enum items are defined as unnamed enums in the global scope of the generated class. In this case, all Enum values must have different names to avoid clashes. However, you can use a 'prefix' argument @@ -380,7 +383,7 @@ - + \endverbatim diff --git a/src/kconfig_compiler/kcfg.xsd b/src/kconfig_compiler/kcfg.xsd --- a/src/kconfig_compiler/kcfg.xsd +++ b/src/kconfig_compiler/kcfg.xsd @@ -93,6 +93,7 @@ +