From 2a9bb9926d9e4515179b69d70bd579d778980058 Mon Sep 17 00:00:00 2001 From: Karsten Heimrich Date: Mon, 15 Oct 2018 14:52:25 +0200 Subject: Fix KNX project parsing for ETS version >= 5.6.* Task-number: QTBUG-70667 Change-Id: I626755acdbfa7f5bd2f187b5b3fee79346efa0c7 Reviewed-by: Karsten Heimrich --- src/knx/knxproj/qknxbuildings.cpp | 47 +++++++----- src/knx/knxproj/qknxbuildings_p.h | 2 + src/knx/knxproj/qknxgroupaddressinfos.cpp | 4 +- src/knx/knxproj/qknxinstallation.cpp | 21 +++--- tests/auto/qknxproject/data/locations.xml | 114 +++++++++++++++++++++++++++++ tests/auto/qknxproject/project.qrc | 1 + tests/auto/qknxproject/tst_qknxproject.cpp | 13 +++- 7 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 tests/auto/qknxproject/data/locations.xml diff --git a/src/knx/knxproj/qknxbuildings.cpp b/src/knx/knxproj/qknxbuildings.cpp index 850cf6a..ff81bc1 100644 --- a/src/knx/knxproj/qknxbuildings.cpp +++ b/src/knx/knxproj/qknxbuildings.cpp @@ -140,7 +140,7 @@ bool QKnxBuildingPart::parseElement(QXmlStreamReader *reader, bool pedantic) if (!reader || !reader->isStartElement()) return false; - if (reader->name() == QLatin1String("BuildingPart")) { + if (reader->name() == QLatin1String("BuildingPart") || reader->name() == QLatin1String("Space")) { auto attrs = reader->attributes(); // required attributes @@ -161,14 +161,15 @@ bool QKnxBuildingPart::parseElement(QXmlStreamReader *reader, bool pedantic) QStringLiteral("Building"), QStringLiteral("BuildingPart"), QStringLiteral("Floor"), QStringLiteral("Room"), QStringLiteral("DistributionBoard"), QStringLiteral("Stairway"), - QStringLiteral("Corridor") + QStringLiteral("Corridor"), QStringLiteral("Area"), QStringLiteral("Ground"), + QStringLiteral("Segment") }, &Type, reader, pedantic)) return false; if (!QKnxProjectUtils::fetchAttr(attrs, QStringLiteral("Puid"), &attr, reader)) return false; Puid = attr.toUInt(); - Type = attrs.value(QStringLiteral("Type")).toString(); // TODO: pedantic + Usage = attrs.value(QStringLiteral("Usage")).toString(); // TODO: pedantic Number = attrs.value(QStringLiteral("Number")).toString(); // TODO: pedantic Comment = attrs.value(QStringLiteral("Comment")).toString(); Description = attrs.value(QStringLiteral("Description")).toString(); @@ -184,11 +185,12 @@ bool QKnxBuildingPart::parseElement(QXmlStreamReader *reader, bool pedantic) while (!reader->atEnd() && !reader->hasError()) { auto tokenType = reader->readNext(); if (tokenType == QXmlStreamReader::TokenType::StartElement) { - if (reader->name() == QLatin1String("BuildingPart")) { - QKnxBuildingPart part; - if (!part.parseElement(reader, pedantic)) - return false; - BuildingPart.append(part); + if (reader->name() == QLatin1String("BuildingPart") + || reader->name() == QLatin1String("Space")) { + QKnxBuildingPart part; + if (!part.parseElement(reader, pedantic)) + return false; + BuildingPart.append(part); } else if (reader->name() == QStringLiteral("DeviceInstanceRef")) { QStringRef attr; if (!QKnxProjectUtils::fetchAttr(reader->attributes(), QLatin1String("RefId"), @@ -204,12 +206,15 @@ bool QKnxBuildingPart::parseElement(QXmlStreamReader *reader, bool pedantic) Function.append(function); } } else if (tokenType == QXmlStreamReader::TokenType::EndElement) { - if (reader->name() == QLatin1String("BuildingPart")) + if (reader->name() == QLatin1String("BuildingPart") + || reader->name() == QLatin1String("Space")) { break; + } } } } else { - reader->raiseError(tr("Expected element , got: <%1>.").arg(reader->name())); + reader->raiseError(tr("Expected element or , got: <%1>.") + .arg(reader->name())); } return !reader->hasError(); } @@ -222,24 +227,28 @@ bool QKnxBuildings::parseElement(QXmlStreamReader *reader, bool pedantic) if (!reader || !reader->isStartElement()) return false; - if (reader->name() == QLatin1String("Buildings")) { + if (reader->name() == QLatin1String("Buildings") || reader->name() == QLatin1String("Locations")) { // children while (!reader->atEnd() && !reader->hasError()) { auto tokenType = reader->readNext(); if (tokenType == QXmlStreamReader::TokenType::StartElement) { - if (reader->name() == QLatin1String("BuildingPart")) { - QKnxBuildingPart part; - if (!part.parseElement(reader, pedantic)) - return false; - BuildingPart.append(part); + if (reader->name() == QLatin1String("BuildingPart") + || reader->name() == QLatin1String("Space")) { + QKnxBuildingPart part; + if (!part.parseElement(reader, pedantic)) + return false; + BuildingPart.append(part); } } else if (tokenType == QXmlStreamReader::TokenType::EndElement) { - if (reader->name() == QLatin1String("Buildings")) - break; + if (reader->name() == QLatin1String("Buildings") + || reader->name() == QLatin1String("Locations")) { + break; + } } } } else { - reader->raiseError(tr("Expected element , got: <%1>.").arg(reader->name())); + reader->raiseError(tr("Expected element or , got: <%1>.") + .arg(reader->name())); } return !reader->hasError(); } diff --git a/src/knx/knxproj/qknxbuildings_p.h b/src/knx/knxproj/qknxbuildings_p.h index 6baa7ef..5d2ad09 100644 --- a/src/knx/knxproj/qknxbuildings_p.h +++ b/src/knx/knxproj/qknxbuildings_p.h @@ -92,7 +92,9 @@ public: QString Id; // non-colonized name, pattern [\i-[:]][\c-[:]]* QString Name; // 255 character max. QString Type; // Building, BuildingPart, Floor, Room, DistributionBoard, Stairway, Corridor + QString Usage; // optional QString Number; // optional, 255 character max. + QString Comment; // optional QString Description; // optional diff --git a/src/knx/knxproj/qknxgroupaddressinfos.cpp b/src/knx/knxproj/qknxgroupaddressinfos.cpp index 87f2e25..510fcab 100644 --- a/src/knx/knxproj/qknxgroupaddressinfos.cpp +++ b/src/knx/knxproj/qknxgroupaddressinfos.cpp @@ -294,7 +294,9 @@ bool QKnxGroupAddressInfos::parse() QZipReader zipReader(&file); const auto fileInfos = zipReader.fileInfoList(); for (const auto &fileInfo : qAsConst(fileInfos)) { - if (fileInfo.filePath.endsWith(QStringLiteral("0.xml"))) + auto file = fileInfo.filePath; + file = file.mid(file.lastIndexOf(QLatin1Char('/'), -5) + 1); + if (file == QStringLiteral("0.xml")) files.insert(fileInfo.filePath); } diff --git a/src/knx/knxproj/qknxinstallation.cpp b/src/knx/knxproj/qknxinstallation.cpp index ed1ef11..c351805 100644 --- a/src/knx/knxproj/qknxinstallation.cpp +++ b/src/knx/knxproj/qknxinstallation.cpp @@ -201,16 +201,17 @@ bool QKnxInstallation::parseElement(QXmlStreamReader *reader, bool pedantic) if (!topology.parseElement(reader, pedantic)) return false; Topology.append(topology); - } else if (reader->name() == QStringLiteral("Buildings")) { - if (pedantic && Buildings.size() >= 1) { - reader->raiseError(tr("Pedantic error: Encountered element " - " more than once.")); - return false; - } - QKnxBuildings buildings; - if (!buildings.parseElement(reader, pedantic)) - return false; - Buildings.append(buildings); + } else if (reader->name() == QStringLiteral("Buildings") + || reader->name() == QStringLiteral("Locations")) { + if (pedantic && Buildings.size() >= 1) { + reader->raiseError(tr("Pedantic error: Encountered element " + "<%1> more than once.").arg(reader->name())); + return false; + } + QKnxBuildings buildings; + if (!buildings.parseElement(reader, pedantic)) + return false; + Buildings.append(buildings); } else if (reader->name() == QStringLiteral("GroupAddresses")) { if (pedantic && GroupAddresses.size() >= 1) { reader->raiseError(tr("Pedantic error: Encountered element " diff --git a/tests/auto/qknxproject/data/locations.xml b/tests/auto/qknxproject/data/locations.xml new file mode 100644 index 0000000..a2ad8a2 --- /dev/null +++ b/tests/auto/qknxproject/data/locations.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qknxproject/project.qrc b/tests/auto/qknxproject/project.qrc index cbed69d..2553498 100644 --- a/tests/auto/qknxproject/project.qrc +++ b/tests/auto/qknxproject/project.qrc @@ -4,6 +4,7 @@ data/trades-busaccess-splitinfos.xml data/groupaddresses.xml data/buildings.xml + data/locations.xml data/topology.xml data/unassigneddevices.xml diff --git a/tests/auto/qknxproject/tst_qknxproject.cpp b/tests/auto/qknxproject/tst_qknxproject.cpp index 8dc04c4..a9429dd 100644 --- a/tests/auto/qknxproject/tst_qknxproject.cpp +++ b/tests/auto/qknxproject/tst_qknxproject.cpp @@ -449,9 +449,18 @@ private Q_SLOTS: QCOMPARE(address.Security, QLatin1String("Auto")); } - void testBuildings() + void testBuildingsAndLocations_data() { - QFile file(":/data/buildings.xml"); + QTest::addColumn("path"); + QTest::newRow("Test 'buildings' XML") << ":/data/buildings.xml"; + QTest::newRow("Test 'locations' XML") << ":/data/locations.xml"; + } + + void testBuildingsAndLocations() + { + QFETCH(QString, path); + + QFile file(path); QCOMPARE(file.open(QIODevice::ReadOnly), true); QXmlStreamReader reader(&file); -- cgit v1.2.3