From ba6320bff8ca65adfb0fa5e1b6a735a51b75eff2 Mon Sep 17 00:00:00 2001 From: Shane Ringrose Date: Fri, 12 Jun 2026 05:45:08 +1200 Subject: [PATCH] Folio properties: auto-add a title block's custom variables (#271) When a title block template uses custom variables (e.g. %{department}, %{owner}), the user previously had to declare each one by hand in the folio properties 'Custom' tab before a value could be entered. Now the template's undefined custom variables are added automatically, so the user only fills in the values. - listOfVariables() now extracts %{name} placeholders with a regex (deduplicated) instead of a crude '%' strip that returned '{name}'. - The folio properties widget merges the template's custom variables into the Custom tab both on open (setProperties) and when the template is changed, preserving any values already entered and skipping the standard fields (title, author, date, ...) which have their own inputs. Fixes #271 (variable auto-population; the revision-history request in the thread is a separate feature). --- sources/titleblocktemplate.cpp | 17 ++++-- sources/ui/titleblockpropertieswidget.cpp | 74 ++++++++++++++++++----- sources/ui/titleblockpropertieswidget.h | 3 + 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/sources/titleblocktemplate.cpp b/sources/titleblocktemplate.cpp index 351a34469..a7c729f31 100644 --- a/sources/titleblocktemplate.cpp +++ b/sources/titleblocktemplate.cpp @@ -1756,6 +1756,10 @@ QString TitleBlockTemplate::interpreteVariables( QStringList TitleBlockTemplate::listOfVariables() { QStringList list; + // Match every "%{name}" placeholder. The bare "%name" form can't be + // extracted reliably without the variable list, and templates use the + // braced form, so only that is collected here. + static const QRegularExpression rx(QStringLiteral("%\\{([^}]+)\\}")); // run through each individual cell for (int j = 0 ; j < rows_heights_.count() ; ++ j) { for (int i = 0 ; i < columns_width_.count() ; ++ i) { @@ -1763,14 +1767,15 @@ QStringList TitleBlockTemplate::listOfVariables() || cells_[i][j] -> cell_type == TitleBlockCell::EmptyCell) continue; -#if TODO_LIST -#pragma message("@TODO not works on all cases...") -#endif - // TODO: not works on all cases... - list << cells_[i][j] -> value.name().replace("%",""); + const QString cell_value = cells_[i][j] -> value.name(); + auto it = rx.globalMatch(cell_value); + while (it.hasNext()) { + const QString name = it.next().captured(1); + if (!name.isEmpty() && !list.contains(name)) + list << name; + } } } - qDebug() << list; return list; } diff --git a/sources/ui/titleblockpropertieswidget.cpp b/sources/ui/titleblockpropertieswidget.cpp index d4dc0a5b1..edce4217f 100644 --- a/sources/ui/titleblockpropertieswidget.cpp +++ b/sources/ui/titleblockpropertieswidget.cpp @@ -24,6 +24,7 @@ #include "ui_titleblockpropertieswidget.h" #include +#include #include /** @@ -162,7 +163,11 @@ void TitleBlockPropertiesWidget::setProperties( } ui -> m_tbt_cb -> setCurrentIndex(index); - m_dcw -> setContext(properties.context); + // Show the saved custom values, plus any of the template's custom variables + // that aren't defined yet, so the user only fills in the missing ones (#271). + DiagramContext context = properties.context; + addTemplateVariables(context, index); + m_dcw -> setContext(context); } /** @@ -435,12 +440,15 @@ void TitleBlockPropertiesWidget::updateTemplateList() } /** - @brief TitleBlockPropertiesWidget::changeCurrentTitleBlockTemplate - Load the additional field of title block "text" + @brief TitleBlockPropertiesWidget::templateForIndex + @param index : index in the collection-type map (= the template combo index) + @return the TitleBlockTemplate currently selected for that collection, or + nullptr. */ -void TitleBlockPropertiesWidget::changeCurrentTitleBlockTemplate(int index) +TitleBlockTemplate *TitleBlockPropertiesWidget::templateForIndex(int index) const { - m_dcw -> clear(); + if (index < 0 || index >= m_map_index_to_collection_type.count()) + return nullptr; QET::QetCollection qc = m_map_index_to_collection_type.at(index); TitleBlockTemplatesCollection *collection = nullptr; @@ -448,21 +456,55 @@ void TitleBlockPropertiesWidget::changeCurrentTitleBlockTemplate(int index) if (c -> collection() == qc) collection = c; - if (!collection) return; + if (!collection) return nullptr; + return collection -> getTemplate(ui -> m_tbt_cb -> currentText()); +} - // get template - TitleBlockTemplate *tpl = collection -> getTemplate(ui -> m_tbt_cb -> currentText()); - if(tpl != nullptr) { - // get all template fields - QStringList fields = tpl -> listOfVariables(); - // set fields to additional_fields_ widget - DiagramContext templateContext; - for(int i =0; i setContext(templateContext); +/** + @brief TitleBlockPropertiesWidget::addTemplateVariables + Add to @p context every CUSTOM variable used by the currently selected + template that is not already present, with an empty value — so the user + only has to fill in the values instead of declaring the variables (#271). + The standard fields (title, author, date, …) are handled by their own + widgets and are skipped. Existing values in @p context are preserved. +*/ +void TitleBlockPropertiesWidget::addTemplateVariables( + DiagramContext &context, int index) const +{ + TitleBlockTemplate *tpl = templateForIndex(index); + if (!tpl) return; + + // Variables rendered from the dedicated standard-field widgets; they must + // not appear in the "Custom" tab. + static const QSet reserved { + QStringLiteral("author"), QStringLiteral("date"), + QStringLiteral("title"), QStringLiteral("filename"), + QStringLiteral("plant"), QStringLiteral("locmach"), + QStringLiteral("indexrev"), QStringLiteral("version"), + QStringLiteral("folio"), QStringLiteral("folio-id"), + QStringLiteral("folio-total"), QStringLiteral("auto_page_num"), + QStringLiteral("previous-folio-num"), QStringLiteral("next-folio-num") + }; + + const QStringList variables = tpl -> listOfVariables(); + for (const QString &name : variables) { + if (name.isEmpty() || reserved.contains(name)) continue; + if (!context.contains(name)) context.addValue(name, ""); } } +/** + @brief TitleBlockPropertiesWidget::changeCurrentTitleBlockTemplate + When the user picks a template, append its missing custom variables to the + "Custom" tab while keeping the values already entered (#271). +*/ +void TitleBlockPropertiesWidget::changeCurrentTitleBlockTemplate(int index) +{ + DiagramContext context = m_dcw -> context(); + addTemplateVariables(context, index); + m_dcw -> setContext(context); +} + /** @brief TitleBlockPropertiesWidget::on_m_date_now_pb_clicked Set the date to current date diff --git a/sources/ui/titleblockpropertieswidget.h b/sources/ui/titleblockpropertieswidget.h index 66db05baa..00e8c1758 100644 --- a/sources/ui/titleblockpropertieswidget.h +++ b/sources/ui/titleblockpropertieswidget.h @@ -30,6 +30,7 @@ class NumerotationContext; class QETProject; class QMenu; class TitleBlockTemplatesCollection; +class TitleBlockTemplate; namespace Ui { class TitleBlockPropertiesWidget; @@ -77,6 +78,8 @@ class TitleBlockPropertiesWidget : public QWidget void initDialog(const bool ¤t_date, QETProject *project); int getIndexFor (const QString &tbt_name, const QET::QetCollection collection) const; + TitleBlockTemplate *templateForIndex (int index) const; + void addTemplateVariables (DiagramContext &context, int index) const; private slots: void editCurrentTitleBlockTemplate();