mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-11 22:54:12 +02:00
Revert "Add cable management: drawing, cores, numbering, cross-references and cable list"
This commit is contained in:
@@ -1,383 +0,0 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cablenumberingdialog.h"
|
||||
|
||||
#include "../autoNum/ui/selectautonumw.h"
|
||||
#include "../cable/cablerenumber.h"
|
||||
#include "../cable/editcablecommand.h"
|
||||
#include "../qetproject.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QUndoStack>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::CableNumberingDialog
|
||||
Build the window around the numbering rule of the project: the rule
|
||||
itself, the axis the cables are laid out along when the whole
|
||||
project is numbered again, and the button which does that numbering.
|
||||
@param project the project whose cables are numbered
|
||||
@param parent
|
||||
*/
|
||||
CableNumberingDialog::CableNumberingDialog(QETProject *project, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_project(project)
|
||||
{
|
||||
setWindowTitle(tr("Cable numbering"));
|
||||
//The rule editor needs room to be read: this window opens with
|
||||
//the size it needs rather than with whatever its contents
|
||||
//happen to add up to, so nothing of the rule is cramped from
|
||||
//the first moment
|
||||
setMinimumSize(QSize(900, 620));
|
||||
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
|
||||
auto *note = new QLabel(tr(
|
||||
"This window shows the automatic numbering rule for the cables "
|
||||
"of this project and edits it. A rule changed here is the one "
|
||||
"the project keeps: it is written into the project when you "
|
||||
"apply it."), this);
|
||||
note->setWordWrap(true);
|
||||
layout->addWidget(note);
|
||||
|
||||
m_rule = new SelectAutonumW(3, this);
|
||||
//One rule only, so the row which picks between several named
|
||||
//numberings is hidden: what is on show is the project's rule
|
||||
m_rule->setSingleRuleMode(true);
|
||||
layout->addWidget(m_rule);
|
||||
|
||||
auto *axis_group = new QGroupBox(tr("Axis priority"), this);
|
||||
auto *axis_layout = new QHBoxLayout(axis_group);
|
||||
m_axis_x = new QRadioButton(tr("Priority to the X axis (horizontal)"), axis_group);
|
||||
m_axis_y = new QRadioButton(tr("Priority to the Y axis (vertical)"), axis_group);
|
||||
axis_layout->addWidget(m_axis_x);
|
||||
axis_layout->addWidget(m_axis_y);
|
||||
layout->addWidget(axis_group);
|
||||
|
||||
auto *axis_note = new QLabel(tr(
|
||||
"The chosen axis decides the order in which the cables are "
|
||||
"renumbered: X numbers them from left to right, Y numbers them "
|
||||
"from top to bottom."), this);
|
||||
axis_note->setWordWrap(true);
|
||||
layout->addWidget(axis_note);
|
||||
|
||||
auto *actions = new QHBoxLayout();
|
||||
m_renumber_pb = new QPushButton(tr("Renumber all cables"), this);
|
||||
m_renumber_pb->setToolTip(tr(
|
||||
"Sets the number of each cable of the project again from the "
|
||||
"rule, starting at the beginning: a number left missing after "
|
||||
"a cable is deleted is filled in this way."));
|
||||
actions->addWidget(m_renumber_pb);
|
||||
actions->addStretch();
|
||||
|
||||
//No confirm button: this window is there to number the cables
|
||||
//again and to show the rule which does it. What the window
|
||||
//holds is written by the editor's own Apply button, and by the
|
||||
//numbering button which writes it before numbering -- so a
|
||||
//second button only saving and closing would say the same
|
||||
//thing twice.
|
||||
m_box = new QDialogButtonBox(this);
|
||||
m_box->addButton(QDialogButtonBox::Cancel);
|
||||
m_box->button(QDialogButtonBox::Cancel)->setText(tr("Cancel"));
|
||||
actions->addWidget(m_box);
|
||||
layout->addLayout(actions);
|
||||
|
||||
connect(m_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
connect(m_renumber_pb, &QPushButton::clicked, this, &CableNumberingDialog::renumber);
|
||||
//The editor's own buttons are wired the same way the project
|
||||
//properties wire them, so this window saves exactly what that
|
||||
//page would have saved
|
||||
connect(m_rule, &SelectAutonumW::applyPressed, this, &CableNumberingDialog::applyRule);
|
||||
connect(m_rule, &SelectAutonumW::removeClicked, this, &CableNumberingDialog::removeRule);
|
||||
//Filling a rule in lights the numbering button up as soon as
|
||||
//there is something to number with
|
||||
connect(m_rule, &SelectAutonumW::contextEdited, this,
|
||||
&CableNumberingDialog::updateEnabling);
|
||||
|
||||
if (m_project)
|
||||
{
|
||||
const QString key = m_project->cableCurrentAutoNum();
|
||||
const bool has_rule = !key.isEmpty()
|
||||
&& !m_project->cableAutoNum(key).isEmpty();
|
||||
m_rule->setContext(has_rule ? m_project->cableAutoNum(key)
|
||||
: NumerotationContext());
|
||||
//The button which takes the rule away is only worth showing
|
||||
//when there is one, and only while the project may be
|
||||
//written to
|
||||
m_rule->setRuleRemovable(has_rule && !m_project->isReadOnly());
|
||||
|
||||
m_axis_x->setChecked(m_project->cableXAxisFirst());
|
||||
m_axis_y->setChecked(!m_project->cableXAxisFirst());
|
||||
|
||||
if (m_project->isReadOnly())
|
||||
{
|
||||
m_rule->setEnabled(false);
|
||||
m_axis_x->setEnabled(false);
|
||||
m_axis_y->setEnabled(false);
|
||||
}
|
||||
}
|
||||
updateEnabling();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::applyRule
|
||||
What the editor's own Apply button does: write the rule into the
|
||||
project and leave the window open, the way that button behaves on
|
||||
the numbering pages of the settings.
|
||||
*/
|
||||
void CableNumberingDialog::applyRule()
|
||||
{
|
||||
save();
|
||||
updateEnabling();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::save
|
||||
Write the rule and the axis into the project. Nothing is written
|
||||
when nothing was changed, so confirming a window which was only
|
||||
ever looked at leaves the project exactly as it was.
|
||||
@return true when the window holds nothing which could not be written
|
||||
*/
|
||||
bool CableNumberingDialog::save()
|
||||
{
|
||||
if (!m_project || m_project->isReadOnly()) return false;
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if (m_rule->isModified())
|
||||
{
|
||||
if (!m_rule->isValid())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cable numbering"),
|
||||
tr("The rule is not complete yet: "
|
||||
"there is still an empty field in it."));
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString title = QETProject::cableAutoNumRuleName();
|
||||
m_project->addCableAutoNum(title, m_rule->toNumContext());
|
||||
m_project->setCurrentCableAutoNum(title);
|
||||
//What was edited is written now, so there is nothing of it
|
||||
//left for a second save to write again
|
||||
m_rule->setContext(m_rule->toNumContext());
|
||||
m_rule->setRuleRemovable(true);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
const bool axis_first = m_axis_x->isChecked();
|
||||
if (m_project->cableXAxisFirst() != axis_first) changed = true;
|
||||
m_project->setCableXAxisFirst(axis_first);
|
||||
|
||||
if (changed) m_project->setModified(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::removeRule
|
||||
Take the cable numbering rule out of the project. The project then
|
||||
numbers its cables by no rule at all -- they are called W until one
|
||||
is defined again -- and the cable tool asks once more whether one
|
||||
should be defined.
|
||||
*/
|
||||
void CableNumberingDialog::removeRule()
|
||||
{
|
||||
if (!m_project || m_project->isReadOnly()) return;
|
||||
|
||||
const QString title = m_project->cableCurrentAutoNum();
|
||||
if (title.isEmpty()) return;
|
||||
|
||||
m_project->removeCableAutoNum(title);
|
||||
m_rule->setContext(NumerotationContext());
|
||||
//No rule left, so the button which takes one away goes too. And
|
||||
//having just taken the rule away means numbering cables by hand
|
||||
//again: the question of defining one comes back the next time a
|
||||
//cable is drawn, so it is not held back in this project any more.
|
||||
m_rule->setRuleRemovable(false);
|
||||
m_project->setCableAskNumbering(true);
|
||||
m_project->setModified(true);
|
||||
updateEnabling();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::updateEnabling
|
||||
Renumbering needs something to number with: a rule filled in well
|
||||
enough to be one, and a project which may be written to.
|
||||
*/
|
||||
void CableNumberingDialog::updateEnabling()
|
||||
{
|
||||
if (!m_project || m_project->isReadOnly() || !m_rule) {
|
||||
m_renumber_pb->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const QString key = m_project->cableCurrentAutoNum();
|
||||
const bool saved_rule = !key.isEmpty()
|
||||
&& !m_project->cableAutoNum(key).isEmpty();
|
||||
//A rule which is still being filled in counts as soon as it is
|
||||
//written, and the numbering writes it together with the numbers
|
||||
//it hands out
|
||||
const bool drawn_rule = m_rule->isModified() && m_rule->isValid()
|
||||
&& !m_rule->toNumContext().isEmpty();
|
||||
|
||||
m_renumber_pb->setEnabled((saved_rule || drawn_rule)
|
||||
&& m_rule->isValid()
|
||||
&& !m_rule->toNumContext().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::askAboutHandWritten
|
||||
Some cables carry a name he typed in himself rather than one the
|
||||
rule handed out. Taking such a name away is his to allow: yes and
|
||||
they are numbered like all the others, no and they keep their name
|
||||
while the rest is numbered around them, and cancelling leaves every
|
||||
cable exactly where it stands.
|
||||
@param count how many such names the project holds
|
||||
@return 1 to number them too, 0 to leave them alone, -1 for nothing
|
||||
*/
|
||||
int CableNumberingDialog::askAboutHandWritten(int count)
|
||||
{
|
||||
if (count <= 0) return 1;
|
||||
|
||||
QMessageBox box(QMessageBox::Question, tr("Cable numbering"),
|
||||
tr("%n cable(s) of this project were entered by "
|
||||
"hand.\n\n"
|
||||
"Do you want to renumber them too?", "", count),
|
||||
QMessageBox::NoButton, this);
|
||||
QPushButton *take = box.addButton(
|
||||
tr("Yes", "Les noms saisis à la main sont remplacés eux aussi."),
|
||||
QMessageBox::YesRole);
|
||||
QPushButton *leave = box.addButton(
|
||||
tr("No", "Les noms saisis à la main sont laissés tels quels."),
|
||||
QMessageBox::NoRole);
|
||||
QPushButton *cancel = box.addButton(
|
||||
tr("Cancel", "Ne renumérote rien du tout."),
|
||||
QMessageBox::RejectRole);
|
||||
//Keeping his own names is the safe answer under his finger
|
||||
box.setDefaultButton(leave);
|
||||
box.setEscapeButton(cancel);
|
||||
box.exec();
|
||||
|
||||
const QAbstractButton *clicked = box.clickedButton();
|
||||
if (clicked == take) return 1;
|
||||
if (clicked == leave) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief CableNumberingDialog::renumber
|
||||
Number every cable of the project again with the rule on show,
|
||||
from the beginning of that rule and in the order the cables stand
|
||||
along the chosen axis. One single undo step takes it all back, and
|
||||
the window closes once the numbering has been written so that he
|
||||
can see what became of his cables.
|
||||
*/
|
||||
void CableNumberingDialog::renumber()
|
||||
{
|
||||
if (!m_project || m_project->isReadOnly()) return;
|
||||
|
||||
//A rule which is not complete yet is refused before anything is
|
||||
//worked out at all. What the window holds is written only together
|
||||
//with the numbering itself, so every way out coming before that
|
||||
//point -- a rule which does not fit, him saying no, nothing to
|
||||
//number -- leaves the project exactly as it stands.
|
||||
const NumerotationContext rule = m_rule->toNumContext();
|
||||
if (!m_rule->isValid() || rule.isEmpty())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cable numbering"),
|
||||
tr("The rule is not complete yet."));
|
||||
return;
|
||||
}
|
||||
const bool axis_first = m_axis_x->isChecked();
|
||||
|
||||
//Whether he lets his own names be taken away or not, a project
|
||||
//with nothing to number with says so before he is asked
|
||||
//anything: the rule has to be one first
|
||||
CableRenumberPlan plan = CableRenumber::plan(m_project, rule, axis_first,
|
||||
true);
|
||||
if (!plan.ok())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cable numbering"), plan.error);
|
||||
return;
|
||||
}
|
||||
|
||||
const int answer = askAboutHandWritten(CableRenumber::byHandCount(m_project));
|
||||
if (answer < 0) return;
|
||||
|
||||
//Leaving his own names alone means the numbering runs around
|
||||
//them, which can hand out a number somebody else keeps: that
|
||||
//is worked out again here and refused if it does not fit
|
||||
if (answer == 0)
|
||||
{
|
||||
plan = CableRenumber::plan(m_project, rule, axis_first, false);
|
||||
if (!plan.ok())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cable numbering"), plan.error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (plan.cables.isEmpty())
|
||||
{
|
||||
QMessageBox::information(this, tr("Cable numbering"),
|
||||
tr("No cable to renumber in this project."));
|
||||
return;
|
||||
}
|
||||
|
||||
//Every cable already carries the number the rule says: there is
|
||||
//nothing to write, and an undo step which undoes nothing would
|
||||
//only be in the way
|
||||
bool changed = false;
|
||||
for (int i = 0; i < plan.cables.size(); ++i)
|
||||
{
|
||||
if (plan.cables.at(i)->designation() != plan.designations.at(i)
|
||||
|| plan.cables.at(i)->designationByHand()) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!changed)
|
||||
{
|
||||
QMessageBox::information(this, tr("Cable numbering"),
|
||||
tr("All the cables already carry the number "
|
||||
"that the rule gives them."));
|
||||
return;
|
||||
}
|
||||
|
||||
//The rule on show is written now, right with the numbering it
|
||||
//belongs to, and the numbering then leaves the counters of that
|
||||
//rule where the last number was taken from: both go into the
|
||||
//project with the names, as one single act which undo takes
|
||||
//back together. Nothing was written before this point, which is
|
||||
//why he may still back out of here without the project having
|
||||
//been touched.
|
||||
if (!save()) return;
|
||||
|
||||
const QString num_key = QETProject::cableAutoNumRuleName();
|
||||
if (QUndoStack *stack = m_project->undoStack()) {
|
||||
stack->push(new RenumberCablesCommand(
|
||||
plan.cables, plan.designations, m_project, num_key,
|
||||
m_project->cableAutoNum(num_key), plan.after));
|
||||
}
|
||||
accept();
|
||||
}
|
||||
Reference in New Issue
Block a user