diff --git a/sources/autoNum/ui/autonumberingdockwidget.cpp b/sources/autoNum/ui/autonumberingdockwidget.cpp index 97f2d2f1b..664a00e90 100644 --- a/sources/autoNum/ui/autonumberingdockwidget.cpp +++ b/sources/autoNum/ui/autonumberingdockwidget.cpp @@ -26,6 +26,9 @@ #include "../numerotationcontext.h" #include "ui_autonumberingdockwidget.h" +#include +#include + /** @brief AutoNumberingDockWidget::AutoNumberingDockWidget Constructor @@ -58,6 +61,9 @@ void AutoNumberingDockWidget::clear() ui->m_conductor_cb->clear(); ui->m_element_cb->clear(); ui->m_folio_cb->clear(); + ui->m_conductor_value_le->clear(); + ui->m_element_value_le->clear(); + ui->m_folio_value_le->clear(); } void AutoNumberingDockWidget::projectClosed() @@ -109,6 +115,8 @@ void AutoNumberingDockWidget::setProject(QETProject *project, this,SLOT(setActive())); //Conductor, Element and Folio Signals + disconnect(m_project, &QETProject::autoNumContextUpdated, + this, &AutoNumberingDockWidget::refreshValueFields); disconnect(m_project, &QETProject::destroyed, this, &AutoNumberingDockWidget::projectClosed); } @@ -146,6 +154,8 @@ void AutoNumberingDockWidget::setProject(QETProject *project, this,SLOT(setActive())); //Conductor, Element and Folio Signals + connect(m_project, &QETProject::autoNumContextUpdated, + this, &AutoNumberingDockWidget::refreshValueFields); connect(m_project, &QETProject::destroyed, this, &AutoNumberingDockWidget::projectClosed); @@ -189,6 +199,12 @@ void AutoNumberingDockWidget::setContext() { ui->m_folio_cb -> addItem(str);} } + //The combo boxes have just been repopulated, so the value fields next + //to them are showing whatever the previous project left there. + refreshValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor); + refreshValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element); + refreshValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio); + this->setActive(); } @@ -263,6 +279,7 @@ void AutoNumberingDockWidget::on_m_conductor_cb_activated(int) m_project->setCurrentConductorAutoNum(current_autonum); m_project_view->currentDiagram()->diagram()->setConductorsAutonumName(current_autonum); m_project_view->currentDiagram()->diagram()->loadCndFolioSeq(); + refreshValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor); } /** @@ -291,6 +308,7 @@ void AutoNumberingDockWidget::on_m_element_cb_activated(int) { m_project->setCurrrentElementAutonum(ui->m_element_cb->currentText()); m_project_view->currentDiagram()->diagram()->loadElmtFolioSeq(); + refreshValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element); } /** @@ -328,6 +346,7 @@ void AutoNumberingDockWidget::on_m_folio_cb_activated(int) { m_project->setDefaultTitleBlockProperties(ip); } emit(folioAutoNumChanged(current_autonum)); + refreshValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio); } void AutoNumberingDockWidget::on_m_configure_pb_clicked() @@ -339,3 +358,209 @@ void AutoNumberingDockWidget::on_m_configure_pb_clicked() ppd.exec(); } } + +void AutoNumberingDockWidget::on_m_conductor_reset_start_pb_clicked() +{ + resetAutoNum(ui->m_conductor_cb, AutoNumCategory::Conductor); +} + +void AutoNumberingDockWidget::on_m_element_reset_start_pb_clicked() +{ + resetAutoNum(ui->m_element_cb, AutoNumCategory::Element); +} + +void AutoNumberingDockWidget::on_m_folio_reset_start_pb_clicked() +{ + resetAutoNum(ui->m_folio_cb, AutoNumCategory::Folio); +} + +void AutoNumberingDockWidget::on_m_conductor_value_le_editingFinished() +{ + applyValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor); +} + +void AutoNumberingDockWidget::on_m_element_value_le_editingFinished() +{ + applyValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element); +} + +void AutoNumberingDockWidget::on_m_folio_value_le_editingFinished() +{ + applyValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio); +} + +/** + @brief AutoNumberingDockWidget::contextFor + @return the numerotation context named by combo_box, for category +*/ +NumerotationContext AutoNumberingDockWidget::contextFor(QComboBox *combo_box, AutoNumCategory category) const +{ + const QString key = combo_box->currentText(); + switch (category) { + case AutoNumCategory::Conductor: return m_project->conductorAutoNum(key); + case AutoNumCategory::Element: return m_project->elementAutoNum(key); + case AutoNumCategory::Folio: return m_project->folioAutoNum(key); + } + return NumerotationContext(); +} + +/** + @brief AutoNumberingDockWidget::storeContext + Write context back under the name selected in combo_box and flag the + project as modified -- without that last step the change is not saved + and the user is never asked to save it on close. +*/ +void AutoNumberingDockWidget::storeContext(QComboBox *combo_box, AutoNumCategory category, const NumerotationContext &context) +{ + const QString key = combo_box->currentText(); + switch (category) { + case AutoNumCategory::Conductor: m_project->addConductorAutoNum(key, context); break; + case AutoNumCategory::Element: m_project->addElementAutoNum(key, context); break; + case AutoNumCategory::Folio: m_project->addFolioAutoNum(key, context); break; + } + m_project->setModified(true); +} + +/** + @brief AutoNumberingDockWidget::counterIndex + @return the index of the part the value field shows: the last one that + actually progresses, i.e. the least significant digit of the number. + -1 when the context has no progressing part at all. +*/ +int AutoNumberingDockWidget::counterIndex(const NumerotationContext &context) +{ + for (int i = context.size() - 1 ; i >= 0 ; --i) + { + const QString type = context.itemAt(i).at(0); + if (type == QLatin1String("unit") + || type == QLatin1String("ten") + || type == QLatin1String("hundred") + || type == QLatin1String("unitfolio") + || type == QLatin1String("tenfolio") + || type == QLatin1String("hundredfolio") + || type == QLatin1String("wrap") + || type == QLatin1String("alpha")) + return i; + } + return -1; +} + +/** + @brief AutoNumberingDockWidget::refreshValueFields + Re-read all three value fields from the project. Called whenever a + numerotation context's values change, which includes every element or + conductor that consumes the next number -- without this the field only + caught up when the user re-picked a rule from the combo box, because + the combo's activated() signal fires on user interaction alone. +*/ +void AutoNumberingDockWidget::refreshValueFields() +{ + //Leave alone a field the user is typing in: numbering an element + //refreshes all three, and overwriting a half-typed value under the + //cursor is worse than showing it a moment out of date. Only this + //automatic path skips; an explicit refresh after a reset or an edit + //still writes, so the field always ends up canonical. + if (!ui->m_conductor_value_le->hasFocus()) + refreshValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor); + if (!ui->m_element_value_le->hasFocus()) + refreshValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element); + if (!ui->m_folio_value_le->hasFocus()) + refreshValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio); +} + +/** + @brief AutoNumberingDockWidget::refreshValueField + Show the current value of the selected context's counter, so the field + always reflects where the numbering has actually got to. +*/ +void AutoNumberingDockWidget::refreshValueField(QComboBox *combo_box, QLineEdit *line_edit, AutoNumCategory category) +{ + if (!m_project || combo_box->currentText().isEmpty()) + { + line_edit->clear(); + line_edit->setEnabled(false); + return; + } + + const NumerotationContext context = contextFor(combo_box, category); + const int index = counterIndex(context); + line_edit->setEnabled(index >= 0); + line_edit->setText(index >= 0 ? context.itemAt(index).at(1) : QString()); +} + +/** + @brief AutoNumberingDockWidget::applyValueField + Write the value typed in line_edit to the counter it displays. An empty + field is treated as "no change" rather than as an empty value, so + clearing the box by accident cannot wipe the counter. +*/ +void AutoNumberingDockWidget::applyValueField(QComboBox *combo_box, QLineEdit *line_edit, AutoNumCategory category) +{ + if (!m_project || combo_box->currentText().isEmpty()) + return; + + NumerotationContext context = contextFor(combo_box, category); + const int index = counterIndex(context); + if (index < 0) + return; + + const QString typed = line_edit->text(); + if (typed.isEmpty() || typed == context.itemAt(index).at(1)) + { + refreshValueField(combo_box, line_edit, category); + return; + } + + context.replaceValue(index, typed); + storeContext(combo_box, category, context); + refreshValueField(combo_box, line_edit, category); +} + +/** + @brief AutoNumberingDockWidget::resetAutoNum + Reset the numerotation context currently selected in combo_box back to + a per-type starting value, then write it back. Does nothing if no + context is selected. + + Only parts that actually progress are touched: folio-anchored numeric + types go back to their own stored initialvalue, plain numeric types go + back to "1", a wrap part goes back to "0" because a modulo counter + cycles over [0, modulus) -- a PLC card addressed %IX0.0..%IX0.31 starts + at 0, not 1 -- and alpha goes back to "a". Non-incrementing types + (string, plant, locmach, idfolio, folio, elementline, elementcolumn, + elementprefix) are left alone: there is no "start" for them distinct + from the fixed or contextual value the user configured. +*/ +void AutoNumberingDockWidget::resetAutoNum(QComboBox *combo_box, AutoNumCategory category) +{ + if (!m_project || combo_box->currentText().isEmpty()) + return; + + NumerotationContext context = contextFor(combo_box, category); + + for (int i = 0 ; i < context.size() ; ++i) + { + const QStringList item = context.itemAt(i); + const QString &type = item.at(0); + if (type == QLatin1String("unitfolio") + || type == QLatin1String("tenfolio") + || type == QLatin1String("hundredfolio")) + context.replaceValue(i, item.size() > 3 ? item.at(3) : QStringLiteral("1")); + else if (type == QLatin1String("unit") + || type == QLatin1String("ten") + || type == QLatin1String("hundred")) + context.replaceValue(i, QStringLiteral("1")); + else if (type == QLatin1String("wrap")) + context.replaceValue(i, QStringLiteral("0")); + else if (type == QLatin1String("alpha")) + context.replaceValue(i, QStringLiteral("a")); + } + + storeContext(combo_box, category, context); + + switch (category) { + case AutoNumCategory::Conductor: refreshValueField(combo_box, ui->m_conductor_value_le, category); break; + case AutoNumCategory::Element: refreshValueField(combo_box, ui->m_element_value_le, category); break; + case AutoNumCategory::Folio: refreshValueField(combo_box, ui->m_folio_value_le, category); break; + } +} diff --git a/sources/autoNum/ui/autonumberingdockwidget.h b/sources/autoNum/ui/autonumberingdockwidget.h index 9232b908b..cdfb9f08e 100644 --- a/sources/autoNum/ui/autonumberingdockwidget.h +++ b/sources/autoNum/ui/autonumberingdockwidget.h @@ -23,6 +23,9 @@ #include +class QComboBox; +class QLineEdit; + namespace Ui { class AutoNumberingDockWidget; } @@ -51,13 +54,45 @@ class AutoNumberingDockWidget : public QDockWidget void folioAutoNumChanged(); void clear(); void projectClosed(); + void refreshValueFields(); void on_m_configure_pb_clicked(); - + + void on_m_conductor_reset_start_pb_clicked(); + void on_m_element_reset_start_pb_clicked(); + void on_m_folio_reset_start_pb_clicked(); + + void on_m_conductor_value_le_editingFinished(); + void on_m_element_value_le_editingFinished(); + void on_m_folio_value_le_editingFinished(); + signals: void folioAutoNumChanged(QString); private: + enum class AutoNumCategory { Conductor, Element, Folio }; + + /** + @brief resetAutoNum + Reset the numerotation context currently selected in combo_box + (for the given category) to a per-type starting value. Does + nothing if no context is selected. + */ + void resetAutoNum(QComboBox *combo_box, AutoNumCategory category); + + /// Read/write the numerotation context named in combo_box. + NumerotationContext contextFor(QComboBox *combo_box, AutoNumCategory category) const; + void storeContext(QComboBox *combo_box, AutoNumCategory category, const NumerotationContext &context); + + /// Index of the counter the value field shows and edits: the last + /// part that actually progresses. Returns -1 when the context has + /// no such part (e.g. it is only fixed text). + static int counterIndex(const NumerotationContext &context); + + /// Refresh a value field from its context, and apply a typed value. + void refreshValueField(QComboBox *combo_box, QLineEdit *line_edit, AutoNumCategory category); + void applyValueField(QComboBox *combo_box, QLineEdit *line_edit, AutoNumCategory category); + Ui::AutoNumberingDockWidget *ui; QETProject* m_project = nullptr; ProjectView* m_project_view = nullptr; diff --git a/sources/autoNum/ui/autonumberingdockwidget.ui b/sources/autoNum/ui/autonumberingdockwidget.ui index a1d9082aa..578a475b1 100644 --- a/sources/autoNum/ui/autonumberingdockwidget.ui +++ b/sources/autoNum/ui/autonumberingdockwidget.ui @@ -28,6 +28,39 @@ + + + + + 24 + 16777215 + + + + Réinitialiser à la valeur de départ + + + + + + + :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png + + + + + + + + 70 + 16777215 + + + + Valeur actuelle du compteur. Saisir une nouvelle valeur et valider pour la modifier. + + + @@ -42,9 +75,75 @@ + + + + + 24 + 16777215 + + + + Réinitialiser à la valeur de départ + + + + + + + :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png + + + + + + + + 70 + 16777215 + + + + Valeur actuelle du compteur. Saisir une nouvelle valeur et valider pour la modifier. + + + + + + + + 24 + 16777215 + + + + Réinitialiser à la valeur de départ + + + + + + + :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png + + + + + + + + 70 + 16777215 + + + + Valeur actuelle du compteur. Saisir une nouvelle valeur et valider pour la modifier. + + + diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index 3d205edfa..9b115458d 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -726,6 +726,7 @@ QHash QETProject::folioAutoNum() const */ void QETProject::addConductorAutoNum(const QString& key, const NumerotationContext& context) { m_conductor_autonum.insert(key, context); + emit autoNumContextUpdated(); } /** @@ -739,6 +740,7 @@ void QETProject::addElementAutoNum(const QString& key, const NumerotationContext { m_element_autonum.insert(key, context); emit elementAutoNumAdded(key); + emit autoNumContextUpdated(); } /** @@ -750,6 +752,7 @@ void QETProject::addElementAutoNum(const QString& key, const NumerotationContext */ void QETProject::addFolioAutoNum(const QString& key, const NumerotationContext& context) { m_folio_autonum.insert(key, context); + emit autoNumContextUpdated(); } /** diff --git a/sources/qetproject.h b/sources/qetproject.h index dfd5ab8ea..61427ca72 100644 --- a/sources/qetproject.h +++ b/sources/qetproject.h @@ -234,6 +234,12 @@ class QETProject : public QObject void conductorAutoNumAdded(); void conductorAutoNumRemoved(); void folioAutoNumAdded(); + /// A numerotation context's *values* changed -- as happens every + /// time an element or conductor consumes the next number, not + /// only when a rule is added or removed. Deliberately separate + /// from the *Added/*Removed signals above, which make listeners + /// rebuild their rule lists; this one just says "re-read me". + void autoNumContextUpdated(); void folioAutoNumRemoved(); void folioAutoNumChanged(QString); void defaultTitleBlockPropertiesChanged();