Add a Target column to the terminal strip editor

Reading where a cable lands meant going back to the drawing: the strip
editor said which cable a terminal carries and which core, but never
what the cable goes to. A single core (1x16) could not be followed
from the terminal to its piece at all.

The new Target column names it: Installation, Location and Label (BMK)
of the piece the wires land on, past this strip, joined in one line --
the very three fields the strip drawing writes in the box under its
cable, in the same order (RealTerminal::cableTarget()). It is worked
out of the project like the Cable cells and so follows their rule: a
target the drawing names is read only, for only the drawing decides
it, and a cell nothing is worked out for takes an edit, so a target
the drawing cannot find -- a cable landing on a piece with no
Installation, Location nor Label set, a cable going to another strip
-- is still worth naming by hand. The text typed in is stored in the
element (RealTerminal::cableTargetInfoKey()) and kept until a cable
works a target out again, and back once that cable goes, exactly like
a cable designation typed by hand: the automatic value is never
written, so no stale text can be left behind. The column takes the
width of its own text, so a long Installation is never cut off.

A text typed in is written the way the fields are shown in the column,
"Installation / Location / Label", and gives one line per field: the
box under the cable draws three lines without any slash in them, just
like a target worked out from the project, instead of one long line
carrying its separators as text.

tst_terminalcableauto checks the column is empty -- and editable --
without a cable, reads "Plant 7 / Cabinet 7 / -S7" with one, goes
empty -- and editable again -- when the core is removed, takes no edit
while the drawing names the target, and is headed "Target"; a second
case checks a target typed in by hand is taken by the cell, stored by
Apply, shown again by a fresh model, set aside for the read only
target of the drawing once a cable lands somewhere worth naming, and
back once that cable goes; a third one the line per field. tst_cable
target paints a strip whose cable ends on one field and the same strip
ending on three, the second box two lines deeper than the first.
This commit is contained in:
Kellermorph
2026-10-20 10:49:24 +02:00
parent 6e83012109
commit dc92a57873
8 changed files with 512 additions and 28 deletions
+52 -1
View File
@@ -407,6 +407,57 @@ bool RealTerminal::isShield() const {
/**
* @brief RealTerminal::cableTarget
* Where the cable of this terminal goes at its far end: the lines to
* write in the box under the cable. What the project itself says when
* a cable lands on a piece (see automaticCableTarget()), and the text
* typed in by hand when none does -- the Target cell of the terminal
* strip editor is read only in the first case, so a target the drawing
* cannot work out is still worth naming by hand. A text typed in is
* written the way the fields are shown in the column,
* "Installation / Location / Label", and gives one line per field.
* @return the lines to write in the box under the cable
*/
QVector<QString> RealTerminal::cableTarget() const
{
const auto automatic_{automaticCableTarget()};
if (!automatic_.isEmpty()) {
return automatic_;
}
if (hasData())
{
const auto typed_{terminalData().m_informations
.value(cableTargetInfoKey()).toString()};
if (!typed_.isEmpty())
{
//Written the way the fields are shown in the column,
//"Installation / Location / Label": the box draws one line
//per field, without the separators, like it does for a
//target worked out from the project
QVector<QString> lines_;
for (const QString &field_
: typed_.split(QStringLiteral(" / "), Qt::SkipEmptyParts)) {
lines_ << field_;
}
return lines_;
}
}
return QVector<QString>();
}
/**
* @brief RealTerminal::cableTargetIsAutomatic
* @return true when the target of this terminal is worked out from the
* project -- one of its cables lands on a piece worth naming -- and
* false when only a text typed in by hand is there to show.
*/
bool RealTerminal::cableTargetIsAutomatic() const
{
return !automaticCableTarget().isEmpty();
}
/**
* @brief RealTerminal::automaticCableTarget
* Where the cable of this terminal goes at its far end: the
* Installation, Location and Label (BMK) of the first piece the
* wires of the cable land on, past the strip's own terminals, in
@@ -420,7 +471,7 @@ bool RealTerminal::isShield() const {
* its name among the cables of the project.
* @return the lines to write in the box under the cable
*/
QVector<QString> RealTerminal::cableTarget() const
QVector<QString> RealTerminal::automaticCableTarget() const
{
if (m_spare || m_element.isNull()) {
return QVector<QString>();
+10
View File
@@ -55,6 +55,11 @@ class RealTerminal
void setPhysicalTerminal(const QSharedPointer<PhysicalTerminal> &phy_t);
///Where the wires of a cable land, worked out from the project:
///empty when no cable lands on a piece worth naming (cableTarget()
///then falls back on the text typed in by hand).
QVector<QString> automaticCableTarget() const;
public:
~RealTerminal();
static QSharedPointer<RealTerminal> createSpare(const ElementData &data, const QUuid &uuid = QUuid());
@@ -76,6 +81,9 @@ class RealTerminal
bool cableIsAutomatic() const;
bool isShield() const;
QVector<QString> cableTarget() const;
///True when cableTarget() is worked out from the project (read only),
///false when it is the text typed in by hand (which may be edited)
bool cableTargetIsAutomatic() const;
QColor color() const;
QColor stripeColor() const;
qreal section() const;
@@ -86,6 +94,8 @@ class RealTerminal
//Keys used to store the cable data in the element informations
static QString cableInfoKey() { return QStringLiteral("terminal_cable"); }
static QString cableWireInfoKey() { return QStringLiteral("terminal_cable_wire"); }
//Target typed in by hand, only read when the cables give none
static QString cableTargetInfoKey() { return QStringLiteral("terminal_cable_target"); }
static QString shieldInfoKey() { return QStringLiteral("terminal_shield"); }
//Keys used to store the color and the section (mm2) of the terminal
static QString colorInfoKey() { return QStringLiteral("terminal_color"); }
@@ -20,11 +20,30 @@
#include <QColor>
#include <QString>
#include <QStringList>
#include "../../qetgraphicsitem/element.h"
#include "../realterminal.h"
struct modelRealTerminalData
{
///The Installation, Location and Label (BMK) of the piece the cable
///lands on, joined in one line : what the strip draws in the box
///under its cable (RealTerminal::cableTarget), in the same order.
///A target typed in by hand is one single line, and nothing is
///shown when the cable lands on nothing worth naming and no text
///was ever written in.
static QString targetText(const QVector<QString> &target_)
{
QStringList fields_;
for (const QString &field_ : target_)
{
if (!field_.isEmpty()) {
fields_ << field_;
}
}
return fields_.join(QStringLiteral(" / "));
}
static modelRealTerminalData data(const QSharedPointer<RealTerminal> &real_t)
{
modelRealTerminalData mrtd;
@@ -35,6 +54,8 @@ struct modelRealTerminalData
mrtd.Xref_ = real_t->Xref();
mrtd.cable_ = real_t->cable();
mrtd.cable_wire = real_t->cableWire();
mrtd.cable_target_ = targetText(real_t->cableTarget());
mrtd.cable_target_auto_ = real_t->cableTargetIsAutomatic();
mrtd.cable_auto_ = real_t->cableIsAutomatic();
mrtd.conductor_ = real_t->conductor();
mrtd.led_ = real_t->isLed();
@@ -61,6 +82,11 @@ struct modelRealTerminalData
QString Xref_;
QString cable_;
QString cable_wire;
//Where the cable lands, past this strip : Installation / Location / Label
QString cable_target_;
//True when cable_target_ comes from the project (read only),
//false when it is empty or was typed in by hand (editable)
bool cable_target_auto_ = false;
bool cable_auto_ = false; //True when cable_ and cable_wire come from the cables of the project
QString conductor_;
bool led_ = false;
@@ -249,6 +249,10 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
{
m_model = new TerminalStripModel{strip_, this};
ui->m_table_widget->setModel(m_model);
//The Target column is worked out from the drawing: it takes
//the width of its own text, never a cut off Installation
ui->m_table_widget->horizontalHeader()->setSectionResizeMode(
TerminalStripModel::CableTarget, QHeaderView::ResizeToContents);
m_model->buildBridgePixmap(setUpBridgeCellWidth());
connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged);
}
@@ -335,6 +339,12 @@ void TerminalStripEditor::apply()
if (!data_.cable_auto_) {
set_info(RealTerminal::cableInfoKey(), data_.cable_);
set_info(RealTerminal::cableWireInfoKey(), data_.cable_wire);
}
//The same for the target: a target worked out from the
//project is never written in the element, only the one
//typed in by hand is stored
if (!data_.cable_target_auto_) {
set_info(RealTerminal::cableTargetInfoKey(), data_.cable_target_);
}
set_info(RealTerminal::shieldInfoKey(), data_.shield_ ? QStringLiteral("true") : QString());
//The color and the section are stored with the dot as decimal separator, whatever the locale
@@ -790,7 +800,8 @@ void TerminalStripEditor::on_m_led_cb_activated(int index)
namespace {
/**
* @return true if the cell at @a index contain a free text
* (label, cable, wire of the cable, color, section or width), so a text can be pasted in it.
* (label, cable, wire of the cable, target of the cable, color, section
* or width), so a text can be pasted in it.
*/
bool cellAcceptText(const QModelIndex &index)
{
@@ -798,6 +809,7 @@ bool cellAcceptText(const QModelIndex &index)
return column_ == TerminalStripModel::Label
|| column_ == TerminalStripModel::Cable
|| column_ == TerminalStripModel::CableWire
|| column_ == TerminalStripModel::CableTarget
|| column_ == TerminalStripModel::Color
|| column_ == TerminalStripModel::Section
|| column_ == TerminalStripModel::Width;
+47 -17
View File
@@ -48,16 +48,17 @@ const int CONDUCTOR_CELL = 7;
const int XREF_CELL = 8;
const int CABLE_CELL = 9;
const int CABLE_WIRE_CELL = 10;
const int TYPE_CELL = 11;
const int FUNCTION_CELL = 12;
const int LED_CELL = 13;
const int SHIELD_CELL = 14;
const int COLOR_CELL = 15;
const int SECTION_CELL = 16;
const int WIDTH_CELL = 17;
const int SEPARATOR_CELL = 18;
const int CABLE_TARGET_CELL = 11;
const int TYPE_CELL = 12;
const int FUNCTION_CELL = 13;
const int LED_CELL = 14;
const int SHIELD_CELL = 15;
const int COLOR_CELL = 16;
const int SECTION_CELL = 17;
const int WIDTH_CELL = 18;
const int SEPARATOR_CELL = 19;
const int COLUMN_COUNT = 19;
const int COLUMN_COUNT = 20;
static QVector<bool> UNMODIFIED_CELL_VECTOR(COLUMN_COUNT, false);
@@ -132,14 +133,15 @@ TerminalStripModel::Column TerminalStripModel::columnTypeForIndex(const QModelIn
case 8 : return XRef;
case 9 : return Cable;
case 10 : return CableWire;
case 11 : return Type;
case 12 : return Function;
case 13 : return Led;
case 14 : return Shield;
case 15 : return Color;
case 16 : return Section;
case 17 : return Width;
case 18 : return Separator;
case 11 : return CableTarget;
case 12 : return Type;
case 13 : return Function;
case 14 : return Led;
case 15 : return Shield;
case 16 : return Color;
case 17 : return Section;
case 18 : return Width;
case 19 : return Separator;
default : return Invalid;
}
}
@@ -215,6 +217,7 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
case XREF_CELL : return mrtd.spare_ ? tr("Spare") : mrtd.Xref_;
case CABLE_CELL : return mrtd.cable_;
case CABLE_WIRE_CELL : return mrtd.cable_wire;
case CABLE_TARGET_CELL : return mrtd.cable_target_;
case TYPE_CELL : return ElementData::translatedTerminalType(mrtd.type_);
case FUNCTION_CELL : return ElementData::translatedTerminalFunction(mrtd.function_);
case COLOR_CELL : return TerminalColor::displayName(mrtd.color_, mrtd.stripe_color_);
@@ -235,6 +238,7 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
case LABEL_CELL : return mrtd.label_;
case CABLE_CELL : return mrtd.cable_;
case CABLE_WIRE_CELL : return mrtd.cable_wire;
case CABLE_TARGET_CELL : return mrtd.cable_target_;
case COLOR_CELL : return TerminalColor::toSpec(mrtd.color_, mrtd.stripe_color_);
case SECTION_CELL : return mrtd.section_ > 0 ? QLocale().toString(mrtd.section_, 'g', 6) : QString();
case WIDTH_CELL : return mrtd.width_mm_ > 0 ? QLocale().toString(mrtd.width_mm_, 'g', 6) : QString();
@@ -309,6 +313,10 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value
&& mrtd.cable_auto_) {
return false;
}
if (column_ == CABLE_TARGET_CELL
&& mrtd.cable_target_auto_) {
return false;
}
if (column_ == LEVEL_CELL &&
role == Qt::EditRole)
@@ -361,6 +369,14 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value
modified_ = true;
modified_cell = CABLE_WIRE_CELL;
}
else if (column_ == CABLE_TARGET_CELL &&
role == Qt::EditRole &&
mrtd.cable_target_ != value.toString())
{
mrtd.cable_target_ = value.toString();
modified_ = true;
modified_cell = CABLE_TARGET_CELL;
}
else if (column_ == SHIELD_CELL)
{
mrtd.shield_ = value.toBool();
@@ -484,6 +500,7 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation
case XREF_CELL: return tr("Cross-reference");
case CABLE_CELL: return tr("Cable");
case CABLE_WIRE_CELL: return tr("Color / wire number of the cable");
case CABLE_TARGET_CELL: return tr("Target");
case TYPE_CELL: return tr("Type");
case FUNCTION_CELL : return tr("Function");
case LED_CELL: return tr("led");
@@ -496,6 +513,13 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation
}
}
}
else if (role == Qt::ToolTipRole &&
orientation == Qt::Horizontal &&
section == CABLE_TARGET_CELL)
{
//Same three fields as the box drawn under the cable
return tr("Installation, Location and Label (BMK) of the piece the cable lands on, past this strip");
}
return QVariant();
}
@@ -510,6 +534,12 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const
if ((c == CABLE_CELL || c == CABLE_WIRE_CELL)
&& !dataAtRow(index.row()).cable_auto_)
flags = flags | Qt::ItemIsEditable;
//The target the project works out is read only: only the drawing
//decides it. No target to show, or one typed in by hand, may be
//written -- the same rule as the cable cells.
if (c == CABLE_TARGET_CELL
&& !dataAtRow(index.row()).cable_target_auto_)
flags = flags | Qt::ItemIsEditable;
if (c == LABEL_CELL || c == TYPE_CELL || c == FUNCTION_CELL
|| c == COLOR_CELL || c == SECTION_CELL || c == WIDTH_CELL)
flags = flags | Qt::ItemIsEditable;
@@ -58,14 +58,15 @@ class TerminalStripModel : public QAbstractTableModel
XRef = 8,
Cable = 9,
CableWire = 10,
Type = 11,
Function = 12,
Led = 13,
Shield = 14,
Color = 15,
Section = 16,
Width = 17,
Separator = 18,
CableTarget = 11,
Type = 12,
Function = 13,
Led = 14,
Shield = 15,
Color = 16,
Section = 17,
Width = 18,
Separator = 19,
Invalid = 99
};