diff --git a/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.cpp b/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.cpp
index e11ede4a3..0bbb726b5 100644
--- a/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.cpp
+++ b/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.cpp
@@ -171,6 +171,32 @@ namespace
}
}
+/**
+ * @brief TerminalStripLayoutPattern::drawStyleToString
+ * @return the string used to save @a style in the project xml (terminal strip item)
+ */
+QString TerminalStripLayoutPattern::drawStyleToString(DrawStyle style)
+{
+ switch (style) {
+ case DrawStyle::RealisticPushIn : return QStringLiteral("realistic_push_in");
+ case DrawStyle::RealisticScrew : return QStringLiteral("realistic_screw");
+ default : return QStringLiteral("schematic");
+ }
+}
+
+/**
+ * @brief TerminalStripLayoutPattern::drawStyleFromString
+ * @return the style saved as @a string, or @a default_style if @a string is unknown or empty
+ * (item saved before the drawing styles : the schematic style is kept).
+ */
+TerminalStripLayoutPattern::DrawStyle TerminalStripLayoutPattern::drawStyleFromString(const QString &string, DrawStyle default_style)
+{
+ if (string == QLatin1String("schematic")) return DrawStyle::Schematic;
+ if (string == QLatin1String("realistic_push_in") || string == QLatin1String("realistic")) return DrawStyle::RealisticPushIn;
+ if (string == QLatin1String("realistic_screw")) return DrawStyle::RealisticScrew;
+ return default_style;
+}
+
/**
* @brief TerminalStripLayoutPattern::xmlTagName
* @return the tag name of the xml element used by toXml / fromXml
@@ -228,6 +254,11 @@ QDomElement TerminalStripLayoutPattern::toXml(QDomDocument &document) const
element.setAttribute(QStringLiteral("bridge_point_y_offset_%1").arg(i), m_bridge_point_y_offset.at(i));
}
+ element.setAttribute(QStringLiteral("realistic_px_per_mm"), m_realistic_px_per_mm);
+ element.setAttribute(QStringLiteral("realistic_length_mm"), m_realistic_length_mm);
+ element.setAttribute(QStringLiteral("realistic_end_stops"), m_realistic_end_stops ? 1 : 0);
+ element.setAttribute(QStringLiteral("realistic_group_marker"), m_realistic_group_marker ? 1 : 0);
+
return element;
}
@@ -290,4 +321,19 @@ void TerminalStripLayoutPattern::fromXml(const QDomElement &layout_element)
for (auto i = 0; i < m_bridge_point_y_offset.size(); ++i) {
m_bridge_point_y_offset[i] = realFromXml(layout_element, QStringLiteral("bridge_point_y_offset_%1").arg(i), m_bridge_point_y_offset.at(i));
}
+
+ const auto px_per_mm_ = realFromXml(layout_element, QStringLiteral("realistic_px_per_mm"), m_realistic_px_per_mm);
+ if (px_per_mm_ > 0) {
+ m_realistic_px_per_mm = px_per_mm_;
+ }
+ const auto length_mm_ = realFromXml(layout_element, QStringLiteral("realistic_length_mm"), m_realistic_length_mm);
+ if (length_mm_ > 0) {
+ m_realistic_length_mm = length_mm_;
+ }
+ if (layout_element.hasAttribute(QStringLiteral("realistic_end_stops"))) {
+ m_realistic_end_stops = layout_element.attribute(QStringLiteral("realistic_end_stops")).toInt() != 0;
+ }
+ if (layout_element.hasAttribute(QStringLiteral("realistic_group_marker"))) {
+ m_realistic_group_marker = layout_element.attribute(QStringLiteral("realistic_group_marker")).toInt() != 0;
+ }
}
diff --git a/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.h b/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.h
index b432783b2..4dc941601 100644
--- a/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.h
+++ b/sources/TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.h
@@ -44,6 +44,37 @@ class TerminalStripLayoutPattern
public:
TerminalStripLayoutPattern();
+ /**
+ * @brief The DrawStyle enum
+ * How the terminals of a strip are drawn.
+ * The style is chosen for each terminal strip item, when the item is
+ * added to a folio (see TerminalStripItem::setDrawStyle), the layout
+ * only hold the values used by the styles.
+ * Schematic : the classic drawing (header, xrefs, symbols, connections, cables).
+ * RealisticPushIn : the strip seen from above, at scale, like the mounting
+ * drawing of a cabinet : end stops, group marker, push-in wire entries.
+ * RealisticScrew : same as RealisticPushIn, with screw clamps.
+ * The schematic style use most of the values of this class,
+ * the realistic styles use the values prefixed by m_realistic_.
+ */
+ enum class DrawStyle {
+ Schematic = 0,
+ RealisticPushIn = 1,
+ RealisticScrew = 2
+ };
+ static QString drawStyleToString(DrawStyle style);
+ static DrawStyle drawStyleFromString(const QString &string, DrawStyle default_style);
+
+ //Realistic style
+ //Scale of the drawing : number of pixels for one millimeter
+ qreal m_realistic_px_per_mm{4.0};
+ //Length (mm) of a terminal along the wires, from the top to the bottom
+ qreal m_realistic_length_mm{60.0};
+ //Draw an end stop at each end of the strip
+ bool m_realistic_end_stops{true};
+ //Draw a group marker carrier with the name of the strip, after the first end stop
+ bool m_realistic_group_marker{true};
+
//Header of terminal strip
QRectF m_header_rect{0,30,50,146};
Qt::Orientation m_header_text_orientation{Qt::Horizontal};
diff --git a/sources/TerminalStrip/GraphicsItem/realisticterminalstripdrawer.cpp b/sources/TerminalStrip/GraphicsItem/realisticterminalstripdrawer.cpp
new file mode 100644
index 000000000..431b6c1e2
--- /dev/null
+++ b/sources/TerminalStrip/GraphicsItem/realisticterminalstripdrawer.cpp
@@ -0,0 +1,564 @@
+/*
+ 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 .
+*/
+#include "realisticterminalstripdrawer.h"
+#include "terminalstripdrawerhelpers.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace TerminalStripDrawer {
+namespace Realistic {
+
+namespace {
+
+ //Width (mm) of the accessories. Values of usual products, enough for a drawing.
+constexpr qreal end_stop_width_mm{8.0};
+constexpr qreal group_marker_width_mm{11.0};
+constexpr qreal separator_width_mm{1.5};
+ //Biggest radius of a wire entry (mm), for the wide terminals
+constexpr qreal max_entry_radius_mm{1.9};
+
+ //Vertical layout of a terminal, in fraction of its length (top = 0, bottom = 1).
+ //The wire entries are in [entries_top, band_top] and [band_bottom, 1 - entries_top],
+ //the middle band (marker tag, bridge channels) is in [band_top, band_bottom].
+constexpr qreal entries_top{0.04};
+constexpr qreal band_top{0.40};
+constexpr qreal band_bottom{0.60};
+constexpr qreal channels_top{0.405};
+constexpr qreal channels_bottom{0.445};
+
+ //Colors of the accessories, close to the real products
+const QColor end_stop_color{232, 228, 220};
+const QColor end_stop_grip_color{35, 35, 35};
+const QColor group_marker_color{168, 168, 168};
+const QColor group_marker_text_color{200, 0, 0};
+const QColor band_color{85, 85, 85};
+const QColor channel_color{55, 55, 55};
+const QColor bridge_color{200, 30, 30};
+const QColor separator_color{196, 196, 198};
+
+/**
+ * @brief The PhysicalGeometry struct
+ * What is needed to draw a physical terminal.
+ */
+struct PhysicalGeometry
+{
+ qreal width_mm{0};
+ bool separator_after{false}; //A separator plate is mounted after this terminal
+ QVector> reals;
+};
+
+/**
+ * @return the physical terminals of @a strip with their width, in the drawing order.
+ * The width of a physical terminal is the biggest width of its real terminals,
+ * or the reference width if no width is known.
+ */
+QVector geometry(const AbstractTerminalStripInterface *strip)
+{
+ QVector geometry_;
+ if (!strip) {
+ return geometry_;
+ }
+
+ for (const auto &physical_t : strip->physicalTerminal())
+ {
+ if (!physical_t) {
+ continue;
+ }
+ PhysicalGeometry g_;
+ for (const auto &real_t : physical_t->realTerminals())
+ {
+ if (!real_t) {
+ continue;
+ }
+ g_.reals.append(real_t);
+ g_.width_mm = std::max(g_.width_mm, real_t->widthMm());
+ g_.separator_after = g_.separator_after || real_t->hasSeparatorAfter();
+ if (g_.reals.size() == 4) { //Same limit than the schematic style
+ break;
+ }
+ }
+ if (g_.reals.isEmpty()) {
+ continue;
+ }
+ if (g_.width_mm <= 0) {
+ g_.width_mm = Helpers::referenceTerminalWidthMm();
+ }
+ geometry_.append(g_);
+ }
+ return geometry_;
+}
+
+qreal endStopWidthMm(const TerminalStripLayoutPattern &pattern) {
+ if (!pattern.m_realistic_end_stops) {
+ return 0;
+ }
+ return end_stop_width_mm;
+}
+
+qreal groupMarkerWidthMm(const TerminalStripLayoutPattern &pattern) {
+ return pattern.m_realistic_group_marker ? group_marker_width_mm : 0;
+}
+
+/**
+ * @brief fitFont
+ * Reduce the pixel size of the font of @a painter so that @a text fit in
+ * @a length (along the text) and @a thickness (across the text).
+ * The font is never enlarged.
+ */
+void fitFont(QPainter *painter, const QString &text, qreal length, qreal thickness)
+{
+ auto font_{painter->font()};
+ qreal size_{font_.pixelSize() > 0 ? qreal(font_.pixelSize()) : font_.pointSizeF()};
+ const QFontMetricsF metrics_{font_};
+ qreal factor_{1};
+ if (metrics_.horizontalAdvance(text) > length && length > 0) {
+ factor_ = std::min(factor_, length / metrics_.horizontalAdvance(text));
+ }
+ if (metrics_.height() > thickness && thickness > 0) {
+ factor_ = std::min(factor_, thickness / metrics_.height());
+ }
+ if (factor_ < 1)
+ {
+ size_ = std::max(2.0, size_ * factor_);
+ if (font_.pixelSize() > 0) {
+ font_.setPixelSize(std::max(1, static_cast(size_)));
+ } else {
+ font_.setPointSizeF(size_);
+ }
+ painter->setFont(font_);
+ }
+}
+
+/**
+ * @brief drawVerticalText
+ * Draw @a text from the bottom to the top, centered in @a rect.
+ * The font is reduced if needed.
+ */
+void drawVerticalText(QPainter *painter, const QRectF &rect, const QString &text, const QColor &color)
+{
+ if (text.isEmpty() || rect.isEmpty()) {
+ return;
+ }
+ painter->save();
+ fitFont(painter, text, rect.height() - 2, rect.width() - 1);
+ painter->setPen(color);
+ painter->translate(rect.left(), rect.bottom());
+ painter->rotate(270);
+ painter->drawText(QRectF{0, 0, rect.height(), rect.width()},
+ Qt::AlignCenter, text);
+ painter->restore();
+}
+
+/**
+ * @brief drawGrip
+ * Draw a black ribbed grip (end of an end stop).
+ */
+void drawGrip(QPainter *painter, const QRectF &rect)
+{
+ painter->save();
+ painter->setBrush(end_stop_grip_color);
+ painter->drawRect(rect);
+ painter->setPen(QPen(QColor(150, 150, 150), 0));
+ const qreal step_{std::max(1.5, rect.height() / 5)};
+ for (qreal y = rect.top() + step_ ; y < rect.bottom() - 0.5 ; y += step_) {
+ painter->drawLine(QPointF{rect.left() + 1, y}, QPointF{rect.right() - 1, y});
+ }
+ painter->restore();
+}
+
+/**
+ * @brief drawEndStop
+ * Draw an end stop seen from above : a light body with a black grip at each end,
+ * the fixing screw, the key slot and the locking part.
+ * @param rect : the whole end stop
+ */
+void drawEndStop(QPainter *painter, const QRectF &rect)
+{
+ painter->save();
+ painter->setBrush(end_stop_color);
+ painter->drawRect(rect);
+
+ const qreal w_{rect.width()};
+ const qreal h_{rect.height()};
+ const qreal cx_{rect.center().x()};
+ const qreal grip_h_{h_ * 0.08};
+ drawGrip(painter, QRectF{rect.left(), rect.top(), w_, grip_h_});
+ drawGrip(painter, QRectF{rect.left(), rect.bottom() - grip_h_, w_, grip_h_});
+
+ //Fixing screw
+ const qreal screw_r_{std::min(w_ * 0.3, h_ * 0.05)};
+ const QPointF screw_c_{cx_, rect.top() + h_ * 0.25};
+ painter->setBrush(QColor(60, 60, 60));
+ painter->drawEllipse(screw_c_, screw_r_, screw_r_);
+ painter->setBrush(QColor(20, 20, 20));
+ painter->drawEllipse(screw_c_, screw_r_ * 0.65, screw_r_ * 0.65);
+
+ //Key slot : a narrow slot with a wider middle
+ painter->setBrush(QColor(210, 205, 195));
+ const qreal slot_w_{w_ * 0.22};
+ painter->drawRoundedRect(QRectF{cx_ - slot_w_ / 2, rect.top() + h_ * 0.36, slot_w_, h_ * 0.26}, 1, 1);
+ painter->drawRect(QRectF{cx_ - slot_w_, rect.top() + h_ * 0.45, slot_w_ * 2, h_ * 0.06});
+
+ //Locking part
+ painter->setBrush(QColor(20, 20, 20));
+ const qreal lock_w_{w_ * 0.36};
+ painter->drawRect(QRectF{cx_ - lock_w_ / 2, rect.top() + h_ * 0.68, lock_w_, h_ * 0.07});
+ painter->drawEllipse(QPointF{cx_, rect.top() + h_ * 0.79}, lock_w_ * 0.35, lock_w_ * 0.35);
+
+ painter->restore();
+}
+
+/**
+ * @brief drawSeparator
+ * Draw a separator plate (partition plate) seen from above :
+ * a thin plate as long as the terminals, with rounded ends and a light edge.
+ */
+void drawSeparator(QPainter *painter, const QRectF &rect)
+{
+ painter->save();
+ painter->setPen(QPen(separator_color.darker(170), 0.5));
+ painter->setBrush(separator_color);
+ const qreal r_{std::min(rect.width() / 2, qreal(2.0))};
+ painter->drawRoundedRect(rect, r_, r_);
+ //Light edge, the plate is a bit higher than the terminals
+ painter->setPen(QPen(separator_color.lighter(118), std::max(0.5, rect.width() * 0.25)));
+ painter->drawLine(QPointF{rect.left() + rect.width() * 0.35, rect.top() + r_},
+ QPointF{rect.left() + rect.width() * 0.35, rect.bottom() - r_});
+ painter->restore();
+}
+
+/**
+ * @brief drawGroupMarker
+ * Draw the group marker carrier with the name of the strip on a white label.
+ */
+void drawGroupMarker(QPainter *painter, const QRectF &rect, const QString &text)
+{
+ painter->save();
+ painter->setBrush(group_marker_color);
+ painter->drawRect(rect);
+
+ if (!text.isEmpty())
+ {
+ //White label : as long as the text, centered on the carrier
+ const qreal label_w_{rect.width() * 0.6};
+ fitFont(painter, text, rect.height() * 0.8, label_w_ - 2);
+ const qreal text_len_{QFontMetricsF{painter->font()}.horizontalAdvance(text)};
+ const qreal label_h_{std::min(rect.height() * 0.85, text_len_ + label_w_ * 0.6)};
+ const QRectF label_{rect.center().x() - label_w_ / 2,
+ rect.center().y() - label_h_ / 2,
+ label_w_, label_h_};
+ painter->setBrush(Qt::white);
+ painter->drawRect(label_);
+ drawVerticalText(painter, label_, text, group_marker_text_color);
+ }
+ painter->restore();
+}
+
+/**
+ * @brief drawWireEntry
+ * Draw one wire entry of a terminal.
+ * Push-in : a black hole.
+ * Screw : the head of the clamping screw, with the hole of the wire next to it.
+ * @param center : center of the entry
+ * @param width : width of the terminal
+ * @param row_h : height available for the entry
+ * @param max_r : biggest radius of the entry (a wide terminal don't have a huge hole)
+ * @param outer : -1 if the end of the terminal is above the entry (top half), +1 if it is under (bottom half)
+ * @param screw : true for a screw clamp
+ */
+void drawWireEntry(QPainter *painter, const QPointF ¢er, qreal width, qreal row_h,
+ qreal max_r, qreal outer, const QColor &fill, bool screw)
+{
+ painter->save();
+ if (!screw)
+ {
+ const qreal r_{std::min({width * 0.32, row_h * 0.3, max_r})};
+ painter->setBrush(Qt::black);
+ painter->drawEllipse(center, r_, r_);
+ }
+ else
+ {
+ //Hole of the wire, toward the end of the terminal
+ const qreal hole_{std::min({width * 0.45, row_h * 0.22, max_r * 1.6})};
+ const qreal hole_y_{outer < 0 ? center.y() - row_h * 0.38 : center.y() + row_h * 0.38 - hole_};
+ painter->setBrush(Qt::black);
+ painter->drawRect(QRectF{center.x() - hole_ / 2, hole_y_, hole_, hole_});
+ //Screw head, toward the middle of the terminal
+ const qreal r_{std::min({width * 0.36, row_h * 0.26, max_r * 1.1})};
+ const QPointF c_{center.x(), center.y() - outer * row_h * 0.08};
+ painter->setBrush(fill.darker(125));
+ painter->drawEllipse(c_, r_ * 1.15, r_ * 1.15);
+ painter->setBrush(QColor(175, 175, 175));
+ painter->drawEllipse(c_, r_, r_);
+ painter->setPen(QPen(Qt::black, std::max(0.6, r_ * 0.25)));
+ painter->drawLine(QPointF{c_.x() - r_ * 0.7, c_.y()}, QPointF{c_.x() + r_ * 0.7, c_.y()});
+ }
+ painter->restore();
+}
+
+/**
+ * @brief drawEntriesHalf
+ * Draw the rows of wire entries of one half of a terminal (top or bottom).
+ * One row by level. Each row have a few ribs at its outer side and a line
+ * at its inner side, like the real terminals.
+ * @param outer : y of the outer side of the half (end of the terminal)
+ * @param inner : y of the inner side of the half (middle band). For the bottom half outer > inner.
+ * @param max_r : biggest radius of a wire entry
+ */
+void drawEntriesHalf(QPainter *painter, const QRectF &body, qreal outer, qreal inner,
+ int levels, qreal max_r, const QColor &fill, bool screw)
+{
+ const qreal row_h_{(inner - outer) / levels}; //Negative for the bottom half
+ const qreal abs_row_h_{std::abs(row_h_)};
+ const QPen rib_pen_{fill.darker(170), 0};
+
+ for (int k = 0 ; k < levels ; ++k)
+ {
+ const qreal a_{outer + k * row_h_};
+ //Ribs
+ painter->save();
+ painter->setPen(rib_pen_);
+ for (const qreal f_ : {0.12, 0.22, 0.32}) {
+ const qreal y_{a_ + f_ * row_h_};
+ painter->drawLine(QPointF{body.left(), y_}, QPointF{body.right(), y_});
+ }
+ //Limit of the row
+ if (k > 0) {
+ painter->drawLine(QPointF{body.left(), a_}, QPointF{body.right(), a_});
+ }
+ painter->restore();
+
+ drawWireEntry(painter, QPointF{body.center().x(), a_ + 0.67 * row_h_},
+ body.width(), abs_row_h_, max_r, row_h_ > 0 ? -1 : 1, fill, screw);
+ }
+}
+
+/**
+ * @brief The BridgePoint struct
+ * Where a bridge is plugged.
+ */
+struct BridgePoint
+{
+ QPointF point;
+ qreal width{0};
+};
+
+} //End anonymous namespace
+
+QRectF boundingRect(const AbstractTerminalStripInterface *strip,
+ const TerminalStripLayoutPattern &pattern)
+{
+ qreal width_mm_{2 * endStopWidthMm(pattern) + groupMarkerWidthMm(pattern)};
+ for (const auto &g_ : geometry(strip)) {
+ width_mm_ += g_.width_mm;
+ if (g_.separator_after) {
+ width_mm_ += separator_width_mm;
+ }
+ }
+ const qreal s_{pattern.m_realistic_px_per_mm};
+ return QRectF{0, 0, width_mm_ * s_, pattern.m_realistic_length_mm * s_};
+}
+
+void paint(QPainter *painter,
+ const AbstractTerminalStripInterface &strip,
+ const TerminalStripLayoutPattern &pattern,
+ TerminalStripLayoutPattern::DrawStyle style,
+ bool preview_draw)
+{
+ const bool screw_{style == TerminalStripLayoutPattern::DrawStyle::RealisticScrew};
+ const qreal s_{pattern.m_realistic_px_per_mm};
+ const qreal length_{pattern.m_realistic_length_mm * s_};
+ if (s_ <= 0 || length_ <= 0) {
+ return;
+ }
+
+ painter->save();
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->setFont(pattern.font());
+ painter->setPen(QPen(Qt::black, 0.5));
+
+ if (preview_draw)
+ {
+ painter->save();
+ painter->setPen(Qt::blue);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(boundingRect(&strip, pattern));
+ painter->restore();
+ }
+
+ qreal x_{0};
+
+ //The accessories are a bit shorter than the terminals, centered on them
+ const qreal end_stop_w_{endStopWidthMm(pattern) * s_};
+ const qreal end_stop_h_{length_ * 0.88};
+ const qreal end_stop_y_{(length_ - end_stop_h_) / 2};
+ auto draw_end_stop = [&]()
+ {
+ if (end_stop_w_ <= 0) {
+ return;
+ }
+ const QRectF rect_{x_, end_stop_y_, end_stop_w_, end_stop_h_};
+ drawEndStop(painter, rect_);
+ x_ += end_stop_w_;
+ };
+
+ draw_end_stop();
+
+ if (pattern.m_realistic_group_marker)
+ {
+ const qreal w_{group_marker_width_mm * s_};
+ const qreal h_{length_ * 0.72};
+ drawGroupMarker(painter, QRectF{x_, (length_ - h_) / 2, w_, h_}, strip.name());
+ x_ += w_;
+ }
+
+ QHash> bridges_;
+
+ for (const auto &g_ : geometry(&strip))
+ {
+ const qreal w_{g_.width_mm * s_};
+ const QRectF body_{x_, 0, w_, length_};
+ const auto first_{g_.reals.first()};
+ const int levels_{static_cast(g_.reals.size())};
+
+ QColor fill_, stripe_;
+ Helpers::terminalColors(first_, fill_, stripe_);
+ if (!fill_.isValid()) {
+ fill_ = QColor(150, 150, 150);
+ }
+
+ //Body
+ painter->save();
+ painter->setPen(QPen(fill_.darker(220), 0.5));
+ painter->setBrush(fill_);
+ painter->drawRect(body_);
+ if (stripe_.isValid())
+ {
+ //Two-tone terminal (PE) : the stripe color on the left part, like the real ones
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(stripe_);
+ painter->drawRect(QRectF{body_.left(), body_.top(), w_ * 0.6, length_});
+ }
+ painter->restore();
+
+ //Wire entries : one row by level, at the top and at the bottom
+ const qreal max_r_{max_entry_radius_mm * s_};
+ drawEntriesHalf(painter, body_, length_ * entries_top, length_ * band_top, levels_, max_r_, fill_, screw_);
+ drawEntriesHalf(painter, body_, length_ * (1 - entries_top), length_ * band_bottom, levels_, max_r_, fill_, screw_);
+
+ //Middle band, with one bridge channel by level
+ painter->save();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(band_color);
+ painter->drawRect(QRectF{x_, length_ * band_top, w_, length_ * (band_bottom - band_top)});
+ painter->setBrush(channel_color);
+ const qreal channel_h_{length_ * (channels_bottom - channels_top) / levels_};
+ for (int k = 0 ; k < levels_ ; ++k) {
+ painter->drawRect(QRectF{x_ + w_ * 0.15, length_ * channels_top + (k + 0.2) * channel_h_,
+ w_ * 0.7, channel_h_ * 0.6});
+ }
+ painter->restore();
+
+ //Symbol of the type (fuse, led...), at the bottom of the band
+ const bool have_symbol_{first_->type() != ElementData::TTGeneric || first_->isLed()};
+ const qreal tag_top_{length_ * 0.455};
+ const qreal tag_bottom_{length_ * (have_symbol_ ? 0.535 : 0.59)};
+ if (have_symbol_)
+ {
+ painter->save();
+ painter->setPen(QPen(Qt::white, 0.5));
+ Helpers::drawTypeSymbol(painter, QRectF{x_, length_ * 0.54, w_, length_ * 0.055},
+ first_->type(), first_->isLed());
+ painter->restore();
+ }
+
+ //Marker tag with the number(s) of the terminal
+ QStringList numbers_;
+ for (const auto &real_t : g_.reals) {
+ numbers_ << Helpers::terminalNumber(real_t->label());
+ }
+ const bool sectional_{first_->type() == ElementData::TTSectional};
+ const QRectF tag_{x_ + std::min(0.6 * s_, w_ * 0.12), tag_top_,
+ w_ - 2 * std::min(0.6 * s_, w_ * 0.12), tag_bottom_ - tag_top_};
+ painter->save();
+ painter->setPen(QPen(QColor(120, 120, 120), 0.3));
+ painter->setBrush(sectional_ ? QColor(Qt::black) : QColor(Qt::white));
+ painter->drawRect(tag_);
+ painter->restore();
+ drawVerticalText(painter, tag_, numbers_.join(QStringLiteral(" / ")),
+ sectional_ ? QColor(Qt::white) : QColor(Qt::black));
+
+ //Bridge points : one channel by level
+ for (int k = 0 ; k < levels_ ; ++k)
+ {
+ const auto &real_t{g_.reals.at(k)};
+ if (!real_t->isBridged()) {
+ continue;
+ }
+ QScopedPointer bridge_{real_t->bridge()};
+ if (!bridge_) {
+ continue;
+ }
+ const qreal channel_h_{length_ * (channels_bottom - channels_top) / levels_};
+ const qreal y_{length_ * channels_top + (k + 0.5) * channel_h_};
+ bridges_[bridge_->uuid()].append(BridgePoint{QPointF{x_ + w_ / 2, y_}, w_});
+ }
+
+ x_ += w_;
+
+ //Separator plate after the terminal
+ if (g_.separator_after)
+ {
+ const qreal sep_w_{separator_width_mm * s_};
+ drawSeparator(painter, QRectF{x_, 0, sep_w_, length_});
+ x_ += sep_w_;
+ }
+ }
+
+ //Bridges : a red comb plugged in the channels
+ for (const auto &points_ : std::as_const(bridges_))
+ {
+ if (points_.size() < 2) {
+ continue;
+ }
+ painter->save();
+ const qreal thickness_{std::max(1.0, 0.9 * s_)};
+ painter->setPen(QPen(bridge_color, thickness_, Qt::SolidLine, Qt::FlatCap));
+ painter->drawLine(points_.first().point, points_.last().point);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(bridge_color.darker(140));
+ for (const auto &p_ : points_) {
+ const qreal r_{std::min(p_.width * 0.18, thickness_ * 0.8)};
+ painter->drawEllipse(p_.point, r_, r_);
+ }
+ painter->restore();
+ }
+
+ draw_end_stop();
+
+ painter->restore();
+}
+
+} //End namespace Realistic
+} //End namespace TerminalStripDrawer
diff --git a/sources/TerminalStrip/GraphicsItem/realisticterminalstripdrawer.h b/sources/TerminalStrip/GraphicsItem/realisticterminalstripdrawer.h
new file mode 100644
index 000000000..97afa0206
--- /dev/null
+++ b/sources/TerminalStrip/GraphicsItem/realisticterminalstripdrawer.h
@@ -0,0 +1,50 @@
+/*
+ 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 .
+*/
+#ifndef REALISTICTERMINALSTRIPDRAWER_H
+#define REALISTICTERMINALSTRIPDRAWER_H
+
+#include "terminalstripdrawer.h"
+
+class QPainter;
+
+/**
+ * Drawing of a terminal strip at scale, seen from above, like the
+ * mounting drawing of a cabinet. Used by the styles
+ * RealisticPushIn and RealisticScrew of TerminalStripLayoutPattern.
+ *
+ * The strip is drawn from the left to the right :
+ * end stop, group marker carrier (with the name of the strip), terminals, end stop.
+ * The width of each terminal is its real width (mm) multiplied by the scale of the layout.
+ * A terminal with several levels is drawn with one row of wire entries by level,
+ * at the top and at the bottom.
+ */
+namespace TerminalStripDrawer
+{
+ namespace Realistic
+ {
+ QRectF boundingRect(const AbstractTerminalStripInterface *strip,
+ const TerminalStripLayoutPattern &pattern);
+ void paint(QPainter *painter,
+ const AbstractTerminalStripInterface &strip,
+ const TerminalStripLayoutPattern &pattern,
+ TerminalStripLayoutPattern::DrawStyle style,
+ bool preview_draw = false);
+ }
+}
+
+#endif // REALISTICTERMINALSTRIPDRAWER_H
diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp
index 789226ab7..cefecbdd2 100644
--- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp
+++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp
@@ -16,6 +16,8 @@
along with QElectroTech. If not, see .
*/
#include "terminalstripdrawer.h"
+#include "terminalstripdrawerhelpers.h"
+#include "realisticterminalstripdrawer.h"
#include
#include
@@ -834,12 +836,51 @@ QColor contrastColor(const QColor &background)
} //End anonymous namespace
+/*
+ * Helpers : give to the other drawing styles access to
+ * the functions of the anonymous namespace.
+ */
+qreal Helpers::referenceTerminalWidthMm() {
+ return reference_terminal_width_mm;
+}
+
+void Helpers::terminalColors(const QSharedPointer &real_t,
+ QColor &fill, QColor &stripe)
+{
+ const auto colors_{::TerminalStripDrawer::terminalColors(real_t)};
+ fill = colors_.fill;
+ stripe = colors_.stripe;
+}
+
+QColor Helpers::contrastColor(const QColor &background) {
+ return ::TerminalStripDrawer::contrastColor(background);
+}
+
+QString Helpers::terminalNumber(const QString &label) {
+ return ::TerminalStripDrawer::terminalNumber(label);
+}
+
+void Helpers::drawTypeSymbol(QPainter *painter, const QRectF &box,
+ ElementData::TerminalType type, bool led) {
+ ::TerminalStripDrawer::drawTypeSymbol(painter, box, type, led);
+}
+
/**
* @brief TerminalStripDrawer::paint
* @param painter
*/
void TerminalStripDrawer::paint(QPainter *painter)
{
+ if (m_strip && m_pattern && m_draw_style != TerminalStripLayoutPattern::DrawStyle::Schematic)
+ {
+ //No xref in the realistic styles
+ m_united_xref_text_rect = QRectF();
+ m_xref_rects.clear();
+ m_hovered_xref = hoverTerminal{};
+ Realistic::paint(painter, *m_strip, *m_pattern, m_draw_style, m_preview_draw);
+ return;
+ }
+
if (m_strip && m_pattern)
{
m_united_xref_text_rect = QRectF();
@@ -1195,6 +1236,25 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->translate(terminal_rect.width(),0);
x_offset += terminal_rect.width();
}
+
+ //Separator plate after the physical terminal : a thick line
+ //on the full height of the terminal, after its last level
+ const bool separator_after_ = std::any_of(real_terminal_vector.cbegin(), real_terminal_vector.cend(),
+ [](const QSharedPointer &real_t) {
+ return real_t && real_t->hasSeparatorAfter();
+ });
+ if (separator_after_ && real_t_count > 0 && offset_ >= 0 && offset_ < 4)
+ {
+ const auto &rect_{m_pattern->m_terminal_rect.at(offset_)};
+ painter->save();
+ QPen separator_pen_{painter->pen()};
+ separator_pen_.setColor(Qt::black);
+ separator_pen_.setWidthF(3);
+ separator_pen_.setCapStyle(Qt::FlatCap);
+ painter->setPen(separator_pen_);
+ painter->drawLine(QPointF{0, rect_.top() - 3}, QPointF{0, rect_.top() + rect_.height() + 3});
+ painter->restore();
+ }
physical_index++;
}
painter->restore();
@@ -1225,6 +1285,10 @@ void TerminalStripDrawer::paint(QPainter *painter)
QRectF TerminalStripDrawer::boundingRect() const
{
+ if (m_pattern && m_draw_style != TerminalStripLayoutPattern::DrawStyle::Schematic) {
+ return Realistic::boundingRect(m_strip.data(), *m_pattern);
+ }
+
QRectF rect_{0, 0, width(), height()};
if (m_pattern)
@@ -1292,6 +1356,19 @@ void TerminalStripDrawer::setPreviewDraw(bool draw) {
m_preview_draw = draw;
}
+/**
+ * @brief TerminalStripDrawer::setDrawStyle
+ * Set how the terminals are drawn (schematic, realistic...).
+ * The values used by each style come from the layout.
+ */
+void TerminalStripDrawer::setDrawStyle(TerminalStripLayoutPattern::DrawStyle style) {
+ m_draw_style = style;
+}
+
+TerminalStripLayoutPattern::DrawStyle TerminalStripDrawer::drawStyle() const {
+ return m_draw_style;
+}
+
void TerminalStripDrawer::setMouseHoverPos(const QPointF &pos)
{
m_last_mouse_pos_in_xrefs_rect = m_united_xref_text_rect.contains(m_mouse_hover_pos);
diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h
index ca8917e30..04d92cec5 100644
--- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h
+++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h
@@ -85,6 +85,8 @@ namespace TerminalStripDrawer
//Second color of a two-tone color (like green/yellow), drawn as stripes over color()
virtual QColor stripeColor() const { return QColor(); }
virtual qreal widthMm() const { return 0; }
+ //A separator plate is mounted after the terminal (drawn by the realistic styles)
+ virtual bool hasSeparatorAfter() const { return false; }
};
class AbstractPhysicalTerminalInterface
@@ -121,6 +123,9 @@ namespace TerminalStripDrawer
void setPreviewDraw(bool draw = true);
+ void setDrawStyle(TerminalStripLayoutPattern::DrawStyle style);
+ TerminalStripLayoutPattern::DrawStyle drawStyle() const;
+
void setMouseHoverPos(const QPointF &pos);
bool mouseHoverXref() const;
bool needUpdate();
@@ -135,6 +140,7 @@ namespace TerminalStripDrawer
QSharedPointer m_strip;
QSharedPointer m_pattern;
bool m_preview_draw { false };
+ TerminalStripLayoutPattern::DrawStyle m_draw_style { TerminalStripLayoutPattern::DrawStyle::Schematic };
QPointF m_mouse_hover_pos;
QRectF m_united_xref_text_rect;
bool m_last_mouse_pos_in_xrefs_rect{false};
diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawerhelpers.h b/sources/TerminalStrip/GraphicsItem/terminalstripdrawerhelpers.h
new file mode 100644
index 000000000..7cbafd5ea
--- /dev/null
+++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawerhelpers.h
@@ -0,0 +1,48 @@
+/*
+ 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 .
+*/
+#ifndef TERMINALSTRIPDRAWERHELPERS_H
+#define TERMINALSTRIPDRAWERHELPERS_H
+
+#include "terminalstripdrawer.h"
+
+class QPainter;
+
+/**
+ * Functions shared by the drawing styles of a terminal strip
+ * (schematic style in terminalstripdrawer.cpp, realistic style in realisticterminalstripdrawer.cpp).
+ */
+namespace TerminalStripDrawer
+{
+ namespace Helpers
+ {
+ //Width (mm) of the reference terminal (2.5 mm2), used when the width of a terminal is unknown
+ qreal referenceTerminalWidthMm();
+ //Fill color and stripe color (can be invalid) of a terminal
+ void terminalColors(const QSharedPointer &real_t,
+ QColor &fill, QColor &stripe);
+ //Black or white, the more readable on background
+ QColor contrastColor(const QColor &background);
+ //Number of a terminal : "1" for "XAUZ1:1"
+ QString terminalNumber(const QString &label);
+ //Symbol of the type of the terminal (fuse, diode, led...) scaled to fit in box
+ void drawTypeSymbol(QPainter *painter, const QRectF &box,
+ ElementData::TerminalType type, bool led);
+ }
+}
+
+#endif // TERMINALSTRIPDRAWERHELPERS_H
diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp
index fc706fc1b..1867b8032 100644
--- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp
+++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp
@@ -205,6 +205,26 @@ void TerminalStripItem::setLayout(QSharedPointer lay
m_drawer.setLayout(layout);
}
+/**
+ * @brief TerminalStripItem::setDrawStyle
+ * Set how this item draw the terminals (schematic, realistic...).
+ * The style is chosen when the item is added to a folio and saved with the item.
+ * @param style
+ */
+void TerminalStripItem::setDrawStyle(TerminalStripLayoutPattern::DrawStyle style)
+{
+ if (style == m_drawer.drawStyle()) {
+ return;
+ }
+ prepareGeometryChange();
+ m_drawer.setDrawStyle(style);
+ update();
+}
+
+TerminalStripLayoutPattern::DrawStyle TerminalStripItem::drawStyle() const {
+ return m_drawer.drawStyle();
+}
+
void TerminalStripItem::setDefaultLayout()
{
if (m_strip && m_strip->project()) {
diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h
index b5c29c67c..b4cd5d77f 100644
--- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h
+++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h
@@ -54,6 +54,8 @@ class TerminalStripItem : public QetGraphicsItem
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
void refreshPending();
void setLayout(QSharedPointer layout);
+ void setDrawStyle(TerminalStripLayoutPattern::DrawStyle style);
+ TerminalStripLayoutPattern::DrawStyle drawStyle() const;
/**
* @brief The PdfRef struct
diff --git a/sources/TerminalStrip/GraphicsItem/trueterminalstrip.cpp b/sources/TerminalStrip/GraphicsItem/trueterminalstrip.cpp
index f96fcc356..8b6e66462 100644
--- a/sources/TerminalStrip/GraphicsItem/trueterminalstrip.cpp
+++ b/sources/TerminalStrip/GraphicsItem/trueterminalstrip.cpp
@@ -168,6 +168,11 @@ namespace TerminalStripDrawer
return m_real ? m_real->widthMm() : 0;
}
+ bool TrueRealTerminal::hasSeparatorAfter() const
+ {
+ return m_real ? m_real->hasSeparatorAfter() : false;
+ }
+
TrueBridge::TrueBridge(QSharedPointer bridge) :
m_bridge { bridge }
{}
diff --git a/sources/TerminalStrip/GraphicsItem/trueterminalstrip.h b/sources/TerminalStrip/GraphicsItem/trueterminalstrip.h
index 4438eb97f..807a29f4e 100644
--- a/sources/TerminalStrip/GraphicsItem/trueterminalstrip.h
+++ b/sources/TerminalStrip/GraphicsItem/trueterminalstrip.h
@@ -67,6 +67,7 @@ namespace TerminalStripDrawer
QColor color() const override;
QColor stripeColor() const override;
qreal widthMm() const override;
+ bool hasSeparatorAfter() const override;
private:
QSharedPointer m_real;
diff --git a/sources/TerminalStrip/realterminal.cpp b/sources/TerminalStrip/realterminal.cpp
index 4ad4bcd54..afd308385 100644
--- a/sources/TerminalStrip/realterminal.cpp
+++ b/sources/TerminalStrip/realterminal.cpp
@@ -264,6 +264,20 @@ qreal RealTerminal::widthMm() const
return 0;
}
+/**
+ * @brief RealTerminal::hasSeparatorAfter
+ * @return true if a separator plate (partition plate) is mounted
+ * after this terminal, between this terminal and the next one of the strip.
+ * Used to separate groups of terminals (voltages, functions...).
+ */
+bool RealTerminal::hasSeparatorAfter() const {
+ if (m_element) {
+ return QET::infoFlagIsTrue(
+ m_element->elementData().m_informations.value(separatorInfoKey()).toString());
+ }
+ return false;
+}
+
/**
* @brief RealTerminal::conductor
* @return
diff --git a/sources/TerminalStrip/realterminal.h b/sources/TerminalStrip/realterminal.h
index b14969464..5946e707e 100644
--- a/sources/TerminalStrip/realterminal.h
+++ b/sources/TerminalStrip/realterminal.h
@@ -71,6 +71,7 @@ class RealTerminal
QColor stripeColor() const;
qreal section() const;
qreal widthMm() const;
+ bool hasSeparatorAfter() const;
//Keys used to store the cable data in the element informations
static QString cableInfoKey() { return QStringLiteral("terminal_cable"); }
@@ -81,6 +82,8 @@ class RealTerminal
static QString sectionInfoKey() { return QStringLiteral("terminal_section"); }
//Key used to store the width (mm) of the terminal, drawn in the terminal strip
static QString widthInfoKey() { return QStringLiteral("terminal_width"); }
+ //Key used to store if a separator plate is mounted after the terminal
+ static QString separatorInfoKey() { return QStringLiteral("terminal_separator"); }
QString conductor() const;
diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp b/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp
index fe4c77d8b..0c0eb8752 100644
--- a/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp
+++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp
@@ -24,6 +24,8 @@
#include "../../diagram.h"
#include "../../qet.h"
+
+#include
void AddTerminalStripItemDialog::openDialog(Diagram *diagram, QWidget *parent)
{
AddTerminalStripItemDialog d(diagram->project(), parent);
@@ -33,6 +35,7 @@ void AddTerminalStripItemDialog::openDialog(Diagram *diagram, QWidget *parent)
if (strip_)
{
auto item_ = new TerminalStripItem(strip_);
+ item_->setDrawStyle(static_cast(d.selectedDrawStyle()));
diagram->addItem(item_);
item_->setPos(50, 50);
@@ -77,6 +80,16 @@ TerminalStrip *AddTerminalStripItemDialog::selectedTerminalStrip() const
return nullptr;
}
+/**
+ * @brief AddTerminalStripItemDialog::selectedDrawStyle
+ * @return The drawing style chosen for the new item,
+ * as an int value of TerminalStripLayoutPattern::DrawStyle.
+ * The index of the combo box is the value of the enum.
+ */
+int AddTerminalStripItemDialog::selectedDrawStyle() const {
+ return std::clamp(ui->m_draw_style_cb->currentIndex(), 0, 2);
+}
+
void AddTerminalStripItemDialog::fillComboBox()
{
if (m_project)
diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.h b/sources/TerminalStrip/ui/addterminalstripitemdialog.h
index 02eb3bd26..0c1c1d36c 100644
--- a/sources/TerminalStrip/ui/addterminalstripitemdialog.h
+++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.h
@@ -41,6 +41,7 @@ class AddTerminalStripItemDialog : public QDialog
explicit AddTerminalStripItemDialog(QETProject *project, QWidget *parent = nullptr);
~AddTerminalStripItemDialog();
TerminalStrip *selectedTerminalStrip() const;
+ int selectedDrawStyle() const;
void fillComboBox();
private:
diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.ui b/sources/TerminalStrip/ui/addterminalstripitemdialog.ui
index f2300f856..f2ac6d61e 100644
--- a/sources/TerminalStrip/ui/addterminalstripitemdialog.ui
+++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.ui
@@ -24,6 +24,35 @@
-
+ -
+
+
+ Drawing style :
+
+
+
+ -
+
+
+ How the terminals are drawn. The realistic styles draw the strip at scale, seen from above, with the real width of each terminal.
+
+
-
+
+ Schematic
+
+
+ -
+
+ Realistic (push-in)
+
+
+ -
+
+ Realistic (screw)
+
+
+
+
-
diff --git a/sources/TerminalStrip/ui/modelTerminalData.h b/sources/TerminalStrip/ui/modelTerminalData.h
index 97ad958ca..7e6d9e2ac 100644
--- a/sources/TerminalStrip/ui/modelTerminalData.h
+++ b/sources/TerminalStrip/ui/modelTerminalData.h
@@ -38,6 +38,7 @@ struct modelRealTerminalData
mrtd.conductor_ = real_t->conductor();
mrtd.led_ = real_t->isLed();
mrtd.shield_ = real_t->isShield();
+ mrtd.separator_ = real_t->hasSeparatorAfter();
mrtd.color_ = real_t->color();
mrtd.stripe_color_ = real_t->stripeColor();
mrtd.section_ = real_t->section();
@@ -60,6 +61,7 @@ struct modelRealTerminalData
QString conductor_;
bool led_ = false;
bool shield_ = false;
+ bool separator_ = false; //A separator plate is mounted after the terminal
QColor color_; //Invalid = no color set by the user
QColor stripe_color_; //Second color of a two-tone color, invalid if plain
qreal section_ = 0; //In mm2, 0 = no section set by the user
diff --git a/sources/TerminalStrip/ui/terminalstripeditor.cpp b/sources/TerminalStrip/ui/terminalstripeditor.cpp
index ceafd9c33..a31fa46b8 100644
--- a/sources/TerminalStrip/ui/terminalstripeditor.cpp
+++ b/sources/TerminalStrip/ui/terminalstripeditor.cpp
@@ -222,6 +222,7 @@ void TerminalStripEditor::apply()
set_info(RealTerminal::colorInfoKey(), TerminalColor::toSpec(data_.color_, data_.stripe_color_));
set_info(RealTerminal::sectionInfoKey(), data_.section_ > 0 ? QString::number(data_.section_, 'g', 6) : QString());
set_info(RealTerminal::widthInfoKey(), data_.width_mm_ > 0 ? QString::number(data_.width_mm_, 'g', 6) : QString());
+ set_info(RealTerminal::separatorInfoKey(), data_.separator_ ? QStringLiteral("true") : QString());
if (element->elementData() != current_data)
m_project->undoStack()->push(new ChangeElementDataCommand(element, current_data));
diff --git a/sources/TerminalStrip/ui/terminalstriplayouteditor.cpp b/sources/TerminalStrip/ui/terminalstriplayouteditor.cpp
index f67087017..64ab52a35 100644
--- a/sources/TerminalStrip/ui/terminalstriplayouteditor.cpp
+++ b/sources/TerminalStrip/ui/terminalstriplayouteditor.cpp
@@ -17,6 +17,8 @@
*/
#include
+#include
+
#include "terminalstriplayouteditor.h"
#include "ui_terminalstriplayouteditor.h"
#include "../GraphicsItem/properties/terminalstriplayoutpattern.h"
@@ -33,6 +35,26 @@ TerminalStripLayoutEditor::TerminalStripLayoutEditor(QSharedPointerm_graphics_view->setBackgroundBrush(Qt::white);
ui->m_graphics_view->scene()->addItem(&m_preview_strip_item);
+
+ //Drawing style
+ //The style is chosen for each item when it is added to a folio,
+ //here it only change the preview, to see the values of each style.
+ connect(ui->m_draw_style_cb, &QComboBox::currentIndexChanged, this, [this](int index) {
+ m_preview_strip_item.prepareGeometryChange();
+ m_preview_strip_item.m_drawer.setDrawStyle(
+ static_cast(std::clamp(index, 0, 2)));
+ m_preview_strip_item.update();
+ updatePreview();
+ });
+ connect(ui->m_realistic_scale_sb, &QDoubleSpinBox::valueChanged,
+ this, &TerminalStripLayoutEditor::valueEdited);
+ connect(ui->m_realistic_length_sb, &QSpinBox::valueChanged,
+ this, &TerminalStripLayoutEditor::valueEdited);
+ connect(ui->m_realistic_end_stops_cb, &QCheckBox::toggled,
+ this, &TerminalStripLayoutEditor::valueEdited);
+ connect(ui->m_realistic_group_marker_cb, &QCheckBox::toggled,
+ this, &TerminalStripLayoutEditor::valueEdited);
+
updateUi();
}
@@ -159,6 +181,12 @@ void TerminalStripLayoutEditor::valueEdited()
m_layout.data()->m_cable_length = ui->m_cable_length_sb->value();
m_layout.data()->m_cable_end_length = ui->m_cable_end_length_sb->value();
+ //Values of the realistic styles
+ m_layout.data()->m_realistic_px_per_mm = ui->m_realistic_scale_sb->value();
+ m_layout.data()->m_realistic_length_mm = ui->m_realistic_length_sb->value();
+ m_layout.data()->m_realistic_end_stops = ui->m_realistic_end_stops_cb->isChecked();
+ m_layout.data()->m_realistic_group_marker = ui->m_realistic_group_marker_cb->isChecked();
+
updateUi();
m_preview_strip_item.update();
}
@@ -271,6 +299,12 @@ void TerminalStripLayoutEditor::updateUi()
ui->m_cable_length_sb->setValue(data->m_cable_length);
ui->m_cable_end_length_sb->setValue(data->m_cable_end_length);
+ //Values of the realistic styles
+ ui->m_realistic_scale_sb->setValue(data->m_realistic_px_per_mm);
+ ui->m_realistic_length_sb->setValue(qRound(data->m_realistic_length_mm));
+ ui->m_realistic_end_stops_cb->setChecked(data->m_realistic_end_stops);
+ ui->m_realistic_group_marker_cb->setChecked(data->m_realistic_group_marker);
+
m_ui_updating = false;
updatePreview();
}
diff --git a/sources/TerminalStrip/ui/terminalstriplayouteditor.ui b/sources/TerminalStrip/ui/terminalstriplayouteditor.ui
index 73b8c3ac9..d44f681c5 100644
--- a/sources/TerminalStrip/ui/terminalstriplayouteditor.ui
+++ b/sources/TerminalStrip/ui/terminalstriplayouteditor.ui
@@ -540,6 +540,88 @@
+ -
+
+
+ Preview style
+
+
+
+ -
+
+
+ Style of the preview only. The style of a terminal strip plan is chosen when it is added to a folio.
+
+
-
+
+ Schematic
+
+
+ -
+
+ Realistic (push-in)
+
+
+ -
+
+ Realistic (screw)
+
+
+
+
+ -
+
+
+ Scale (px/mm) / length (mm)
+
+
+
+ -
+
+
+ Number of pixels for one millimeter of terminal.
+
+
+ 1
+
+
+ 0.5
+
+
+ 50.0
+
+
+ 0.5
+
+
+
+ -
+
+
+ Length of a terminal along the wires, in millimeter.
+
+
+ 10
+
+
+ 300
+
+
+
+ -
+
+
+ End stops
+
+
+
+ -
+
+
+ Group marker
+
+
+
diff --git a/sources/TerminalStrip/ui/terminalstripmodel.cpp b/sources/TerminalStrip/ui/terminalstripmodel.cpp
index 029647257..54e5ed8f1 100644
--- a/sources/TerminalStrip/ui/terminalstripmodel.cpp
+++ b/sources/TerminalStrip/ui/terminalstripmodel.cpp
@@ -55,8 +55,9 @@ 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 COLUMN_COUNT = 18;
+const int COLUMN_COUNT = 19;
static QVector UNMODIFIED_CELL_VECTOR(COLUMN_COUNT, false);
@@ -130,6 +131,7 @@ TerminalStripModel::Column TerminalStripModel::columnTypeForIndex(const QModelIn
case 15 : return Color;
case 16 : return Section;
case 17 : return Width;
+ case 18 : return Separator;
default : return Invalid;
}
}
@@ -236,6 +238,11 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
{
return mrtd.shield_ ? Qt::Checked : Qt::Unchecked;
}
+ else if (role == Qt::CheckStateRole &&
+ index.column() == SEPARATOR_CELL)
+ {
+ return mrtd.separator_ ? Qt::Checked : Qt::Unchecked;
+ }
else if (role == Qt::BackgroundRole && index.column() < COLUMN_COUNT )
{
if (m_modified_cell.contains(mrtd.element_) &&
@@ -327,6 +334,12 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value
modified_ = true;
modified_cell = SHIELD_CELL;
}
+ else if (column_ == SEPARATOR_CELL)
+ {
+ mrtd.separator_ = value.toBool();
+ modified_ = true;
+ modified_cell = SEPARATOR_CELL;
+ }
else if (column_ == COLOR_CELL &&
role == Qt::EditRole)
{
@@ -417,6 +430,7 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation
case COLOR_CELL: return tr("Color");
case SECTION_CELL: return tr("Section (mm²)");
case WIDTH_CELL: return tr("Width (mm)");
+ case SEPARATOR_CELL: return tr("Separator plate after");
default : return QVariant();
}
}
@@ -434,7 +448,7 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const
|| c == CABLE_CELL || c == CABLE_WIRE_CELL
|| c == COLOR_CELL || c == SECTION_CELL || c == WIDTH_CELL)
flags = flags | Qt::ItemIsEditable;
- if (c == LED_CELL || c == SHIELD_CELL) {
+ if (c == LED_CELL || c == SHIELD_CELL || c == SEPARATOR_CELL) {
flags = flags | Qt::ItemIsUserCheckable;
}
return flags;
diff --git a/sources/TerminalStrip/ui/terminalstripmodel.h b/sources/TerminalStrip/ui/terminalstripmodel.h
index 1a1f89fc5..8c2b48fb0 100644
--- a/sources/TerminalStrip/ui/terminalstripmodel.h
+++ b/sources/TerminalStrip/ui/terminalstripmodel.h
@@ -65,6 +65,7 @@ class TerminalStripModel : public QAbstractTableModel
Color = 15,
Section = 16,
Width = 17,
+ Separator = 18,
Invalid = 99
};
diff --git a/sources/xml/terminalstripitemxml.cpp b/sources/xml/terminalstripitemxml.cpp
index 0b0290f51..0f9087d39 100644
--- a/sources/xml/terminalstripitemxml.cpp
+++ b/sources/xml/terminalstripitemxml.cpp
@@ -95,6 +95,12 @@ QDomElement TerminalStripItemXml::toXml(TerminalStripItem *item, QDomDocument &d
dom_element.appendChild(QETXML::qGraphicsItemPosToXml(item, document));
+ //Drawing style of the item, not saved for the default (schematic) style
+ if (item->drawStyle() != TerminalStripLayoutPattern::DrawStyle::Schematic) {
+ dom_element.setAttribute(QStringLiteral("draw_style"),
+ TerminalStripLayoutPattern::drawStyleToString(item->drawStyle()));
+ }
+
return dom_element;
} else {
return QDomElement();
@@ -134,6 +140,11 @@ bool TerminalStripItemXml::fromXml(TerminalStripItem *item, QETProject *project,
bool b{QETXML::qGraphicsItemPosFromXml(item,
xml_elmt.firstChildElement(QStringLiteral("pos")))};
+ //Item saved before the drawing styles : no attribute, schematic style
+ item->setDrawStyle(TerminalStripLayoutPattern::drawStyleFromString(
+ xml_elmt.attribute(QStringLiteral("draw_style")),
+ TerminalStripLayoutPattern::DrawStyle::Schematic));
+
return (a && b);
}
return false;