From e22f94175532219bc0d16f62422e8bfe0e1d1f40 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Thu, 29 Feb 2024 15:28:38 +0100 Subject: [PATCH] ensure that there are no duplicate names in lists --- GUI/Model/Type/NamedItem.cpp | 60 +++++++++++++++++++++++++++++++++++ GUI/Model/Type/NamedItem.h | 7 +++- GUI/Model/Type/SetWithModel.h | 5 ++- 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 GUI/Model/Type/NamedItem.cpp diff --git a/GUI/Model/Type/NamedItem.cpp b/GUI/Model/Type/NamedItem.cpp new file mode 100644 index 00000000000..3a61656596a --- /dev/null +++ b/GUI/Model/Type/NamedItem.cpp @@ -0,0 +1,60 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Type/NamedItem.cpp +//! @brief Implements class NamedItem. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "GUI/Model/Type/NamedItem.h" +#include <QRegularExpression> +#include <QRegularExpressionMatch> + +namespace { + +QStringList splitName(const QString& s) { + QRegularExpression pattern("(.*)_(\\d+)"); + QRegularExpressionMatch match = pattern.match(s); + if (match.hasMatch()) { + QStringList groups; + for (int i = 1; i < match.lastCapturedIndex() + 1; ++i) + groups << match.captured(i); + return groups; + } + return {}; // s does not contain '_\d+' +} + +} // namespace + + +void NamedItem::renumber(const QStringList& extant_names) +{ + // Item name consists of a stem and an optional number + QStringList ns = splitName(name()); + QString stem = ns.isEmpty() ? name() : ns[0]; + + // Determine highest number for given stem in extant_items + int imax = 0; + for (QString tname : extant_names) { + QStringList ts = splitName(tname); + if (ts.isEmpty()) { + if (tname == stem) + imax = std::max(imax, 1); + } else { + if (ts[0] == stem) + imax = std::max(imax, ts[1].toInt()); + } + } + + if (imax != 0) + setName(stem + "_" + QString::number(imax + 1)); + + if (name().contains(' ')) + setName(name().replace(' ', '_')); +} diff --git a/GUI/Model/Type/NamedItem.h b/GUI/Model/Type/NamedItem.h index ef088ba376c..f60bf46783e 100644 --- a/GUI/Model/Type/NamedItem.h +++ b/GUI/Model/Type/NamedItem.h @@ -3,7 +3,7 @@ // BornAgain: simulate and fit reflection and scattering // //! @file GUI/Model/Type/NamedItem.h -//! @brief Defines and implements class NamedItem. +//! @brief Defines class NamedItem. //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -16,6 +16,7 @@ #define BORNAGAIN_GUI_MODEL_TYPE_NAMEDITEM_H #include <QString> +#include <vector> //! Base class of items that have a name and a description. @@ -33,6 +34,10 @@ public: QString description() const { return m_description; } void setDescription(const QString& description) { m_description = description; } + //! Changes name of item to avoid duplication of any name from extant items. + //! Also replaces blank by underscore characters. + void renumber(const QStringList& extant_names); + private: QString m_name; QString m_description; diff --git a/GUI/Model/Type/SetWithModel.h b/GUI/Model/Type/SetWithModel.h index 0c57c403f29..b2605d0ac0f 100644 --- a/GUI/Model/Type/SetWithModel.h +++ b/GUI/Model/Type/SetWithModel.h @@ -74,6 +74,7 @@ public: void add_item(T* t) { m_qmodel->beginInsertRows({}, size(), size()); + t->renumber(itemNames()); m_vec.push_back(t); m_idx = m_vec.size() - 1; m_qmodel->endInsertRows(); @@ -82,8 +83,10 @@ public: void add_items(std::vector<T*> v) { m_qmodel->beginInsertRows({}, size(), size()); - for (T* t : v) + for (T* t : v) { + t->renumber(itemNames()); m_vec.push_back(t); + } m_idx = m_vec.size() - 1; m_qmodel->endInsertRows(); emit AbstractSetModel::setChanged(); -- GitLab