mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-29 05:44:14 +02:00
Fix #1113: custom title-block variables in Find/Replace and unset placeholders
Two problems with a custom variable newly added to a title-block template:
1. Find/Replace > Folio > Custom showed an empty table, so the user had to
know and type each variable name. It now lists every custom variable the
folios already carry plus those their templates use, with empty values.
An empty value now means "leave unchanged", like every field of the main
tab; only the variables actually filled in are written to the folios.
2. The title block showed the variable's own name ("%doc-type") until the
folio's properties were opened, because interpreteVariables() only
replaces names present in the context. Placeholders in the template text
that no key resolves now render blank, as auto-added unset ones already
did since #973. Only the template's own text is considered, so a value
that contains "%something" is never touched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 &);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user