diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake index 57a012916..24b8c67ea 100644 --- a/cmake/qet_compilation_vars.cmake +++ b/cmake/qet_compilation_vars.cmake @@ -761,6 +761,8 @@ set(QET_SRC_FILES ${QET_DIR}/sources/undocommand/movediagramcommand.h ${QET_DIR}/sources/undocommand/removediagramcommand.cpp ${QET_DIR}/sources/undocommand/removediagramcommand.h + ${QET_DIR}/sources/undocommand/setautonumcontextcommand.cpp + ${QET_DIR}/sources/undocommand/setautonumcontextcommand.h ${QET_DIR}/sources/undocommand/rotateselectioncommand.cpp ${QET_DIR}/sources/undocommand/rotateselectioncommand.h ${QET_DIR}/sources/undocommand/rotatetextscommand.cpp diff --git a/sources/conductorautonumerotation.cpp b/sources/conductorautonumerotation.cpp index 0f53c870d..58fe952d9 100644 --- a/sources/conductorautonumerotation.cpp +++ b/sources/conductorautonumerotation.cpp @@ -24,6 +24,7 @@ #include "qet.h" #include "qetdiagrameditor.h" #include "ui/potentialselectordialog.h" +#include "undocommand/setautonumcontextcommand.h" /** @brief ConductorAutoNumerotation::ConductorAutoNumerotation @@ -156,7 +157,16 @@ void ConductorAutoNumerotation::newProperties( autonum::setSequential(formula, seq, context, diagram, autoNum_name); NumerotationContextCommands ncc (context, diagram); - diagram->project()->addConductorAutoNum(autoNum_name, ncc.next()); + NumerotationContext new_context = ncc.next(); + + QETProject *project = diagram->project(); + auto *undo = new SetAutoNumContextCommand( + [project](const QString &k, const NumerotationContext &c) {project->addConductorAutoNum(k, c);}, + autoNum_name, + context, + new_context); + undo->setText(QObject::tr("Numéroter automatiquement un conducteur", "undo caption")); + diagram->undoStack().push(undo); } /** @@ -245,7 +255,21 @@ void ConductorAutoNumerotation::numerateNewConductor() autoNum_name); NumerotationContextCommands ncc (context, m_diagram); - m_diagram->project()->addConductorAutoNum(autoNum_name, ncc.next()); + NumerotationContext new_context = ncc.next(); + + QETProject *project = m_diagram->project(); + auto setter = [project](const QString &k, const NumerotationContext &c) {project->addConductorAutoNum(k, c);}; + + if (m_parent_undo) + { + new SetAutoNumContextCommand(setter, autoNum_name, context, new_context, m_parent_undo); + } + else + { + auto *undo = new SetAutoNumContextCommand(setter, autoNum_name, context, new_context); + undo->setText(QObject::tr("Numéroter automatiquement un conducteur", "undo caption")); + m_diagram->undoStack().push(undo); + } } applyText(autonum::AssignVariables::formulaToLabel( diff --git a/sources/diagramevent/diagrameventaddelement.cpp b/sources/diagramevent/diagrameventaddelement.cpp index 203a0d953..dee2834c0 100644 --- a/sources/diagramevent/diagrameventaddelement.cpp +++ b/sources/diagramevent/diagrameventaddelement.cpp @@ -271,7 +271,12 @@ void DiagramEventAddElement::addElement() } m_diagram->addItem(m_element); + //Autonum the new element before pushing undo_object, so the counter + //change it triggers is part of the same undo macro as the element's + //own placement (one Ctrl+Z reverts both, instead of silently + //leaving the counter advanced). + element->setUpFormula(true, undo_object); + m_diagram -> undoStack().push(undo_object); - element->setUpFormula(); element->freezeNewAddedElement(); } diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index d6d12e312..620f9f8f4 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -33,6 +33,7 @@ #include "../qetgraphicsitem/terminal.h" #include "../ui/elementpropertieswidget.h" #include "../undocommand/changeelementinformationcommand.h" +#include "../undocommand/setautonumcontextcommand.h" #include "dynamicelementtextitem.h" #include "elementtextitemgroup.h" #include "iostream" @@ -1626,7 +1627,7 @@ void Element::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) (ex K for coil) with condition : formula is empty, text tagged "label" is emptty or "_"; */ -void Element::setUpFormula(bool code_letter) +void Element::setUpFormula(bool code_letter, QUndoCommand *parent_undo) { Q_UNUSED(code_letter) @@ -1655,8 +1656,21 @@ void Element::setUpFormula(bool code_letter) nc, diagram(), element_currentAutoNum); - diagram()->project()->addElementAutoNum(element_currentAutoNum, - ncc.next()); + + NumerotationContext new_context = ncc.next(); + QETProject *project = diagram()->project(); + auto setter = [project](const QString &k, const NumerotationContext &c) {project->addElementAutoNum(k, c);}; + + if (parent_undo) + { + new SetAutoNumContextCommand(setter, element_currentAutoNum, nc, new_context, parent_undo); + } + else + { + auto *undo = new SetAutoNumContextCommand(setter, element_currentAutoNum, nc, new_context); + undo->setText(tr("Numéroter automatiquement un élément", "undo caption")); + diagram()->undoStack().push(undo); + } if(!m_freeze_label && !formula.isEmpty()) { diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h index fce4f4878..03b2ed5da 100644 --- a/sources/qetgraphicsitem/element.h +++ b/sources/qetgraphicsitem/element.h @@ -35,6 +35,7 @@ class Terminal; class Conductor; class DynamicElementTextItem; class ElementTextItemGroup; +class QUndoCommand; /** This is the base class for electrical elements. @@ -142,7 +143,7 @@ class Element : public QetGraphicsItem {return m_autoNum_seq;} autonum::sequentialNumbers& rSequenceStruct() {return m_autoNum_seq;} - void setUpFormula(bool code_letter = true); + void setUpFormula(bool code_letter = true, QUndoCommand *parent_undo = nullptr); void setPrefix(QString); QString getPrefix() const; void freezeLabel(bool freeze); diff --git a/sources/undocommand/setautonumcontextcommand.cpp b/sources/undocommand/setautonumcontextcommand.cpp new file mode 100644 index 000000000..2941cc82c --- /dev/null +++ b/sources/undocommand/setautonumcontextcommand.cpp @@ -0,0 +1,52 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "setautonumcontextcommand.h" + +#include + +/** + @brief SetAutoNumContextCommand::SetAutoNumContextCommand + @param setter the QETProject setter to call on undo/redo + (addConductorAutoNum/addElementAutoNum/addFolioAutoNum, bound to a project) + @param key the numerotation context's name/key + @param old_context the context's value before this placement + @param new_context the context's value after this placement + @param parent parent undo command +*/ +SetAutoNumContextCommand::SetAutoNumContextCommand( + Setter setter, + const QString &key, + const NumerotationContext &old_context, + const NumerotationContext &new_context, + QUndoCommand *parent) : + QUndoCommand(parent), + m_setter(std::move(setter)), + m_key(key), + m_old_context(old_context), + m_new_context(new_context) +{} + +void SetAutoNumContextCommand::redo() +{ + m_setter(m_key, m_new_context); +} + +void SetAutoNumContextCommand::undo() +{ + m_setter(m_key, m_old_context); +} diff --git a/sources/undocommand/setautonumcontextcommand.h b/sources/undocommand/setautonumcontextcommand.h new file mode 100644 index 000000000..4c4935585 --- /dev/null +++ b/sources/undocommand/setautonumcontextcommand.h @@ -0,0 +1,57 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef SETAUTONUMCONTEXTCOMMAND_H +#define SETAUTONUMCONTEXTCOMMAND_H + +#include "../autoNum/numerotationcontext.h" + +#include +#include + +/** + @brief The SetAutoNumContextCommand class + Undo/redo wrapper around one of QETProject's add*AutoNum() setters + (conductor/element/folio numerotation counters). Placing an + auto-numbered item advances one of these counters as a side effect; + without this command the counter change sits outside the undo stack + entirely, so undoing the placement removes the visible number but + leaves the counter advanced, silently burning it. +*/ +class SetAutoNumContextCommand : public QUndoCommand +{ + public: + using Setter = std::function; + + SetAutoNumContextCommand( + Setter setter, + const QString &key, + const NumerotationContext &old_context, + const NumerotationContext &new_context, + QUndoCommand *parent = nullptr); + + void undo() override; + void redo() override; + + private: + Setter m_setter; + QString m_key; + NumerotationContext m_old_context; + NumerotationContext m_new_context; +}; + +#endif // SETAUTONUMCONTEXTCOMMAND_H