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).
This commit is contained in:
Shane Ringrose
2026-06-12 05:45:08 +12:00
parent e7787daa2c
commit ba6320bff8
3 changed files with 72 additions and 22 deletions
+11 -6
View File
@@ -1756,6 +1756,10 @@ QString TitleBlockTemplate::interpreteVariables(
QStringList TitleBlockTemplate::listOfVariables() QStringList TitleBlockTemplate::listOfVariables()
{ {
QStringList list; 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 // run through each individual cell
for (int j = 0 ; j < rows_heights_.count() ; ++ j) { for (int j = 0 ; j < rows_heights_.count() ; ++ j) {
for (int i = 0 ; i < columns_width_.count() ; ++ i) { for (int i = 0 ; i < columns_width_.count() ; ++ i) {
@@ -1763,14 +1767,15 @@ QStringList TitleBlockTemplate::listOfVariables()
|| cells_[i][j] -> cell_type || cells_[i][j] -> cell_type
== TitleBlockCell::EmptyCell) == TitleBlockCell::EmptyCell)
continue; continue;
#if TODO_LIST const QString cell_value = cells_[i][j] -> value.name();
#pragma message("@TODO not works on all cases...") auto it = rx.globalMatch(cell_value);
#endif while (it.hasNext()) {
// TODO: not works on all cases... const QString name = it.next().captured(1);
list << cells_[i][j] -> value.name().replace("%",""); if (!name.isEmpty() && !list.contains(name))
list << name;
}
} }
} }
qDebug() << list;
return list; return list;
} }
+58 -16
View File
@@ -24,6 +24,7 @@
#include "ui_titleblockpropertieswidget.h" #include "ui_titleblockpropertieswidget.h"
#include <QMenu> #include <QMenu>
#include <QSet>
#include <utility> #include <utility>
/** /**
@@ -162,7 +163,11 @@ void TitleBlockPropertiesWidget::setProperties(
} }
ui -> m_tbt_cb -> setCurrentIndex(index); 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 @brief TitleBlockPropertiesWidget::templateForIndex
Load the additional field of title block "text" @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); QET::QetCollection qc = m_map_index_to_collection_type.at(index);
TitleBlockTemplatesCollection *collection = nullptr; TitleBlockTemplatesCollection *collection = nullptr;
@@ -448,21 +456,55 @@ void TitleBlockPropertiesWidget::changeCurrentTitleBlockTemplate(int index)
if (c -> collection() == qc) if (c -> collection() == qc)
collection = c; 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()); @brief TitleBlockPropertiesWidget::addTemplateVariables
if(tpl != nullptr) { Add to @p context every CUSTOM variable used by the currently selected
// get all template fields template that is not already present, with an empty value — so the user
QStringList fields = tpl -> listOfVariables(); only has to fill in the values instead of declaring the variables (#271).
// set fields to additional_fields_ widget The standard fields (title, author, date, …) are handled by their own
DiagramContext templateContext; widgets and are skipped. Existing values in @p context are preserved.
for(int i =0; i<fields.count(); i++) */
templateContext.addValue(fields.at(i), ""); void TitleBlockPropertiesWidget::addTemplateVariables(
m_dcw -> setContext(templateContext); 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<QString> 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 @brief TitleBlockPropertiesWidget::on_m_date_now_pb_clicked
Set the date to current date Set the date to current date
+3
View File
@@ -30,6 +30,7 @@ class NumerotationContext;
class QETProject; class QETProject;
class QMenu; class QMenu;
class TitleBlockTemplatesCollection; class TitleBlockTemplatesCollection;
class TitleBlockTemplate;
namespace Ui { namespace Ui {
class TitleBlockPropertiesWidget; class TitleBlockPropertiesWidget;
@@ -77,6 +78,8 @@ class TitleBlockPropertiesWidget : public QWidget
void initDialog(const bool &current_date, QETProject *project); void initDialog(const bool &current_date, QETProject *project);
int getIndexFor (const QString &tbt_name, int getIndexFor (const QString &tbt_name,
const QET::QetCollection collection) const; const QET::QetCollection collection) const;
TitleBlockTemplate *templateForIndex (int index) const;
void addTemplateVariables (DiagramContext &context, int index) const;
private slots: private slots:
void editCurrentTitleBlockTemplate(); void editCurrentTitleBlockTemplate();