Merge pull request #1121 from ispyisail/fix/titleblock-custom-vars-1113

Fix #1113: title-block variables shown by name and missing in Replace
This commit is contained in:
Laurent Trinques
2026-09-28 23:28:52 +02:00
committed by GitHub
6 changed files with 89 additions and 9 deletions
@@ -76,7 +76,20 @@ void SearchAndReplaceWorker::replaceDiagram(QList<Diagram *> diagram_list)
}
}
new_properties.context.add(m_titleblock_properties.context);
// The replace dialog lists every custom variable of the folios
// (#1113), so an empty value means "leave unchanged", exactly like
// the fields of the main tab.
const DiagramContext &change = m_titleblock_properties.context;
for (const QString &key : change.keys()) {
const QString value = change.value(key).toString();
if (value.isEmpty()) {
continue;
}
new_properties.context.addValue(
key,
applyChange(new_properties.context.value(key).toString(),
value));
}
if (old_propertie != new_properties) {
project->undoStack()->push(new ChangeTitleBlockCommand(d, old_propertie, new_properties));
@@ -30,6 +30,7 @@
#include "../../qeticons.h"
#include "../../qetinformation.h"
#include "../../qetproject.h"
#include "../../ui/titleblockpropertieswidget.h"
#include "replaceadvanceddialog.h"
#include "replaceconductordialog.h"
#include "replaceelementdialog.h"
@@ -1109,7 +1110,26 @@ void SearchAndReplaceWidget::on_m_previous_pb_clicked()
void SearchAndReplaceWidget::on_m_folio_pb_clicked()
{
ReplaceFolioDialog *dialog = new ReplaceFolioDialog(this);
dialog->setTitleBlockProperties(m_worker.m_titleblock_properties);
// List the custom variables the folios already use, so the user only
// has to type a value instead of guessing each name (#1113).
TitleBlockProperties properties = m_worker.m_titleblock_properties;
for (const QPointer<Diagram> &diagram : std::as_const(m_diagram_hash))
{
if (!diagram) {
continue;
}
for (const QString &key :
diagram->border_and_titleblock.exportTitleBlock().context.keys()) {
if (!properties.context.contains(key)) {
properties.context.addValue(key, QString());
}
}
TitleBlockPropertiesWidget::addTemplateVariables(
properties.context,
diagram->border_and_titleblock.titleBlockTemplate());
}
dialog->setTitleBlockProperties(properties);
int result = dialog->exec();
if (result == QDialogButtonBox::AcceptRole)
+36 -3
View File
@@ -27,6 +27,7 @@
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <algorithm>
/**
@brief TitleBlockTemplate::TitleBlockTemplate
Constructor
@@ -1818,14 +1819,46 @@ QString TitleBlockTemplate::interpreteVariables(
const QString &string,
const DiagramContext &diagram_context) const
{
// A variable nobody has given a value to yet -- e.g. one just added to
// the template, which is not in the folio's Custom tab until its
// properties are opened (#1113) -- must render blank rather than as its
// own name, the same as an auto-added but unset one already does (#973).
// Collect those from the template text before substituting, so a value
// that happens to contain "%something" is never touched.
// A bare "%name" is unset only if no key is a prefix of it, because the
// substitution below replaces "%key" wherever it appears.
static const QRegularExpression rx(
QStringLiteral("%\\{([a-z0-9_-]+)\\}|%([a-z0-9_-]+)"));
const QStringList keys =
diagram_context.keys(DiagramContext::DecreasingLength);
QStringList unset;
auto it = rx.globalMatch(string);
while (it.hasNext()) {
const QRegularExpressionMatch m = it.next();
const QString name = m.captured(1).isEmpty()
? m.captured(2) : m.captured(1);
bool known = diagram_context.contains(name);
if (!known && m.captured(1).isEmpty()) {
for (const QString &key : keys) {
if (name.startsWith(key)) { known = true; break; }
}
}
if (!known) unset << m.captured(0);
}
QString interpreted_string = string;
foreach (QString key,
diagram_context.keys(DiagramContext::DecreasingLength)) {
foreach (QString key, keys) {
interpreted_string.replace("%{" % key % "}",
diagram_context[key].toString());
interpreted_string.replace("%" % key,
diagram_context[key].toString());
}
std::sort(unset.begin(), unset.end(),
[](const QString &a, const QString &b) {
return a.length() > b.length();
});
for (const QString &placeholder : unset)
interpreted_string.remove(placeholder);
return(interpreted_string);
}
@@ -1834,7 +1867,7 @@ QString TitleBlockTemplate::interpreteVariables(
Get list of variables
@return The list of string with variables
*/
QStringList TitleBlockTemplate::listOfVariables()
QStringList TitleBlockTemplate::listOfVariables() const
{
QStringList list;
// Match both the braced "%{name}" form and the bare "%name" form
+1 -1
View File
@@ -188,7 +188,7 @@ class TitleBlockTemplate : public QObject {
void applyCellSpan(TitleBlockCell *);
void applyRowColNums();
void rowColsChanged();
QStringList listOfVariables();
QStringList listOfVariables() const;
protected:
void loadInformation(const QDomElement &);
+13 -3
View File
@@ -483,13 +483,23 @@ TitleBlockTemplate *TitleBlockPropertiesWidget::templateForIndex(int index) cons
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);
addTemplateVariables(context, templateForIndex(index));
}
/**
@brief TitleBlockPropertiesWidget::addTemplateVariables
Add to @p context every CUSTOM variable used by @p tpl that is not already
present, with an empty value.
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, const TitleBlockTemplate *tpl)
{
if (!tpl) return;
// Variables rendered from the dedicated standard-field widgets; they must
+4
View File
@@ -71,6 +71,10 @@ class TitleBlockPropertiesWidget : public QWidget
void setTitleBlockTemplatesVisible(const bool &visible);
void setReadOnly (const bool &ro);
static void addTemplateVariables(
DiagramContext &context,
const TitleBlockTemplate *tpl);
private:
void addCollection (
TitleBlockTemplatesCollection *tbt_collection);