diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake index 60fddcf55..398cdce8c 100644 --- a/cmake/qet_compilation_vars.cmake +++ b/cmake/qet_compilation_vars.cmake @@ -325,6 +325,7 @@ set(QET_SRC_FILES ${QET_DIR}/sources/autoNum/ui/selectautonumw.cpp ${QET_DIR}/sources/autoNum/ui/selectautonumw.h + ${QET_DIR}/sources/dataBase/legacyelementtypes.h ${QET_DIR}/sources/dataBase/projectdatabase.cpp ${QET_DIR}/sources/dataBase/projectdatabase.h ${QET_DIR}/sources/dataBase/sqlreadonly.cpp diff --git a/sources/dataBase/legacyelementtypes.h b/sources/dataBase/legacyelementtypes.h new file mode 100644 index 000000000..51943996b --- /dev/null +++ b/sources/dataBase/legacyelementtypes.h @@ -0,0 +1,69 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef LEGACYELEMENTTYPES_H +#define LEGACYELEMENTTYPES_H + +#include +#include + +/** + Element type names in queries saved by versions before June 2022. + The project database then held Element::linkTypeToString() ("Simple", + "Terminale", ...); since it holds ElementData::typeToString() + ("simple", "terminal", ...). SQLite compares text case-sensitively, so + a nomenclature table saved with element_type = 'Simple' silently lost + every simple element, and its continuation tables were deleted as + empty. +*/ +namespace LegacyElementTypes +{ + /** + @return query with every element_type = '' comparison + rewritten to the current name. Anything else is left as it is, + so a query saved by a current version comes back unchanged. + */ + inline QString upgradeQuery(const QString &query) + { + static const QRegularExpression re(QStringLiteral( + "element_type\\s*=\\s*'(Simple|NextReport|PreviousReport|Master" + "|Slave|Terminale|Thumbnail)'")); + + QString upgraded = query; + auto it = re.globalMatch(query); + int shift = 0; + while (it.hasNext()) + { + const auto match = it.next(); + const QString old_name = match.captured(1); + QString new_name; + if (old_name == QLatin1String("Simple")) new_name = QStringLiteral("simple"); + else if (old_name == QLatin1String("NextReport")) new_name = QStringLiteral("next_report"); + else if (old_name == QLatin1String("PreviousReport")) new_name = QStringLiteral("previous_report"); + else if (old_name == QLatin1String("Master")) new_name = QStringLiteral("master"); + else if (old_name == QLatin1String("Slave")) new_name = QStringLiteral("slave"); + else if (old_name == QLatin1String("Terminale")) new_name = QStringLiteral("terminal"); + else new_name = QStringLiteral("thumbnail"); + + upgraded.replace(match.capturedStart(1) + shift, old_name.size(), new_name); + shift += new_name.size() - old_name.size(); + } + return upgraded; + } +} + +#endif // LEGACYELEMENTTYPES_H diff --git a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp index ca07e5ba8..a201fcb02 100644 --- a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp +++ b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp @@ -19,6 +19,7 @@ #include +#include "../../dataBase/legacyelementtypes.h" #include "../../dataBase/projectdatabase.h" #include "../../qetapp.h" #include "../../qetinformation.h" @@ -294,7 +295,9 @@ void ProjectDBModel::fromXml(const QDomElement &element) return; setIdentifier(element.firstChildElement("identifier").text()); - setQuery(element.firstChildElement("query").text()); + //A query saved before June 2022 names element types the old way + setQuery(LegacyElementTypes::upgradeQuery( + element.firstChildElement("query").text())); //Index 0,0 auto index_00 = element.firstChildElement("index00"); diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt index 66074282d..d2437661d 100644 --- a/tests/qttest/CMakeLists.txt +++ b/tests/qttest/CMakeLists.txt @@ -104,6 +104,13 @@ add_test(NAME tst_textgrid COMMAND tst_textgrid) target_include_directories(tst_textgrid PRIVATE ${QET_DIR}/sources) target_link_libraries(tst_textgrid PRIVATE Qt::Test) +# legacyelementtypes.h is header-only: the rewrite of element type names in +# nomenclature queries saved before June 2022. +add_executable(tst_legacyelementtypes tst_legacyelementtypes.cpp) +add_test(NAME tst_legacyelementtypes COMMAND tst_legacyelementtypes) +target_include_directories(tst_legacyelementtypes PRIVATE ${QET_DIR}/sources) +target_link_libraries(tst_legacyelementtypes PRIVATE Qt::Test) + add_executable( tst_qetpalette tst_qetpalette.cpp diff --git a/tests/qttest/tst_legacyelementtypes.cpp b/tests/qttest/tst_legacyelementtypes.cpp new file mode 100644 index 000000000..bc36725e1 --- /dev/null +++ b/tests/qttest/tst_legacyelementtypes.cpp @@ -0,0 +1,60 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "dataBase/legacyelementtypes.h" + +#include + +class TestLegacyElementTypes : public QObject +{ + Q_OBJECT + + private slots: + void upgradesOldNames_data() + { + QTest::addColumn("saved"); + QTest::addColumn("expected"); + + // The WHERE clause industrial.qet's parts list was saved with. + QTest::newRow("simple, with sub types") + << "WHERE ( element_type = 'Simple' OR element_sub_type = 'coil') ORDER BY label" + << "WHERE ( element_type = 'simple' OR element_sub_type = 'coil') ORDER BY label"; + QTest::newRow("terminal and master, lengths change") + << "element_type = 'Terminale' OR element_type = 'Master' OR element_type = 'Simple'" + << "element_type = 'terminal' OR element_type = 'master' OR element_type = 'simple'"; + QTest::newRow("reports and thumbnail") + << "element_type='NextReport' OR element_type = 'PreviousReport' OR element_type = 'Thumbnail'" + << "element_type='next_report' OR element_type = 'previous_report' OR element_type = 'thumbnail'"; + QTest::newRow("current names unchanged") + << "element_type = 'simple' OR element_type = 'terminal'" + << "element_type = 'simple' OR element_type = 'terminal'"; + QTest::newRow("the word elsewhere unchanged") + << "WHERE label = 'Simple' OR designation = 'Master'" + << "WHERE label = 'Simple' OR designation = 'Master'"; + QTest::newRow("empty") << "" << ""; + } + + void upgradesOldNames() + { + QFETCH(QString, saved); + QFETCH(QString, expected); + QCOMPARE(LegacyElementTypes::upgradeQuery(saved), expected); + } +}; + +QTEST_APPLESS_MAIN(TestLegacyElementTypes) +#include "tst_legacyelementtypes.moc"