diff --git a/sources/autoNum/assignvariables.cpp b/sources/autoNum/assignvariables.cpp index 2aff912fe..8e2d465ec 100644 --- a/sources/autoNum/assignvariables.cpp +++ b/sources/autoNum/assignvariables.cpp @@ -497,15 +497,26 @@ namespace autonum { if (context.itemAt(i).at(0) == type) { + const QStringList item = context.itemAt(i); + //A zero-padding mask, spreadsheet style: its length is the + //minimum number of digits. It overrides the width implied + //by the part type, so "Chiffre 01" with a mask of "0000" + //pads to four. An absent mask -- which is every context + //written before the field existed -- falls through to the + //type's own width, so nothing about existing projects + //changes. + const QString mask = NumerotationContext::formatOf(item); QString number; - if (type == "ten" || type == "tenfolio") - number = QString("%1").arg(context.itemAt(i).at(1).toInt(), 2, 10, QChar('0')); - else if (type == "hundred" || type == "hundredfolio") - number = QString("%1").arg(context.itemAt(i).at(1).toInt(), 3, 10, QChar('0')); - else if (type == "alpha") + if (type == "alpha") //Alphabetic value, not an integer -- used as-is. - number = context.itemAt(i).at(1); - else number = QString::number(context.itemAt(i).at(1).toInt()); + number = item.at(1); + else if (!mask.isEmpty()) + number = QString("%1").arg(item.at(1).toInt(), mask.length(), 10, QChar('0')); + else if (type == "ten" || type == "tenfolio") + number = QString("%1").arg(item.at(1).toInt(), 2, 10, QChar('0')); + else if (type == "hundred" || type == "hundredfolio") + number = QString("%1").arg(item.at(1).toInt(), 3, 10, QChar('0')); + else number = QString::number(item.at(1).toInt()); list.append(number); } } diff --git a/sources/autoNum/numerotationcontext.cpp b/sources/autoNum/numerotationcontext.cpp index fe7200ab8..a8f3b11f4 100644 --- a/sources/autoNum/numerotationcontext.cpp +++ b/sources/autoNum/numerotationcontext.cpp @@ -52,13 +52,18 @@ void NumerotationContext::clear () @param increase the increase number of value @param initialvalue @param modulus wrap-and-carry modulus (0 means "not a wrapping part") + @param format zero-padding mask, spreadsheet style: "00" pads to two + digits, "000" to three. Empty keeps the part type's natural width, so + an absent format reproduces exactly the behaviour of every context + written before this field existed. @return true if value is append */ bool NumerotationContext::addValue(const QString &type, const QVariant &value, const int increase, const int initialvalue, - const int modulus) { + const int modulus, + const QString &format) { if (!keyIsAcceptable(type) && !value.canConvert()) return false; if (keyIsNumber(type) && !value.canConvert()) @@ -74,7 +79,9 @@ bool NumerotationContext::addValue(const QString &type, + "|" + QString::number(initialvalue) + "|" - + QString::number(modulus); + + QString::number(modulus) + + "|" + + QString(format).remove("|"); return true; } @@ -179,6 +186,9 @@ QDomElement NumerotationContext::toXml(QDomDocument &d, const QString& str) { if (strl.at(0) == ("wrap") && strl.size() > 4) { part.setAttribute("modulus", strl.at(4)); } + if (strl.size() > 5 && !strl.at(5).isEmpty()) { + part.setAttribute("format", strl.at(5)); + } num_auto.appendChild(part); } return num_auto; @@ -190,7 +200,7 @@ QDomElement NumerotationContext::toXml(QDomDocument &d, const QString& str) { */ void NumerotationContext::fromXml(QDomElement &e) { clear(); - foreach(QDomElement qde, QET::findInDomElement(e, "part")) addValue(qde.attribute("type"), qde.attribute("value"), qde.attribute("increase").toInt(), qde.attribute("initialvalue").toInt(), qde.attribute("modulus").toInt()); + foreach(QDomElement qde, QET::findInDomElement(e, "part")) addValue(qde.attribute("type"), qde.attribute("value"), qde.attribute("increase").toInt(), qde.attribute("initialvalue").toInt(), qde.attribute("modulus").toInt(), qde.attribute("format")); } /** @@ -206,5 +216,17 @@ void NumerotationContext::replaceValue(int index, QString content) { QString increase = strl.at(2); QString initvalue = strl.at(3); QString modulus = strl.size() > 4 ? strl.at(4) : QStringLiteral("0"); - content_[index] = type + "|" + value + "|" + increase + "|" + initvalue + "|" + modulus; + QString format = strl.size() > 5 ? strl.at(5) : QString(); + content_[index] = type + "|" + value + "|" + increase + "|" + initvalue + "|" + modulus + "|" + format; +} + +/** + @brief NumerotationContext::formatOf + @param item : a context item as returned by itemAt() + @return the part's zero-padding mask, or an empty string when it has + none -- which every context written before the field existed will be. +*/ +QString NumerotationContext::formatOf(const QStringList &item) +{ + return item.size() > 5 ? item.at(5) : QString(); } diff --git a/sources/autoNum/numerotationcontext.h b/sources/autoNum/numerotationcontext.h index dcc0139ea..f53c42751 100644 --- a/sources/autoNum/numerotationcontext.h +++ b/sources/autoNum/numerotationcontext.h @@ -37,7 +37,11 @@ class NumerotationContext const QVariant & = QVariant(1), const int = 1, const int = 0, - const int = 0); + const int = 0, + const QString & = QString()); + /// Zero-padding mask of a part, e.g. "00"; empty means the type's + /// own natural width. See addValue(). + static QString formatOf(const QStringList &item); QString operator[] (const int &) const; void operator << (const NumerotationContext &); int size() const; diff --git a/sources/autoNum/numerotationcontextcommands.cpp b/sources/autoNum/numerotationcontextcommands.cpp index 9b5536cb6..7e65d374e 100644 --- a/sources/autoNum/numerotationcontextcommands.cpp +++ b/sources/autoNum/numerotationcontextcommands.cpp @@ -259,7 +259,7 @@ NumerotationContext NumStrategy::nextString (const NumerotationContext &nc, { QStringList strl = nc.itemAt(i); NumerotationContext newnc; - newnc.addValue(strl.at(0), strl.at(1), strl.at(2).toInt()); + newnc.addValue(strl.at(0), strl.at(1), strl.at(2).toInt(), 0, 0, NumerotationContext::formatOf(strl)); return (newnc); } @@ -273,7 +273,7 @@ NumerotationContext NumStrategy::nextNumber (const NumerotationContext &nc, QStringList strl = nc.itemAt(i); NumerotationContext newnc; QString value = QString::number( (strl.at(1).toInt()) + (strl.at(2).toInt()) ); - newnc.addValue(strl.at(0), value, strl.at(2).toInt(), strl.at(3).toInt()); + newnc.addValue(strl.at(0), value, strl.at(2).toInt(), strl.at(3).toInt(), 0, NumerotationContext::formatOf(strl)); return (newnc); } @@ -287,7 +287,7 @@ NumerotationContext NumStrategy::previousNumber(const NumerotationContext &nc, QStringList strl = nc.itemAt(i); NumerotationContext newnc; QString value = QString::number( (strl.at(1).toInt()) - (strl.at(2).toInt()) ); - newnc.addValue(strl.at(0), value, strl.at(2).toInt(), strl.at(3).toInt()); + newnc.addValue(strl.at(0), value, strl.at(2).toInt(), strl.at(3).toInt(), 0, NumerotationContext::formatOf(strl)); return (newnc); } @@ -550,7 +550,7 @@ NumerotationContext WrapNum::next (const NumerotationContext &nc, const int i) c int new_value = strl.at(1).toInt() + increase; if (modulus > 0) new_value %= modulus; - newnc.addValue(strl.at(0), QString::number(new_value), increase, strl.at(3).toInt(), modulus); + newnc.addValue(strl.at(0), QString::number(new_value), increase, strl.at(3).toInt(), modulus, NumerotationContext::formatOf(strl)); return (newnc); } @@ -570,7 +570,7 @@ NumerotationContext WrapNum::previous(const NumerotationContext &nc, const int i if (new_value < 0) new_value += modulus; } - newnc.addValue(strl.at(0), QString::number(new_value), increase, strl.at(3).toInt(), modulus); + newnc.addValue(strl.at(0), QString::number(new_value), increase, strl.at(3).toInt(), modulus, NumerotationContext::formatOf(strl)); return (newnc); } @@ -706,7 +706,7 @@ NumerotationContext AlphaNum::next (const NumerotationContext &nc, const int i) { QStringList strl = nc.itemAt(i); NumerotationContext newnc; - newnc.addValue(strl.at(0), incrementAlpha(strl.at(1)), strl.at(2).toInt()); + newnc.addValue(strl.at(0), incrementAlpha(strl.at(1)), strl.at(2).toInt(), 0, 0, NumerotationContext::formatOf(strl)); return (newnc); } @@ -718,7 +718,7 @@ NumerotationContext AlphaNum::previous(const NumerotationContext &nc, const int { QStringList strl = nc.itemAt(i); NumerotationContext newnc; - newnc.addValue(strl.at(0), decrementAlpha(strl.at(1)), strl.at(2).toInt()); + newnc.addValue(strl.at(0), decrementAlpha(strl.at(1)), strl.at(2).toInt(), 0, 0, NumerotationContext::formatOf(strl)); return (newnc); } diff --git a/sources/autoNum/ui/numparteditorw.cpp b/sources/autoNum/ui/numparteditorw.cpp index 67300a1df..69db1a119 100644 --- a/sources/autoNum/ui/numparteditorw.cpp +++ b/sources/autoNum/ui/numparteditorw.cpp @@ -18,6 +18,8 @@ #include "numparteditorw.h" #include "ui_numparteditorw.h" +#include "../numerotationcontext.h" + #include /** @@ -35,6 +37,9 @@ NumPartEditorW::NumPartEditorW(int type, QWidget *parent) : { ui -> setupUi(this); setVisibleItems(); + //The mask is a run of zeros and nothing else, so it cannot be typed + //into a state the renderer would have to reject. + ui -> format_le -> setValidator(new QRegularExpressionValidator(QRegularExpression("0*"), this)); setType(NumPartEditorW::unit, true); } @@ -99,6 +104,7 @@ NumPartEditorW::NumPartEditorW (NumerotationContext &context, ui -> increase_spinBox -> setValue(strl.at(2).toInt()); if (strl.at(0)=="wrap" && strl.size() > 4) ui -> modulus_spinBox -> setValue(strl.at(4).toInt()); + ui -> format_le -> setText(NumerotationContext::formatOf(strl)); } } @@ -219,23 +225,30 @@ NumerotationContext NumPartEditorW::toNumContext() type_str = "alpha"; break; } + const QString number_format = ui -> format_le -> text(); if (type_str == "unitfolio" || type_str == "tenfolio" || type_str == "hundredfolio") nc.addValue(type_str, ui -> value_field -> displayText(), ui -> increase_spinBox -> value(), - ui->value_field->displayText().toInt()); + ui->value_field->displayText().toInt(), + 0, + number_format); else if (type_str == "wrap") nc.addValue(type_str, ui -> value_field -> displayText(), ui -> increase_spinBox -> value(), 0, - ui -> modulus_spinBox -> value()); + ui -> modulus_spinBox -> value(), + number_format); else nc.addValue(type_str, ui -> value_field -> displayText(), - ui -> increase_spinBox -> value()); + ui -> increase_spinBox -> value(), + 0, + 0, + number_format); return nc; } @@ -317,6 +330,14 @@ void NumPartEditorW::on_increase_spinBox_valueChanged(int) { @brief NumPartEditorW::on_modulus_spinBox_valueChanged emit changed when modulus_spinBox value changed */ +/** + @brief NumPartEditorW::on_format_le_textEdited + emit changed when the display format is edited +*/ +void NumPartEditorW::on_format_le_textEdited(const QString &) { + emit changed(); +} + void NumPartEditorW::on_modulus_spinBox_valueChanged(int) { if (!ui -> value_field -> text().isEmpty()) emit changed(); } @@ -423,6 +444,13 @@ void NumPartEditorW::setType(NumPartEditorW::type t, bool fnum) { if (t == wrap && ui -> modulus_spinBox -> value() <= 0) ui -> modulus_spinBox -> setValue(8); ui -> modulus_spinBox -> setEnabled(t == wrap); + //A padding mask only means anything for a part rendered as a number. + const bool numeric = (t == unit || t == unitfolio || t == ten + || t == tenfolio || t == hundred || t == hundredfolio + || t == wrap); + ui -> format_le -> setEnabled(numeric); + if (!numeric) + ui -> format_le -> clear(); type_= t; } diff --git a/sources/autoNum/ui/numparteditorw.h b/sources/autoNum/ui/numparteditorw.h index e33560aba..ce7d3ffae 100644 --- a/sources/autoNum/ui/numparteditorw.h +++ b/sources/autoNum/ui/numparteditorw.h @@ -66,6 +66,7 @@ class NumPartEditorW : public QWidget void on_value_field_textEdited(); void on_increase_spinBox_valueChanged(int); void on_modulus_spinBox_valueChanged(int); + void on_format_le_textEdited(const QString &); void setType (NumPartEditorW::type t, bool=false); signals: diff --git a/sources/autoNum/ui/numparteditorw.ui b/sources/autoNum/ui/numparteditorw.ui index bfc4fd9d2..15ee0cfa3 100644 --- a/sources/autoNum/ui/numparteditorw.ui +++ b/sources/autoNum/ui/numparteditorw.ui @@ -126,6 +126,28 @@ + + + + false + + + + 70 + 16777215 + + + + Format d'affichage : une suite de zéros donne le nombre minimum de chiffres (00 = 07, 000 = 007). Vide = largeur naturelle du type. + + + 0 + + + Qt::AlignCenter + + +