Reject more template mistakes

Empty keys, duplicate layer names and section ids, repeat on non-keysym
keys and stretch on letters/keys placeholders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 10:13:56 +02:00
co-authored by Claude Opus 5.5
parent 990d62ffcf
commit cfea9ece99
2 changed files with 49 additions and 0 deletions
+21
View File
@@ -1,6 +1,7 @@
#include "LayoutLoader.h"
#include <QFile>
#include <algorithm>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
@@ -48,6 +49,10 @@ std::optional<KeyDef> parseKey(const QJsonValue &value, QString *error)
KeyDef key;
if (value.isString()) {
key.label = value.toString();
if (key.label.isEmpty()) {
*error = QStringLiteral("empty key \"\"");
return std::nullopt;
}
return key;
}
if (!value.isObject()) {
@@ -104,6 +109,14 @@ std::optional<KeyDef> parseKey(const QJsonValue &value, QString *error)
*error = QStringLiteral("modifier must be one of %1").arg(ModifierNames.join(u", "));
return std::nullopt;
}
if (key.repeat && key.type != KeyType::Keysym) {
*error = QStringLiteral("\"%1\": only keysym keys repeat").arg(typeName);
return std::nullopt;
}
if (key.stretch && (key.type == KeyType::Letters || key.type == KeyType::Keys)) {
*error = QStringLiteral("\"%1\" rows can't stretch; their keys come from the keymap").arg(typeName);
return std::nullopt;
}
if (key.width <= 0) {
*error = QStringLiteral("key \"%1\" has a non-positive width").arg(key.label);
return std::nullopt;
@@ -197,6 +210,10 @@ std::optional<Layout> parse(const QByteArray &json, QString *error)
auto layer = parseLayer(layerValue.toObject(), error);
if (!layer)
return std::nullopt;
if (layout.layer(layer->name)) {
*error = QStringLiteral("duplicate layer \"%1\"").arg(layer->name);
return std::nullopt;
}
layout.layers.append(*layer);
}
@@ -204,6 +221,10 @@ std::optional<Layout> parse(const QByteArray &json, QString *error)
auto section = parseSection(sectionValue.toObject(), error);
if (!section)
return std::nullopt;
if (std::ranges::any_of(layout.sections, [&](const Section &s) { return s.id == section->id; })) {
*error = QStringLiteral("duplicate section \"%1\"").arg(section->id);
return std::nullopt;
}
layout.sections.append(*section);
}