Let a script apply element auto-numbering

useElementAutoNum(name)   select the current element numbering context
  numberElement(folio, el)  give one element its label from it

numberElement calls Element::setUpFormula(), the call the "add element"
tool makes right after placing an element, so a script gets the same
numbering: three coils numbered in turn are K1, K2, K3, and the counter
persists in the project (after a reload the next element is K3).

It is a separate call rather than a change to addElement(), which is
merged code: numbering what it places would change what an existing
script produces the moment its project happens to have a context selected.
A slave or a report is refused, since it takes its label from its master,
and so is a project with no context selected, instead of reporting a
success that did nothing.

setUpFormula() has a hazard for an element that is already placed. It
writes the label straight into the element's information and pushes only
the counter's advance onto the undo stack. Placing a new element hides
that, because undoing the placement removes the element; for an existing
one, a single undo rolled the counter back and left the label, so c3 stayed
"K3" while the counter went back to expecting K3 and the next numbering
would repeat a label it had forgotten. So the label it computed is taken,
the information put back, and the change pushed as a command inside the
same macro as the counter: one undo now reverts both, and renumbering c3
afterwards yields K3 again. Redo and the database agree.

Folio auto-numbering is deliberately not offered: in the application it
spawns whole new folios from a context, which is a different operation
from labelling. "Renumber existing conductors" has no equivalent to bind --
conductor numbering is applied when a conductor is created or moved, and
QElectroTech has no renumber-all action.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-09-21 22:40:05 +12:00
parent 59cc758b7f
commit 279b001a16
2 changed files with 85 additions and 0 deletions
+74
View File
@@ -2115,6 +2115,80 @@ bool QetScriptApi::deleteElementText(int folioIndex, const QString &elementUuid,
return true;
}
/**
@brief QetScriptApi::useElementAutoNum
Make an element numbering context the project's current one, as choosing
it in the auto-numbering panel does. An empty name clears the selection.
*/
bool QetScriptApi::useElementAutoNum(const QString &name)
{
if (!m_project) return false;
if (m_project->isReadOnly()) {
log(QStringLiteral("qet.useElementAutoNum: project is read-only"));
return false;
}
if (!name.isEmpty() && !m_project->elementAutoNum().contains(name)) {
log(QStringLiteral("qet.useElementAutoNum: no element auto-numbering named '%1'").arg(name));
return false;
}
m_project->setCurrrentElementAutonum(name);
return true;
}
/**
@brief QetScriptApi::numberElement
Give one element its label from the current element numbering context,
through Element::setUpFormula() -- the call the "add element" tool makes
right after placing one.
Refused where setUpFormula() would do nothing, rather than reporting
success: a slave or a report takes its label from its master, and with no
current context there is no formula to apply.
*/
bool QetScriptApi::numberElement(int folioIndex, const QString &elementUuid)
{
if (!m_project) return false;
const QString caller = QStringLiteral("numberElement");
if (m_project->isReadOnly()) {
log(QStringLiteral("qet.%1: project is read-only").arg(caller));
return false;
}
Element *element = findElement(folioIndex, elementUuid);
if (!element) return false;
if (element->linkType() == Element::Slave || (element->linkType() & Element::AllReport)) {
log(QStringLiteral("qet.%1: a slave or a report takes its label from its master").arg(caller));
return false;
}
if (m_project->elementAutoNumCurrentFormula().isEmpty()) {
log(QStringLiteral("qet.%1: no element auto-numbering is selected (see useElementAutoNum)").arg(caller));
return false;
}
// setUpFormula() writes the label straight into the element's
// information and pushes only the counter's advance onto the undo stack.
// For a new element that is fine -- undoing the placement removes it --
// but for one already on the folio, one undo rolled the counter back and
// left the label behind (measured: c3 stayed "K3" while the counter went
// back to expecting K3), so the next numbering would repeat a label the
// counter had forgotten. So take the label it computed, put the
// information back, and push the change as a command of its own inside
// the same macro as the counter, making both one step.
const DiagramContext old_info = element->elementInformations();
QUndoStack *stack = m_project->undoStack();
stack->beginMacro(QObject::tr("Numéroter automatiquement un élément"));
element->setUpFormula(true);
const DiagramContext new_info = element->elementInformations();
if (new_info.value(QETInformation::ELMT_LABEL) == old_info.value(QETInformation::ELMT_LABEL)
&& new_info.value(QStringLiteral("formula")) == old_info.value(QStringLiteral("formula"))) {
stack->endMacro();
return false;
}
element->setElementInformations(old_info);
stack->push(new ChangeElementInformationCommand(element, old_info, new_info));
stack->endMacro();
return true;
}
int QetScriptApi::addFolio()
{
if (!m_project) return -1;