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"