Reapply "Add cable management: drawing, cores, numbering, cross-references and cable list"

This reverts commit 2bb3343d2d.
This commit is contained in:
Laurent Trinques
2026-10-11 05:00:01 +02:00
parent 124a889be3
commit 1cd8fadbc4
113 changed files with 18793 additions and 209 deletions
+21 -2
View File
@@ -105,6 +105,16 @@ NumPartEditorW::NumPartEditorW (NumerotationContext &context,
if (strl.at(0)=="wrap" && strl.size() > 4)
ui -> modulus_spinBox -> setValue(strl.at(4).toInt());
ui -> format_le -> setText(NumerotationContext::formatOf(strl));
//A counter bound to the folio keeps the start it was
//configured with: value_field shows the live counter, and
//writing that back as the start would make every folio
//begin at the last number the previous numbering gave out
if ((strl.at(0)==QLatin1String("unitfolio")
|| strl.at(0)==QLatin1String("tenfolio")
|| strl.at(0)==QLatin1String("hundredfolio"))
&& strl.size() > 3 && !strl.at(3).isEmpty()) {
m_initial_value = strl.at(3).toInt();
}
}
}
@@ -131,8 +141,12 @@ void NumPartEditorW::setVisibleItems()
<< tr("Alphabetical")
<< tr("Text");
}
else if (m_edited_type == 1)
else if (m_edited_type == 1 || m_edited_type == 3)
{
//Type 3 is a cable: it is drawn along a folio just like a
//conductor is, so it takes the same kinds of variable and
//none of the ones an element has and a cable has not (its
//line, its column, its prefix).
items << tr("number format 1")
<< tr("number format 1 - Sheet")
<< tr("number format 01")
@@ -232,7 +246,8 @@ NumerotationContext NumPartEditorW::toNumContext()
nc.addValue(type_str,
ui -> value_field -> displayText(),
ui -> increase_spinBox -> value(),
ui->value_field->displayText().toInt(),
m_initial_value >= 0 ? m_initial_value
: ui->value_field->displayText().toInt(),
0,
number_format);
else if (type_str == "wrap")
@@ -315,6 +330,10 @@ void NumPartEditorW::on_type_cb_activated(int) {
*/
void NumPartEditorW::on_value_field_textEdited()
{
//What the user types in is a deliberate start for a counter
//bound to the folio; merely showing the live counter (as
//setContext() does) never changes the start.
m_initial_value = ui -> value_field -> text().toInt();
emit changed();
}
+8
View File
@@ -77,6 +77,14 @@ class NumPartEditorW : public QWidget
QValidator *intValidator;
QValidator *alphaValidator;
int m_edited_type = -1; ///<0 == element : 1 == conductor : 2 == folio
/**
The value a counter bound to the folio counts each folio
from (-1 while the row carries none): value_field shows
the live counter, which numbering a project over leaves
at the last number given out, so the start has to be
kept apart from what is on show.
*/
int m_initial_value = -1;
+25 -3
View File
@@ -37,22 +37,41 @@ QList<ElementAutoNumSchemeCommand::Scheme> PasteNumberingImport::copiedBy(const
elements follow and the project does not have.
@param parent : parent of the question
@param copied : the numberings the copy carries
@param extra : commands the copy brings beside the paste itself
(the cable lines of a fragment, for example); they are pushed inside
the same macro, so one Ctrl+Z undoes all of it at once.
*/
void PasteNumberingImport::push(QWidget *parent,
Diagram *diagram,
const DiagramContent &content,
const QList<ElementAutoNumSchemeCommand::Scheme> &copied)
const QList<ElementAutoNumSchemeCommand::Scheme> &copied,
const QList<QUndoCommand *> &extra)
{
QETProject *project = diagram->project();
auto *paste = new PasteDiagramCommand(diagram, content);
//The paste and the commands beside it are one step: only the
//macros really need more than the single push.
const auto push_all = [&]() {
if (extra.isEmpty()) {
diagram->undoStack().push(paste);
return;
}
diagram->undoStack().beginMacro(paste->text());
diagram->undoStack().push(paste);
for (QUndoCommand *cmd : extra) {
diagram->undoStack().push(cmd);
}
diagram->undoStack().endMacro();
};
QList<ElementAutoNumSchemeCommand::Scheme> missing;
if (project && !copied.isEmpty()
&& QSettings().value("diagramcommands/autonumber-pasted-elements", true).toBool()) {
missing = ElementAutoNumSchemeCommand::missingForPaste(project, copied, content.m_elements);
}
if (missing.isEmpty()) {
diagram->undoStack().push(paste);
push_all();
return;
}
@@ -71,7 +90,7 @@ void PasteNumberingImport::push(QWidget *parent,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes);
if (answer != QMessageBox::Yes) {
diagram->undoStack().push(paste);
push_all();
return;
}
@@ -91,5 +110,8 @@ void PasteNumberingImport::push(QWidget *parent,
}
}
diagram->undoStack().push(paste);
for (QUndoCommand *cmd : extra) {
diagram->undoStack().push(cmd);
}
diagram->undoStack().endMacro();
}
+8 -1
View File
@@ -23,6 +23,7 @@
#include <QCoreApplication>
#include <QList>
#include <QUndoCommand>
class Diagram;
class QWidget;
@@ -40,6 +41,11 @@ class QWidget;
without a numbering.
The import and the paste are one undo step.
A paste which brings more than itself (the cable lines of the copy,
for instance, which are no part of a DiagramContent) hands those
commands over through @p extra: they are pushed inside the very
same macro, so one Ctrl+Z still takes the whole of it back.
*/
class PasteNumberingImport
{
@@ -49,7 +55,8 @@ class PasteNumberingImport
static void push(QWidget *parent,
Diagram *diagram,
const DiagramContent &content,
const QList<ElementAutoNumSchemeCommand::Scheme> &copied);
const QList<ElementAutoNumSchemeCommand::Scheme> &copied,
const QList<QUndoCommand *> &extra = QList<QUndoCommand *>());
static QList<ElementAutoNumSchemeCommand::Scheme> copiedBy(const QDomDocument &clipboard);
};
+120 -2
View File
@@ -138,6 +138,9 @@ void SelectAutonumW::setContext(const NumerotationContext &context)
updatePartButtons();
applyEnable(false);
//Everything the rule held before is read now, so nothing of it
//is left to write: what is on show is what there is.
m_dirty = false;
}
/**
@@ -147,7 +150,11 @@ void SelectAutonumW::setContext(const NumerotationContext &context)
*/
void SelectAutonumW::insertPartRow(NumPartEditorW *part)
{
connect(part, &NumPartEditorW::changed, this, [this]() { applyEnable(); });
connect(part, &NumPartEditorW::changed, this, [this]() {
m_dirty = true;
applyEnable();
emit contextEdited();
});
PartRow r;
r.part = part;
@@ -263,7 +270,10 @@ NumerotationContext SelectAutonumW::toNumContext() const
void SelectAutonumW::on_add_button_clicked()
{
insertPartRow(new NumPartEditorW(m_edited_type, this));
m_dirty = true;
ui -> remove_button -> setEnabled(true);
applyEnable();
emit contextEdited();
}
/**
@@ -272,9 +282,16 @@ void SelectAutonumW::on_add_button_clicked()
*/
void SelectAutonumW::on_remove_button_clicked()
{
if (!m_rows.isEmpty()) {
//remove if @num_part_list contains more than one item
if (num_part_list_.size() > 1) {
m_dirty = true;
removePartRow(m_rows.last().row);
if (num_part_list_.size() == 1) {
ui -> remove_button -> setDisabled(true);
}
}
applyEnable();
emit contextEdited();
}
/**
@@ -296,6 +313,78 @@ QComboBox *SelectAutonumW::contextComboBox() const
return ui->m_comboBox;
}
/**
@brief SelectAutonumW::setSingleRuleMode
@param single true to show this editor as the one and only rule of
its kind.
The row which lists the available numberings -- its label, its combo
box and the button which deletes one -- is hidden, so there is
nothing to name a rule with and nothing to choose between: the rule
being edited is all there is. The combo box itself stays where it is
and keeps holding the rule's name, so everything which reads or
writes the rule through contextComboBox() carries on untouched; he
just cannot see it.
*/
void SelectAutonumW::setSingleRuleMode(bool single)
{
m_single_rule = single;
ui->label->setVisible(!single);
ui->m_comboBox->setVisible(!single);
ui->m_remove_pb->setVisible(!single);
//A single rule has no list to be deleted from, so it needs a
//button of its own to get out of the numbering again. It is
//only shown when there is really a rule to take away -- see
//setRuleRemovable.
if (single && !m_rule_remove_pb) {
m_rule_remove_pb = new QPushButton(tr("Delete the rule"), this);
m_rule_remove_pb->setToolTip(tr(
"Delete the cable numbering rule: cables are "
"numbered again as before, and the question of "
"defining one comes back on the next drawing."));
m_rule_remove_pb->setObjectName(QStringLiteral("m_rule_remove_pb"));
if (ui->m_definition_groupe && ui->m_definition_groupe->layout()) {
ui->m_definition_groupe->layout()->addWidget(m_rule_remove_pb);
}
connect(m_rule_remove_pb, &QPushButton::clicked,
this, &SelectAutonumW::removeClicked);
}
if (m_rule_remove_pb) {
m_rule_remove_pb->setVisible(m_single_rule && m_rule_removable);
}
}
/**
@brief SelectAutonumW::setRuleRemovable
Whether the button which takes the whole rule away is worth showing:
it has nothing to do while this editor holds no rule at all, and it
would only be a button which does nothing.
@param can_remove true when a rule is there to be taken away
*/
void SelectAutonumW::setRuleRemovable(bool can_remove)
{
m_rule_removable = can_remove;
if (m_rule_remove_pb) {
m_rule_remove_pb->setVisible(m_single_rule && can_remove);
}
}
/**
@brief SelectAutonumW::isValid
@return true when there is at least one variable in the editor and
every one of them holds what it needs. An editor which has only just
been opened holds an empty rule, and an empty rule is not one.
*/
bool SelectAutonumW::isValid()
{
if (num_part_list_.isEmpty()) return false;
for (NumPartEditorW *npe : num_part_list_) {
if (!npe || !npe->isValid()) return false;
}
return true;
}
/**
@brief SelectAutonumW::on_buttonBox_clicked
Action on button clicked
@@ -364,6 +453,32 @@ void SelectAutonumW::on_buttonBox_clicked(QAbstractButton *button)
));
break;
}
else if (m_edited_type == 3)
{
QMessageBox::information (
this,
tr("Cable Auto Numbering",
"title window"),
tr("This is where you can define how new cables will be numbered.\n"
"-A numbering is composed of a minimum variable.\n"
"-You can add or delete a dialing variable through the - and + buttons.\n"
"-A numbering variable includes: a type, a value and an increment.\n"
"\n-the \"Digit 1\", \"Digit 01\" and \"Digit 001\" types represent a numeric type defined in the \"Value\" field, "
"which is incremented to each new cable by the value of the \"Increment\" field.\n"
"-\"Digit 01\" and \"Digit 001\", are respectively represented on the diagram by two and three digits minimum.\n"
"If the digit defined in the Value field has fewer digits than the chosen type, it will be preceded by one or two 0s in "
"order to respect its type.\n"
"\n-Type \"Text\", represents a fixed text.\nThe \"Increment\" field is not used.\n"
"\n-The \"Sheet no.\" type represents the number of the current sheet.\nThe other fields are not used.\n"
"\n-The \"Sheet\" type represents the name of the current sheet.\nThe other fields are not used.",
"help dialog about the cable autonumerotation"
));
break;
}
else
{
QMessageBox::information (
@@ -397,6 +512,9 @@ void SelectAutonumW::on_buttonBox_clicked(QAbstractButton *button)
case QDialogButtonBox::ApplyRole:
applyEnable(false);
emit applyPressed();
//Whatever was edited is written now, so there is
//nothing of it left for a later save to write again.
m_dirty = false;
break;
};
}
+58 -1
View File
@@ -27,6 +27,7 @@ class NumPartEditorW;
class QAbstractButton;
class FormulaAutonumberingW;
class QComboBox;
class QPushButton;
class QToolButton;
class QHBoxLayout;
@@ -54,11 +55,55 @@ class SelectAutonumW : public QWidget
void contextToFormula ();
QString formula();
QComboBox *contextComboBox() const;
/**
Show this editor as the only numbering rule there is: the
row which lets several named numberings be kept and chosen
between is hidden, so the rule being edited is the one and
only. Everything else -- the definition itself, the buttons
around it -- stays exactly as it is for the other kinds.
*/
void setSingleRuleMode(bool single);
bool isSingleRuleMode() const { return m_single_rule; }
/**
True while everything the editor holds is filled in well
enough to be a rule -- no variable left with nothing in it.
The Apply button says the same thing; this is so that a page
which saves on its own way knows it too, rather than writing
a rule nobody has finished filling in.
*/
bool isValid();
/**
True while the rule on show has been touched since it was
read or since it was last applied: a page which saves on
its own way (the cable rule does) writes it only when there
is something to write, so that confirming a window with
nothing changed in it leaves the project alone.
*/
bool isModified() const { return m_dirty; }
/**
Show the button which takes the rule itself away, which is
the only way to stop numbering cables automatically again:
the row the other numberings delete from is hidden here, so
a single rule would have no way out at all. The page behind
the editor says whether there is a rule to take away at the
moment -- without one the button has nothing to do and is
kept out of sight.
@param can_remove true when a rule is really there
*/
void setRuleRemovable(bool can_remove);
void setExplicitNaming();
signals:
void applyPressed();
void removeClicked();
/**
Sent whenever what the rule holds is edited -- a
field of a part changed, a part added, a part taken
away -- so that a window holding this editor can let
its own buttons say whether there is something to
write now.
*/
void contextEdited();
/// Only with setExplicitNaming()
void newClicked();
void renameClicked();
@@ -96,7 +141,19 @@ class SelectAutonumW : public QWidget
NumerotationContext m_context;
FormulaAutonumberingW *m_feaw;
FormulaAutonumberingW *m_fcaw;
int m_edited_type = -1; ///<0 == element : 1 == conductor : 2 == folio
int m_edited_type = -1; ///<0 == element : 1 == conductor : 2 == folio : 3 == cable
///< when true, the row of available numberings is hidden and
///< this editor holds the one rule there is (see setSingleRuleMode)
bool m_single_rule = false;
///< true from the moment the rule on show is touched until
///< it is read again or applied (see isModified)
bool m_dirty = false;
///< the button which takes the whole rule away, built for
///< the one kind of numbering which has no list to delete
///< it from (see setRuleRemovable)
QPushButton *m_rule_remove_pb = nullptr;
///< whether such a rule is there to be taken away
bool m_rule_removable = false;
};
#endif // SELECTAUTONUMW_H