mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-11 14:44:15 +02:00
Reapply "Add cable management: drawing, cores, numbering, cross-references and cable list"
This reverts commit 2bb3343d2d.
This commit is contained in:
@@ -649,6 +649,74 @@ namespace autonum
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief resetFolioCounters
|
||||
@param nc the rule to read
|
||||
@return the same rule, with the parts whose counter belongs to a
|
||||
single folio put back to the beginning that folio is numbered
|
||||
from -- the initial value the rule carries for it -- while the
|
||||
parts counting over the whole project are left alone
|
||||
*/
|
||||
NumerotationContext resetFolioCounters(const NumerotationContext &nc)
|
||||
{
|
||||
NumerotationContext out = nc;
|
||||
for (int i = 0; i < out.size(); ++i)
|
||||
{
|
||||
const QStringList parts = out.itemAt(i);
|
||||
if (parts.isEmpty()) continue;
|
||||
|
||||
const QString &type = parts.at(0);
|
||||
if (type == QLatin1String("unitfolio")
|
||||
|| type == QLatin1String("tenfolio")
|
||||
|| type == QLatin1String("hundredfolio"))
|
||||
{
|
||||
//The beginning a folio is numbered from is the one
|
||||
//written into the rule, never a hard 1: a counter
|
||||
//starting at 5 starts every folio at 5.
|
||||
const bool has_start = parts.size() > 3
|
||||
&& !parts.at(3).isEmpty();
|
||||
out.replaceValue(i, has_start ? parts.at(3)
|
||||
: QStringLiteral("1"));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief resetContextCounters
|
||||
@param nc the rule to read
|
||||
@return the same rule, with every part which counts set back to
|
||||
the value it started from
|
||||
*/
|
||||
NumerotationContext resetContextCounters(const NumerotationContext &nc)
|
||||
{
|
||||
NumerotationContext out = resetFolioCounters(nc);
|
||||
for (int i = 0; i < out.size(); ++i)
|
||||
{
|
||||
const QStringList parts = out.itemAt(i);
|
||||
if (parts.isEmpty()) continue;
|
||||
|
||||
const QString &type = parts.at(0);
|
||||
if (type == QLatin1String("unit")
|
||||
|| type == QLatin1String("ten")
|
||||
|| type == QLatin1String("hundred"))
|
||||
{
|
||||
out.replaceValue(i, QStringLiteral("1"));
|
||||
}
|
||||
else if (type == QLatin1String("wrap"))
|
||||
{
|
||||
//A cyclic part walks over [0, modulus), so it goes
|
||||
//back to 0 rather than to 1
|
||||
out.replaceValue(i, QStringLiteral("0"));
|
||||
}
|
||||
else if (type == QLatin1String("alpha"))
|
||||
{
|
||||
out.replaceValue(i, QStringLiteral("a"));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief numerotationContextToFormula
|
||||
@param nc
|
||||
|
||||
@@ -117,6 +117,31 @@ namespace autonum
|
||||
void setFolioSequentialToHash(QStringList &list, QHash<QString, QStringList> &hash, const QString& autoNumName);
|
||||
void setSequential(const QString& label, autonum::sequentialNumbers &seqStruct, NumerotationContext &context, Diagram *diagram, const QString& hashKey);
|
||||
QString numerotationContextToFormula(const NumerotationContext &nc);
|
||||
/**
|
||||
Put back every part of a numbering rule whose counter belongs to
|
||||
one single folio -- "Chiffre 1 - Folio" and its two longer forms
|
||||
-- to the beginning that folio is numbered from, which is the
|
||||
initial value written into the rule itself. The parts which count
|
||||
over the whole project are left exactly as they are: a folio
|
||||
starts again, the project does not.
|
||||
@param nc the rule to read
|
||||
@return the same rule, with its folio-bound counters restarted
|
||||
*/
|
||||
NumerotationContext resetFolioCounters(const NumerotationContext &nc);
|
||||
/**
|
||||
Set every part of a numbering rule which counts back to its very
|
||||
first value, so that numbering starts at the beginning again --
|
||||
which is what numbering a whole project over has to do, whatever
|
||||
the last number handed out happened to be. A part which counts
|
||||
from an initial value of its own goes back to that value, a plain
|
||||
number goes back to 1, a cyclic one to 0 and an alphabetic one to
|
||||
"a". The parts which do not count -- a fixed text, the number of
|
||||
the folio, the plant -- are left exactly as they are: they say
|
||||
what a number is made of, they are not the part which goes on.
|
||||
@param nc the rule to read
|
||||
@return the same rule, with its counters at their beginning
|
||||
*/
|
||||
NumerotationContext resetContextCounters(const NumerotationContext &nc);
|
||||
QString elementPrefixForLocation(const ElementsLocation &location);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user