mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-03 10:34:14 +02:00
Add wrap-and-carry (cyclic/modulo) auto-numbering (#578)
Adds a configurable wrap-at-N counter type to the autonumbering engine (NumerotationContext + NumerotationContextCommands), covering PLC/rack-style addressing conventions like "e0.0...e0.7, e1.0...e1.7" (8 channels per card) generally, rather than hardcoding octal specifically. - New "wrap" part type (WrapNum, alongside the existing UnitNum/TenNum/ HundredNum strategies) stores a modulus in addition to the existing value/increase/initialvalue fields. Its own next()/previous() only wraps its own value modulo the configured modulus -- carrying into (or borrowing from) the adjacent part requires visibility across parts, which only the composition loop has. - NumerotationContextCommands::next()/previous() gained carry()/borrow() helpers: when a wrap part's own next() would reach/exceed its modulus (or go below 0 on previous()), the nearest preceding numeric part is bumped by exactly one unit, skipping non-numeric parts (e.g. a "." string separator). Wrap parts chain correctly if adjacent (e.g. seconds wrapping into minutes wrapping into hours). - For the leading part of a wrap-and-carry pair to stay fixed except when carried into (i.e. actually produce "e0.0...e0.7, e1.0..." rather than advancing on every step under its own strategy), its own increase must be 0. The increase spinbox's minimum was 1, which made this configuration impossible through the UI -- lowered to 0 and documented with a tooltip, since this wasn't obvious from the UI alone. - NumerotationContext gained a 5th pipe-separated field (modulus) in its serialized string form, defaulting to 0 (non-wrapping) for every existing part type; toXml()/fromXml() persist it as a "modulus" XML attribute the same way "initialvalue" is already persisted for unitfolio/tenfolio/hundredfolio. - New "Cyclique (modulo)" entry in the part-type dropdown (numparteditorw), available for element, conductor, and folio autonumbering alike, since all three already go through NumerotationContextCommands. Verified in the running app via the numbering config dialog's own Suivant/Précédent buttons (which call the production NumerotationContextCommands::next()/previous() directly): a two-part context (unit, increase=0 + wrap mod 8) produced exactly e0.0→...→e0.7→e1.0→...→e1.7 on repeated "next", and the exact reverse (with correct borrowing) on repeated "previous".
This commit is contained in:
@@ -71,6 +71,8 @@ NumPartEditorW::NumPartEditorW (NumerotationContext &context,
|
||||
setType(NumPartEditorW::hundred, true);
|
||||
else if (strl.at(0)=="hundredfolio")
|
||||
setType(NumPartEditorW::hundredfolio, true);
|
||||
else if (strl.at(0)=="wrap")
|
||||
setType(NumPartEditorW::wrap, true);
|
||||
else if (strl.at(0)=="string")
|
||||
setType(NumPartEditorW::string);
|
||||
else if (strl.at(0)=="idfolio")
|
||||
@@ -89,6 +91,8 @@ NumPartEditorW::NumPartEditorW (NumerotationContext &context,
|
||||
setType(NumPartEditorW::elementprefix);
|
||||
ui -> value_field -> setText(strl.at(1));
|
||||
ui -> increase_spinBox -> setValue(strl.at(2).toInt());
|
||||
if (strl.at(0)=="wrap" && strl.size() > 4)
|
||||
ui -> modulus_spinBox -> setValue(strl.at(4).toInt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +114,7 @@ void NumPartEditorW::setVisibleItems()
|
||||
items << tr("Chiffre 1")
|
||||
<< tr("Chiffre 01")
|
||||
<< tr("Chiffre 001")
|
||||
<< tr("Cyclique (modulo)")
|
||||
<< tr("Texte");
|
||||
}
|
||||
else if (m_edited_type == 1)
|
||||
@@ -120,6 +125,7 @@ void NumPartEditorW::setVisibleItems()
|
||||
<< tr("Chiffre 01 - Folio")
|
||||
<< tr("Chiffre 001")
|
||||
<< tr("Chiffre 001 - Folio")
|
||||
<< tr("Cyclique (modulo)")
|
||||
<< tr("Texte")
|
||||
<< tr("N° folio")
|
||||
<< tr("Folio")
|
||||
@@ -133,6 +139,7 @@ void NumPartEditorW::setVisibleItems()
|
||||
<< tr("Chiffre 01 - Folio")
|
||||
<< tr("Chiffre 001")
|
||||
<< tr("Chiffre 001 - Folio")
|
||||
<< tr("Cyclique (modulo)")
|
||||
<< tr("Texte")
|
||||
<< tr("N° folio")
|
||||
<< tr("Folio")
|
||||
@@ -195,6 +202,9 @@ NumerotationContext NumPartEditorW::toNumContext()
|
||||
case elementprefix:
|
||||
type_str = "elementprefix";
|
||||
break;
|
||||
case wrap:
|
||||
type_str = "wrap";
|
||||
break;
|
||||
}
|
||||
if (type_str == "unitfolio"
|
||||
|| type_str == "tenfolio"
|
||||
@@ -203,6 +213,12 @@ NumerotationContext NumPartEditorW::toNumContext()
|
||||
ui -> value_field -> displayText(),
|
||||
ui -> increase_spinBox -> value(),
|
||||
ui->value_field->displayText().toInt());
|
||||
else if (type_str == "wrap")
|
||||
nc.addValue(type_str,
|
||||
ui -> value_field -> displayText(),
|
||||
ui -> increase_spinBox -> value(),
|
||||
0,
|
||||
ui -> modulus_spinBox -> value());
|
||||
else
|
||||
nc.addValue(type_str,
|
||||
ui -> value_field -> displayText(),
|
||||
@@ -260,6 +276,8 @@ void NumPartEditorW::on_type_cb_activated(int) {
|
||||
setType(elementcolumn);
|
||||
else if (ui->type_cb->currentText() == tr("Element Prefix"))
|
||||
setType(elementprefix);
|
||||
else if (ui->type_cb->currentText() == tr("Cyclique (modulo)"))
|
||||
setType(wrap);
|
||||
emit changed();
|
||||
}
|
||||
|
||||
@@ -280,6 +298,14 @@ void NumPartEditorW::on_increase_spinBox_valueChanged(int) {
|
||||
if (!ui -> value_field -> text().isEmpty()) emit changed();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief NumPartEditorW::on_modulus_spinBox_valueChanged
|
||||
emit changed when modulus_spinBox value changed
|
||||
*/
|
||||
void NumPartEditorW::on_modulus_spinBox_valueChanged(int) {
|
||||
if (!ui -> value_field -> text().isEmpty()) emit changed();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief NumPartEditorW::setType
|
||||
Set good behavior by type t
|
||||
@@ -299,6 +325,7 @@ void NumPartEditorW::setType(NumPartEditorW::type t, bool fnum) {
|
||||
|| t==tenfolio
|
||||
|| t==hundred
|
||||
|| t==hundredfolio
|
||||
|| t==wrap
|
||||
)
|
||||
&& (type_==string
|
||||
|| type_==folio
|
||||
@@ -317,6 +344,8 @@ void NumPartEditorW::setType(NumPartEditorW::type t, bool fnum) {
|
||||
ui -> value_field -> setValidator(intValidator);
|
||||
ui -> increase_spinBox -> setEnabled(true);
|
||||
ui -> increase_spinBox -> setValue(1);
|
||||
if (t == wrap)
|
||||
ui -> modulus_spinBox -> setValue(8);
|
||||
}
|
||||
//@t isn't a numeric type
|
||||
else if (t == string
|
||||
@@ -362,6 +391,7 @@ void NumPartEditorW::setType(NumPartEditorW::type t, bool fnum) {
|
||||
ui -> increase_spinBox -> setDisabled(true);
|
||||
}
|
||||
}
|
||||
ui -> modulus_spinBox -> setEnabled(t == wrap);
|
||||
type_= t;
|
||||
}
|
||||
|
||||
@@ -400,5 +430,7 @@ void NumPartEditorW::setCurrentIndex(NumPartEditorW::type t) {
|
||||
i = ui->type_cb->findText(tr("Element Column"));
|
||||
else if (t == elementprefix)
|
||||
i = ui->type_cb->findText(tr("Element Prefix"));
|
||||
else if (t == wrap)
|
||||
i = ui->type_cb->findText(tr("Cyclique (modulo)"));
|
||||
ui->type_cb->setCurrentIndex(i);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ class NumPartEditorW : public QWidget
|
||||
enum type {unit,unitfolio,ten,tenfolio, hundred, hundredfolio,
|
||||
string,idfolio,folio,plant,locmach,
|
||||
elementline,elementcolumn,elementprefix,
|
||||
wrap,
|
||||
};
|
||||
NumerotationContext toNumContext();
|
||||
bool isValid ();
|
||||
@@ -63,6 +64,7 @@ class NumPartEditorW : public QWidget
|
||||
void on_type_cb_activated(int);
|
||||
void on_value_field_textEdited();
|
||||
void on_increase_spinBox_valueChanged(int);
|
||||
void on_modulus_spinBox_valueChanged(int);
|
||||
void setType (NumPartEditorW::type t, bool=false);
|
||||
|
||||
signals:
|
||||
|
||||
@@ -75,6 +75,9 @@
|
||||
<property name="wrapping">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Mettre à 0 pour un chiffre qui n'avance que par le report d'un chiffre cyclique suivant (ex: le "0" de "0.7")</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
@@ -88,7 +91,38 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="modulus_spinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Valeur à laquelle ce chiffre revient à 0 en incrémentant le chiffre précédent (0 = pas de cycle)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>mod. </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user