From 279b001a164beaa0c6f41c10c8b9123e26462bb4 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Mon, 21 Sep 2026 22:40:05 +1200 Subject: [PATCH] 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 --- sources/scripting/qetscriptapi.cpp | 74 ++++++++++++++++++++++++++++++ sources/scripting/qetscriptapi.h | 11 +++++ 2 files changed, 85 insertions(+) diff --git a/sources/scripting/qetscriptapi.cpp b/sources/scripting/qetscriptapi.cpp index 92b9cff83..3a059efbf 100644 --- a/sources/scripting/qetscriptapi.cpp +++ b/sources/scripting/qetscriptapi.cpp @@ -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; diff --git a/sources/scripting/qetscriptapi.h b/sources/scripting/qetscriptapi.h index f9f044d76..b6319a292 100644 --- a/sources/scripting/qetscriptapi.h +++ b/sources/scripting/qetscriptapi.h @@ -177,6 +177,15 @@ class DynamicElementTextItem; because the application itself does it through direct project calls and only the counter advance is on the undo stack; the numbering actually applied to a conductor is. + + For elements, useElementAutoNum() selects the current context and + numberElement() applies it to one element, as the "add element" tool + does right after placing one. addElement() deliberately does not + number what it places: doing it silently would change what an existing + script produces the moment its project happens to have a context + selected, so it is a separate, explicit call. Folio auto-numbering is + not offered: in the application it spawns whole new folios from a + context, which is a different operation from labelling. - @b Images: place a picture from a file. The pixels are copied into the project, which stores them inline in the .qet -- the saved file does not refer to the original path, so it opens on another machine, @@ -346,6 +355,8 @@ class QetScriptApi : public QObject Q_INVOKABLE bool addAutoNum(const QString &kind, const QString &name, const QStringList &parts); Q_INVOKABLE bool removeAutoNum(const QString &kind, const QString &name); Q_INVOKABLE bool useConductorAutoNum(int folioIndex, const QString &name); + Q_INVOKABLE bool useElementAutoNum(const QString &name); + Q_INVOKABLE bool numberElement(int folioIndex, const QString &elementUuid); // -- images, embedded in the project -- Q_INVOKABLE QStringList images(int folioIndex) const;