aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autotests/kconfig_compiler/test4.cpp.ref3
-rw-r--r--autotests/kconfig_compiler/test4.kcfg2
-rw-r--r--autotests/kconfig_compiler/test5.cpp.ref3
-rw-r--r--autotests/kconfig_compiler/test5.kcfg2
-rw-r--r--src/core/kcoreconfigskeleton.cpp18
-rw-r--r--src/core/kcoreconfigskeleton.h11
-rw-r--r--src/core/kcoreconfigskeleton_p.h1
-rw-r--r--src/kconfig_compiler/KConfigCommonStructs.h6
-rw-r--r--src/kconfig_compiler/KConfigSourceGenerator.cpp19
-rw-r--r--src/kconfig_compiler/KConfigXmlParser.cpp7
-rw-r--r--src/kconfig_compiler/README.dox7
-rw-r--r--src/kconfig_compiler/kcfg.xsd1
12 files changed, 70 insertions, 10 deletions
diff --git a/autotests/kconfig_compiler/test4.cpp.ref b/autotests/kconfig_compiler/test4.cpp.ref
index e99a1ae9..fb4db2ff 100644
--- a/autotests/kconfig_compiler/test4.cpp.ref
+++ b/autotests/kconfig_compiler/test4.cpp.ref
@@ -68,10 +68,13 @@ QColor defaultColor[4] = { Qt::red, Qt::blue, Qt::green, Qt::black };
}
KConfigSkeleton::ItemEnum *itemMouseAction[3];
itemMouseAction[0] = new KConfigSkeleton::ItemEnum( currentGroup(), QStringLiteral( "right_mouse_action" ), mMouseAction[0], valuesMouseAction, EnumMouseAction::Decrypt );
+ itemMouseAction[0]->setValueForChoice(QStringLiteral( "CrashNBurn" ), QStringLiteral( "Crash and Burn" ));
addItem( itemMouseAction[0], QStringLiteral( "MouseActionright" ) );
itemMouseAction[1] = new KConfigSkeleton::ItemEnum( currentGroup(), QStringLiteral( "mid_mouse_action" ), mMouseAction[1], valuesMouseAction, EnumMouseAction::Encrypt );
+ itemMouseAction[1]->setValueForChoice(QStringLiteral( "CrashNBurn" ), QStringLiteral( "Crash and Burn" ));
addItem( itemMouseAction[1], QStringLiteral( "MouseActionmid" ) );
itemMouseAction[2] = new KConfigSkeleton::ItemEnum( currentGroup(), QStringLiteral( "left_mouse_action" ), mMouseAction[2], valuesMouseAction, EnumMouseAction::PumpNDump );
+ itemMouseAction[2]->setValueForChoice(QStringLiteral( "CrashNBurn" ), QStringLiteral( "Crash and Burn" ));
addItem( itemMouseAction[2], QStringLiteral( "MouseActionleft" ) );
KConfigSkeleton::ItemColor *itemGrayColor[11];
itemGrayColor[0] = new KConfigSkeleton::ItemColor( currentGroup(), QStringLiteral( "gray color #0" ), mGrayColor[0],
diff --git a/autotests/kconfig_compiler/test4.kcfg b/autotests/kconfig_compiler/test4.kcfg
index 0919b46f..4b40fdab 100644
--- a/autotests/kconfig_compiler/test4.kcfg
+++ b/autotests/kconfig_compiler/test4.kcfg
@@ -24,7 +24,7 @@
<choices>
<choice name="Encrypt"/>
<choice name="Decrypt"/>
- <choice name="CrashNBurn"/>
+ <choice name="CrashNBurn" value="Crash and Burn"/>
<choice name="PumpNDump"/>
</choices>
<default param="right">Decrypt</default>
diff --git a/autotests/kconfig_compiler/test5.cpp.ref b/autotests/kconfig_compiler/test5.cpp.ref
index 2ee3dbfd..2b50222c 100644
--- a/autotests/kconfig_compiler/test5.cpp.ref
+++ b/autotests/kconfig_compiler/test5.cpp.ref
@@ -69,10 +69,13 @@ QColor defaultColor[4] = { Qt::red, Qt::blue, Qt::green, Qt::black };
}
KConfigSkeleton::ItemEnum *itemMouseAction[3];
itemMouseAction[0] = new KConfigSkeleton::ItemEnum( currentGroup(), QStringLiteral( "right_mouse_action" ), mMouseAction[0], valuesMouseAction, Decrypt );
+ itemMouseAction[0]->setValueForChoice(QStringLiteral( "CrashNBurn" ), QStringLiteral( "Crash'n Burn" ));
addItem( itemMouseAction[0], QStringLiteral( "MouseActionright" ) );
itemMouseAction[1] = new KConfigSkeleton::ItemEnum( currentGroup(), QStringLiteral( "mid_mouse_action" ), mMouseAction[1], valuesMouseAction, Encrypt );
+ itemMouseAction[1]->setValueForChoice(QStringLiteral( "CrashNBurn" ), QStringLiteral( "Crash'n Burn" ));
addItem( itemMouseAction[1], QStringLiteral( "MouseActionmid" ) );
itemMouseAction[2] = new KConfigSkeleton::ItemEnum( currentGroup(), QStringLiteral( "left_mouse_action" ), mMouseAction[2], valuesMouseAction, PumpNDump );
+ itemMouseAction[2]->setValueForChoice(QStringLiteral( "CrashNBurn" ), QStringLiteral( "Crash'n Burn" ));
addItem( itemMouseAction[2], QStringLiteral( "MouseActionleft" ) );
KConfigSkeleton::ItemString *itemFooBar;
itemFooBar = new KConfigSkeleton::ItemString( currentGroup(), QStringLiteral( "foo bar" ), mFooBar );
diff --git a/autotests/kconfig_compiler/test5.kcfg b/autotests/kconfig_compiler/test5.kcfg
index d8ef2bfa..4b89450f 100644
--- a/autotests/kconfig_compiler/test5.kcfg
+++ b/autotests/kconfig_compiler/test5.kcfg
@@ -24,7 +24,7 @@
<choices>
<choice name="Encrypt"/>
<choice name="Decrypt"/>
- <choice name="CrashNBurn"/>
+ <choice name="CrashNBurn" value="Crash'n Burn"/>
<choice name="PumpNDump"/>
</choices>
<default param="right">Decrypt</default>
diff --git a/src/core/kcoreconfigskeleton.cpp b/src/core/kcoreconfigskeleton.cpp
index 5672a850..575ee721 100644
--- a/src/core/kcoreconfigskeleton.cpp
+++ b/src/core/kcoreconfigskeleton.cpp
@@ -590,6 +590,19 @@ void KCoreConfigSkeleton::ItemLongLong::setMaxValue(qint64 v)
mMax = v;
}
+QString KCoreConfigSkeleton::ItemEnum::valueForChoice(const QString &name) const
+{
+ // HACK for BC concerns
+ // TODO KF6: remove KConfigSkeletonItemPrivate::mValues and add a value field to KCoreConfigSkeleton::ItemEnum::Choice
+ const auto inHash = d_ptr->mValues.value(name);
+ return !inHash.isEmpty() ? inHash : name;
+}
+
+void KCoreConfigSkeleton::ItemEnum::setValueForChoice(const QString &name, const QString &value)
+{
+ d_ptr->mValues.insert(name, value);
+}
+
KCoreConfigSkeleton::ItemEnum::ItemEnum(const QString &_group, const QString &_key,
qint32 &reference,
const QList<Choice> &choices,
@@ -609,7 +622,8 @@ void KCoreConfigSkeleton::ItemEnum::readConfig(KConfig *config)
QString tmp = cg.readEntry(mKey, QString()).toLower();
for (QList<Choice>::ConstIterator it = mChoices.constBegin();
it != mChoices.constEnd(); ++it, ++i) {
- if ((*it).name.toLower() == tmp) {
+ QString choiceName = (*it).name;
+ if (valueForChoice(choiceName).toLower() == tmp) {
mReference = i;
break;
}
@@ -630,7 +644,7 @@ void KCoreConfigSkeleton::ItemEnum::writeConfig(KConfig *config)
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, valueForChoice(mChoices.at(mReference).name), writeFlags());
} else {
cg.writeEntry(mKey, mReference, writeFlags());
}
diff --git a/src/core/kcoreconfigskeleton.h b/src/core/kcoreconfigskeleton.h
index 02473fb4..9d84583e 100644
--- a/src/core/kcoreconfigskeleton.h
+++ b/src/core/kcoreconfigskeleton.h
@@ -802,9 +802,20 @@ public:
void writeConfig(KConfig *config) override;
// Source compatibility with 4.x
+ // TODO KF6 remove
typedef Choice Choice2;
QList<Choice> choices2() const;
+ /**
+ * Returns the value for for the choice with the given name
+ */
+ QString valueForChoice(const QString &name) const;
+
+ /**
+ * Stores a choice value for name
+ */
+ void setValueForChoice(const QString &name, const QString &valueForChoice);
+
private:
QList<Choice> mChoices;
};
diff --git a/src/core/kcoreconfigskeleton_p.h b/src/core/kcoreconfigskeleton_p.h
index 8ba64db7..fcc9bc13 100644
--- a/src/core/kcoreconfigskeleton_p.h
+++ b/src/core/kcoreconfigskeleton_p.h
@@ -62,6 +62,7 @@ public:
QString mToolTip; ///< The ToolTip text for this item
QString mWhatsThis; ///< The What's This text for this item
KConfigGroup mConfigGroup; ///< KConfigGroup, allow to read/write item in nested groups
+ QHash<QString, QString> mValues; /// The values used for ItemEnum's choices, name -> value (if set)
// HACK: Necessary to avoid introducing new virtuals in KConfigSkeletonItem
std::function<bool()> mIsDefaultImpl;
diff --git a/src/kconfig_compiler/KConfigCommonStructs.h b/src/kconfig_compiler/KConfigCommonStructs.h
index 06c8b80f..fef45a9f 100644
--- a/src/kconfig_compiler/KConfigCommonStructs.h
+++ b/src/kconfig_compiler/KConfigCommonStructs.h
@@ -55,6 +55,12 @@ public:
QString label;
QString toolTip;
QString whatsThis;
+ QString val;
+
+ QString value() const
+ {
+ return !val.isEmpty() ? val : name;
+ }
};
class Choices
{
diff --git a/src/kconfig_compiler/KConfigSourceGenerator.cpp b/src/kconfig_compiler/KConfigSourceGenerator.cpp
index 33e0ed69..3e8a8156 100644
--- a/src/kconfig_compiler/KConfigSourceGenerator.cpp
+++ b/src/kconfig_compiler/KConfigSourceGenerator.cpp
@@ -313,13 +313,14 @@ void KConfigSourceGenerator::createEnums(const CfgEntry *entry)
void KConfigSourceGenerator::createNormalEntry(const CfgEntry *entry, const QString &key)
{
+ const QString itemVarStr = itemPath(entry, cfg());
const QString innerItemVarStr = innerItemVar(entry, cfg());
if (!entry->signalList.isEmpty()) {
stream() << " " << innerItemVarStr << " = "
<< newInnerItem(entry, key, entry->defaultValue, cfg()) << '\n';
}
- stream() << " " << itemPath(entry, cfg()) << " = "
+ stream() << " " << itemVarStr << " = "
<< newItem(entry, key, entry->defaultValue, cfg()) << '\n';
if (!entry->min.isEmpty()) {
@@ -335,10 +336,16 @@ void KConfigSourceGenerator::createNormalEntry(const CfgEntry *entry, const QStr
}
if (cfg().allNotifiers || cfg().notifiers.contains(entry->name)) {
- stream() << " " << itemPath(entry, cfg()) << "->setWriteFlags(KConfigBase::Notify);\n";
+ stream() << " " << itemVarStr << "->setWriteFlags(KConfigBase::Notify);\n";
}
- stream() << " addItem( " << itemPath(entry, cfg());
+ for (const CfgEntry::Choice &choice : qAsConst(entry->choices.choices)) {
+ if (!choice.val.isEmpty()) {
+ stream() << " " << itemVarStr << "->setValueForChoice(QStringLiteral( \"" << choice.name << "\" ), QStringLiteral( \"" << choice.val << "\" ));\n";
+ }
+ }
+
+ stream() << " addItem( " << itemVarStr;
QString quotedName = entry->name;
addQuotes(quotedName);
if (quotedName != key) {
@@ -374,6 +381,12 @@ void KConfigSourceGenerator::createIndexedEntry(const CfgEntry *entry, const QSt
stream() << " " << innerItemVarStr << "->setMaxValue(" << entry->max << ");\n";
}
+ for (const CfgEntry::Choice &choice : qAsConst(entry->choices.choices)) {
+ if (!choice.val.isEmpty()) {
+ stream() << " " << itemVarStr << "->setValueForChoice(QStringLiteral( \"" << choice.name << "\" ), QStringLiteral( \"" << choice.val << "\" ));\n";
+ }
+ }
+
if (cfg().setUserTexts) {
stream() << userTextsFunctions(entry, cfg(), itemVarStr, entry->paramName);
}
diff --git a/src/kconfig_compiler/KConfigXmlParser.cpp b/src/kconfig_compiler/KConfigXmlParser.cpp
index 2f31beb9..045018de 100644
--- a/src/kconfig_compiler/KConfigXmlParser.cpp
+++ b/src/kconfig_compiler/KConfigXmlParser.cpp
@@ -176,6 +176,7 @@ void KConfigXmlParser::readParameterFromEntry(CfgEntry &readEntry, const QDomEle
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")) {
@@ -186,10 +187,11 @@ bool KConfigXmlParser::hasDefaultCode(CfgEntry &readEntry, const QDomElement &el
return false;
}
-
void KConfigXmlParser::readChoicesFromEntry(CfgEntry &readEntry, const QDomElement &e)
{
QList<CfgEntry::Choice> chlist;
+ const auto choiceNameRegex = QRegularExpression(QStringLiteral("\\w+"));
+
for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) {
if (e2.tagName() != QLatin1String("choice")) {
continue;
@@ -198,7 +200,10 @@ void KConfigXmlParser::readChoicesFromEntry(CfgEntry &readEntry, const QDomEleme
choice.name = e2.attribute(QStringLiteral("name"));
if (choice.name.isEmpty()) {
std::cerr << "Tag <choice> requires attribute 'name'." << std::endl;
+ } else if (!choiceNameRegex.match(choice.name).hasMatch()) {
+ std::cerr << "Tag <choice> attribute 'name' must be compatible with Enum naming. name was '" << qPrintable(choice.name) << "'. 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
index c17bd395..55e59736 100644
--- a/src/kconfig_compiler/README.dox
+++ b/src/kconfig_compiler/README.dox
@@ -354,7 +354,7 @@ this allows the same Enum value names to be used in different enums. For example
<entry name="KeepData" type="Enum">
<choices>
<choice name="Do">
- <choice name="Dont">
+ <choice name="Dont" value="Don't">
</choices>
</entry>
\endverbatim
@@ -369,6 +369,9 @@ will generate this public class containing the enum definition, inside the gener
};
\endverbatim
+Since 5.68, if present the <b>value</b> attribute will be used as the choice value written to the backend
+instead of the <b>name</b>, allowing to write text incompatible with enum naming.
+
Alternatively, if <b>GlobalEnums</b> 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 @@ is set to true, the .kcfg entry
<entry name="KeepData" type="Enum">
<choices prefix="Keep_">
<choice name="Do">
- <choice name="Dont">
+ <choice name="Dont" value="Don't">
</choices>
</entry>
\endverbatim
diff --git a/src/kconfig_compiler/kcfg.xsd b/src/kconfig_compiler/kcfg.xsd
index 77a335cd..11196d45 100644
--- a/src/kconfig_compiler/kcfg.xsd
+++ b/src/kconfig_compiler/kcfg.xsd
@@ -93,6 +93,7 @@
<xsd:element minOccurs="0" name="tooltip" type="kcfg:translatableString"/>
</xsd:all>
<xsd:attribute name="name" use="required" type="xsd:string"/>
+ <xsd:attribute name="value" use="optional" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>