From 39862dc1094d9e53ca47e7ed46ad5f564e028df2 Mon Sep 17 00:00:00 2001 From: Gordon Crone Date: Thu, 4 Jun 2026 17:30:18 +0100 Subject: [PATCH 1/3] Add buttons to FileInfo to automatically add missing include files --- include/dbe/FileInfo.hpp | 11 +++++- src/structure/FileInfo.cpp | 69 ++++++++++++++++++++++++++++++++------ ui/FileInfo.ui | 14 ++++++++ 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/include/dbe/FileInfo.hpp b/include/dbe/FileInfo.hpp index f0d2aeb..30bd75b 100644 --- a/include/dbe/FileInfo.hpp +++ b/include/dbe/FileInfo.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace dbe { @@ -33,7 +34,9 @@ namespace dbe static QList get_path_urls(); static QStringList get_path_list(); static QString prune_path(QString file); - static bool match_path(QString& file, QStringList& includes); + static bool match_path(const QString& file, + const QString& top_file, + const QStringList& includes); static void parse_all_objects(); static QString check_file_includes(const QString& file); @@ -54,6 +57,8 @@ namespace dbe void add_datafile(); void add_schemafile(); void add_includefile(QFileDialog* fd); + void add_missing_datafiles(); + void add_missing_schemafiles(); void remove_datafile_slot(); void remove_schemafile_slot(); @@ -73,7 +78,11 @@ namespace dbe QMenu* m_object_menu{nullptr}; QUuid const m_uuid; + bool m_updating{false}; + static std::map> s_obj_map; + static std::map> s_missing_schema_map; + static std::map> s_missing_data_map; static QStringList s_path_list; static QList s_path_urls; diff --git a/src/structure/FileInfo.cpp b/src/structure/FileInfo.cpp index b108226..d1c8375 100644 --- a/src/structure/FileInfo.cpp +++ b/src/structure/FileInfo.cpp @@ -23,6 +23,8 @@ QString FileInfo::s_data_path{"."}; QStringList FileInfo::s_path_list{}; QList FileInfo::s_path_urls{}; std::map> FileInfo::s_obj_map{}; +std::map> FileInfo::s_missing_schema_map{}; +std::map> FileInfo::s_missing_data_map{}; void FileInfo::setup_paths() { QString DUNEDAQ_DB_PATH = getenv ( "DUNEDAQ_DB_PATH" ); @@ -57,16 +59,22 @@ QString FileInfo::prune_path(QString file) { return file; } -bool FileInfo::match_path(QString& file, QStringList& includes) { +bool FileInfo::match_path(const QString& file, + const QString& top_file, + const QStringList& includes) { + if (top_file.endsWith(file)) { + return true; + } + if (s_path_list.isEmpty()) { setup_paths(); } QStringList candidates{file}; - // element is a copy here, not a reference - for (const QString element : s_path_list) { + for (const auto& element : s_path_list) { if (file.startsWith(element)) { - candidates.append(file.remove(element)); + auto short_name = file; + candidates.append(short_name.remove(element)); } } @@ -100,6 +108,8 @@ void FileInfo::parse_all_objects() { auto name = QString::fromStdString(obj.full_name()); if (!s_obj_map.contains(file)) { s_obj_map.insert({file,{}}); + s_missing_schema_map.insert({file,{}}); + s_missing_data_map.insert({file,{}}); } s_obj_map.at(file).insert({name, obj}); } @@ -109,6 +119,9 @@ void FileInfo::parse_all_objects() { QString FileInfo::check_file_includes(const QString& filename) { QString message{}; + auto fname = prune_path(filename); + s_missing_schema_map.at(fname).clear(); + s_missing_data_map.at(fname).clear(); QStringList includes(config::api::get::file::inclusions_singlefile ( filename)); if (s_obj_map.contains(prune_path(filename))) { @@ -117,11 +130,12 @@ QString FileInfo::check_file_includes(const QString& filename) { dbe::config::api::info::onclass::definition (obj.class_name(), false); auto schema_file = QString::fromStdString(classdef.p_schema_path); - if (!match_path(schema_file, includes)) { + if (!match_path(schema_file, filename, includes)) { message += QString("Object " + id + " is of class " + QString::fromStdString(obj.class_name()) + " defined in file " + schema_file + " which is not included
"); + s_missing_schema_map.at(fname).insert(prune_path(schema_file)); } std::vector relobjs; for (auto rel: classdef.p_relationships) { @@ -137,14 +151,14 @@ QString FileInfo::check_file_includes(const QString& filename) { relobjs = dbegraph::linked::through::relation> (obj, rel); } - includes.append(prune_path(filename)); for (auto relobj : relobjs) { auto file = QString::fromStdString(relobj.contained_in()); - if (!(match_path(file, includes))) { + if (!(match_path(file, filename, includes))) { message += QString("Object " + id + " has relationship to " + QString::fromStdString(relobj.full_name()) + " in file " + file + " which is not included
"); + s_missing_data_map.at(fname).insert(prune_path(file)); } } } @@ -184,6 +198,9 @@ FileInfo::FileInfo(QString filename, QWidget* /*parent*/) connect (m_ui->add_schema, SIGNAL(pressed()), this, SLOT (add_schemafile())); connect (m_ui->add_data, SIGNAL(pressed()), this, SLOT (add_datafile())); + connect (m_ui->add_missing_schema, SIGNAL(pressed()), this, SLOT (add_missing_schemafiles())); + connect (m_ui->add_missing, SIGNAL(pressed()), this, SLOT (add_missing_datafiles())); + connect (m_ui->schema_list, SIGNAL (customContextMenuRequested(QPoint)), this, SLOT (activate_schema_context_menu(QPoint))); @@ -202,17 +219,20 @@ FileInfo::FileInfo(QString filename, QWidget* /*parent*/) } void FileInfo::filemodel_updated() { + if (m_updating) { + return; + } parse_includes(); parse_objects(); } - void FileInfo::parse_objects() { parse_all_objects(); m_ui->object_list->clear(); - if (s_obj_map.contains(prune_path(m_filename))) { - auto& omap = s_obj_map.at(prune_path(m_filename)); + auto fname = prune_path(m_filename); + if (s_obj_map.contains(fname)) { + auto& omap = s_obj_map.at(fname); for (auto const& [obj_name, obj_ref] : omap) { auto item = new QListWidgetItem(obj_name); m_ui->object_list->addItem(item); @@ -220,7 +240,10 @@ void FileInfo::parse_objects() { } m_ui->object_list->update(); - m_ui->warningBox->setVisible(!check_includes()); + auto status = check_includes(); + m_ui->add_missing_schema->setVisible(!s_missing_schema_map.at(fname).empty()); + m_ui->add_missing->setVisible(!s_missing_data_map.at(fname).empty()); + m_ui->warningBox->setVisible(!status); } @@ -346,15 +369,39 @@ void FileInfo::add_includefile(QFileDialog* fd) { fd->setSidebarUrls(s_path_urls); if (fd->exec() == QDialog::Accepted) { auto files = fd->selectedFiles(); + m_updating = true; for (auto file: files) { file = prune_path(file); config::api::commands::file::add(m_filename, file); } parse_includes(); parse_objects(); + m_updating = false; } } +void FileInfo::add_missing_schemafiles() { + m_updating = true; + for (const auto& file : s_missing_schema_map.at(prune_path(m_filename))) { + config::api::commands::file::add(m_filename, file); + } + parse_includes(); + parse_objects(); + + m_updating = false; +} + +void FileInfo::add_missing_datafiles() { + m_updating = true; + for (const auto& file : s_missing_data_map.at(prune_path(m_filename))) { + config::api::commands::file::add(m_filename, file); + } + parse_includes(); + parse_objects(); + + m_updating = false; +} + void FileInfo::remove_schemafile_slot() { remove_includefile(m_ui->schema_list->currentItem()->text()); } diff --git a/ui/FileInfo.ui b/ui/FileInfo.ui index 708a409..301e521 100644 --- a/ui/FileInfo.ui +++ b/ui/FileInfo.ui @@ -198,6 +198,13 @@ + + + + Add missing schema + + + @@ -259,6 +266,13 @@ + + + + Add missing files + + + From 12d28686902330f7274228fc1ee9e63b0857074c Mon Sep 17 00:00:00 2001 From: Gordon Crone Date: Thu, 11 Jun 2026 15:48:54 +0100 Subject: [PATCH 2/3] Check maps contain expected entry before accessing and use QScopedValueRollback for m_updating variable --- src/structure/FileInfo.cpp | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/structure/FileInfo.cpp b/src/structure/FileInfo.cpp index d1c8375..fc91123 100644 --- a/src/structure/FileInfo.cpp +++ b/src/structure/FileInfo.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -120,8 +122,16 @@ QString FileInfo::check_file_includes(const QString& filename) { QString message{}; auto fname = prune_path(filename); - s_missing_schema_map.at(fname).clear(); - s_missing_data_map.at(fname).clear(); + if (!s_missing_schema_map.contains(fname)) { + s_missing_schema_map.insert({fname,{}}); + } else { + s_missing_schema_map.at(fname).clear(); + } + if (!s_missing_data_map.contains(fname)) { + s_missing_data_map.insert({fname,{}}); + } else { + s_missing_data_map.at(fname).clear(); + } QStringList includes(config::api::get::file::inclusions_singlefile ( filename)); if (s_obj_map.contains(prune_path(filename))) { @@ -241,8 +251,15 @@ void FileInfo::parse_objects() { m_ui->object_list->update(); auto status = check_includes(); + if (!s_missing_schema_map.contains(fname)) { + s_missing_schema_map.insert({fname,{}}); + } + if (!s_missing_data_map.contains(fname)) { + s_missing_data_map.insert({fname,{}}); + } m_ui->add_missing_schema->setVisible(!s_missing_schema_map.at(fname).empty()); m_ui->add_missing->setVisible(!s_missing_data_map.at(fname).empty()); + m_ui->warningBox->setVisible(!status); } @@ -369,37 +386,44 @@ void FileInfo::add_includefile(QFileDialog* fd) { fd->setSidebarUrls(s_path_urls); if (fd->exec() == QDialog::Accepted) { auto files = fd->selectedFiles(); - m_updating = true; + QScopedValueRollback rb(m_updating,true); for (auto file: files) { file = prune_path(file); config::api::commands::file::add(m_filename, file); } parse_includes(); parse_objects(); - m_updating = false; } } void FileInfo::add_missing_schemafiles() { - m_updating = true; - for (const auto& file : s_missing_schema_map.at(prune_path(m_filename))) { + QScopedValueRollback rb(m_updating,true); + auto short_filename = prune_path(m_filename); + if (!s_missing_schema_map.contains(short_filename)) { + QMessageBox::warning (this, "Warning", + QString("Missing schema map is corrupt and does not contain %1").arg(short_filename)); + return; + } + for (const auto& file : s_missing_schema_map.at(short_filename)) { config::api::commands::file::add(m_filename, file); } parse_includes(); parse_objects(); - - m_updating = false; } void FileInfo::add_missing_datafiles() { - m_updating = true; + QScopedValueRollback rb(m_updating,true); + auto short_filename = prune_path(m_filename); + if (!s_missing_data_map.contains(short_filename)) { + QMessageBox::warning (this, "Warning", + QString("Missing data map is corrupt and does not contain %1").arg(short_filename)); + return; + } for (const auto& file : s_missing_data_map.at(prune_path(m_filename))) { config::api::commands::file::add(m_filename, file); } parse_includes(); parse_objects(); - - m_updating = false; } void FileInfo::remove_schemafile_slot() { From 751475c5657cd634a1b5d059be686b66d6c3bebd Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Mon, 22 Jun 2026 11:43:01 +0100 Subject: [PATCH 3/3] bump commit --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b08a214..4edf68a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.12) -project(dbe VERSION 1.8.0) +project(dbe VERSION 1.8.1) find_package(daq-cmake REQUIRED)