diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake
index cabd1ee3b..cdfa8bd8d 100644
--- a/cmake/qet_compilation_vars.cmake
+++ b/cmake/qet_compilation_vars.cmake
@@ -711,6 +711,7 @@ set(QET_SRC_FILES
${QET_DIR}/sources/TerminalStrip/physicalterminal.h
${QET_DIR}/sources/TerminalStrip/realterminal.cpp
${QET_DIR}/sources/TerminalStrip/realterminal.h
+ ${QET_DIR}/sources/TerminalStrip/terminalcatalog.h
${QET_DIR}/sources/TerminalStrip/terminalstripbridge.cpp
${QET_DIR}/sources/TerminalStrip/terminalstripbridge.h
${QET_DIR}/sources/TerminalStrip/terminalstrip.cpp
diff --git a/sources/TerminalStrip/terminalcatalog.h b/sources/TerminalStrip/terminalcatalog.h
new file mode 100644
index 000000000..5c48939b7
--- /dev/null
+++ b/sources/TerminalStrip/terminalcatalog.h
@@ -0,0 +1,70 @@
+/*
+ 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 TERMINALCATALOG_H
+#define TERMINALCATALOG_H
+
+#include
+
+/**
+ * @brief The TerminalCatalog namespace
+ * Data shared between the terminal strip editor and the element editor :
+ * usual sections (mm2) and widths (mm) of the terminals sold by the manufacturers.
+ * Only the values found in the catalogs of the manufacturers are listed,
+ * any other value can be typed by the user.
+ */
+namespace TerminalCatalog
+{
+ /**
+ * Width (mm) of a terminal sold by a manufacturer.
+ * For ABB Entrelec the value is the spacing (pitch) given by the catalog.
+ */
+ struct WidthEntry { double mm; const char *label; double section; };
+
+ inline const QVector §ions()
+ {
+ static const QVector sections_ {0.5, 0.75, 1, 1.5, 2.5, 4, 6, 10, 16, 25, 35, 50, 70, 95, 120, 150, 185, 240, 300};
+ return sections_;
+ }
+
+ inline const QVector &widthEntries()
+ {
+ static const QVector entries_ {
+ {5.1, "Weidmüller WDU 2.5", 2.5},
+ {5.2, "WAGO 2002 (TOPJOB S)", 2.5},
+ {6.0, "ABB Entrelec M 4/6", 4.0},
+ {6.1, "Weidmüller WDU 4", 4.0},
+ {6.2, "Phoenix Contact UT 4", 4.0},
+ {8.0, "ABB Entrelec M 6/8", 6.0},
+ {8.0, "ABB Entrelec M 4/8", 4.0},
+ {8.2, "Phoenix Contact UT 6", 6.0},
+ {10.0, "ABB Entrelec M 10/10", 10.0},
+ {10.2, "Phoenix Contact UT 10", 10.0},
+ {11.9, "Weidmüller WDU 16/ZA", 16.0},
+ {12.2, "Phoenix Contact UT 16", 16.0},
+ {16.0, "Phoenix Contact UT 35", 35.0},
+ {16.0, "Weidmüller WDU 35N", 35.0},
+ {26.0, "ABB Entrelec M 35/26.FF", 35.0},
+ {31.0, "ABB Entrelec M 70/31.AF", 70.0},
+ {35.0, "ABB Entrelec M 120/35.F", 120.0},
+ {42.0, "ABB Entrelec M 300/42.FF", 300.0}
+ };
+ return entries_;
+ }
+}
+
+#endif // TERMINALCATALOG_H
diff --git a/sources/TerminalStrip/ui/terminalstripmodel.cpp b/sources/TerminalStrip/ui/terminalstripmodel.cpp
index 165944fa9..0cf0f3d04 100644
--- a/sources/TerminalStrip/ui/terminalstripmodel.cpp
+++ b/sources/TerminalStrip/ui/terminalstripmodel.cpp
@@ -16,6 +16,7 @@
along with QElectroTech. If not, see .
*/
#include "terminalstripmodel.h"
+#include "../terminalcatalog.h"
#include "../terminalstrip.h"
#include "../../qetgraphicsitem/element.h"
#include "../physicalterminal.h"
@@ -911,34 +912,6 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
**********************************************************/
namespace {
-/**
- * Widths (mm) of terminals sold by the manufacturers.
- * Only the values found in the catalogs of the manufacturers are listed,
- * any other width can be typed in the cell.
- * For ABB Entrelec the value is the spacing (pitch) given by the catalog.
- */
-struct WidthEntry { double mm; const char *label; double section; };
-const WidthEntry WIDTH_ENTRIES[] {
- {5.1, "Weidmüller WDU 2.5", 2.5},
- {5.2, "WAGO 2002 (TOPJOB S)", 2.5},
- {6.0, "ABB Entrelec M 4/6", 4.0},
- {6.1, "Weidmüller WDU 4", 4.0},
- {6.2, "Phoenix Contact UT 4", 4.0},
- {8.0, "ABB Entrelec M 6/8", 6.0},
- {8.0, "ABB Entrelec M 4/8", 4.0},
- {8.2, "Phoenix Contact UT 6", 6.0},
- {10.0, "ABB Entrelec M 10/10", 10.0},
- {10.2, "Phoenix Contact UT 10", 10.0},
- {11.9, "Weidmüller WDU 16/ZA", 16.0},
- {12.2, "Phoenix Contact UT 16", 16.0},
- {16.0, "Phoenix Contact UT 35", 35.0},
- {16.0, "Weidmüller WDU 35N", 35.0},
- {26.0, "ABB Entrelec M 35/26.FF", 35.0},
- {31.0, "ABB Entrelec M 70/31.AF", 70.0},
- {35.0, "ABB Entrelec M 120/35.F", 120.0},
- {42.0, "ABB Entrelec M 300/42.FF", 300.0}
-};
-
QString widthItemText(double mm, const QString &label = QString())
{
const auto text_ = QCoreApplication::translate("TerminalStripModelDelegate", "%1 mm").arg(QLocale().toString(mm, 'g', 6));
@@ -982,8 +955,7 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO
qcb->setObjectName(QStringLiteral("terminal_section"));
qcb->addItem(tr("None (default)"), 0.0);
//Usual sections, in mm2
- static const QVector sections_ {0.5, 0.75, 1, 1.5, 2.5, 4, 6, 10, 16, 25, 35, 50, 70, 95, 120, 150, 185, 240, 300};
- for (const auto section_ : sections_) {
+ for (const auto section_ : TerminalCatalog::sections()) {
qcb->addItem(tr("%1 mm²").arg(QLocale().toString(section_, 'g', 6)), section_);
}
@@ -1000,7 +972,7 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO
const auto section = parsePositiveNumber(section_index.data(Qt::EditRole).toString(), §ion_ok);
bool has_compatible_entry = false;
if (section_ok && section > 0.0) {
- for (const auto &entry : WIDTH_ENTRIES) {
+ for (const auto &entry : TerminalCatalog::widthEntries()) {
if (qFuzzyCompare(1 + entry.section, 1 + section)) {
qcb->addItem(widthItemText(entry.mm, QString::fromUtf8(entry.label)), entry.mm);
has_compatible_entry = true;
@@ -1009,7 +981,7 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO
}
// If the section has no catalog match (or is unspecified), keep all widths available.
if (!has_compatible_entry) {
- for (const auto &entry : WIDTH_ENTRIES) {
+ for (const auto &entry : TerminalCatalog::widthEntries()) {
qcb->addItem(widthItemText(entry.mm, QString::fromUtf8(entry.label)), entry.mm);
}
}
diff --git a/sources/editor/ui/elementpropertieseditorwidget.cpp b/sources/editor/ui/elementpropertieseditorwidget.cpp
index fad80adf4..d06823b9b 100644
--- a/sources/editor/ui/elementpropertieseditorwidget.cpp
+++ b/sources/editor/ui/elementpropertieseditorwidget.cpp
@@ -20,6 +20,9 @@
#include "../../qet.h"
#include "../../qetapp.h"
#include "../../qetinformation.h"
+#include "../../TerminalStrip/terminalcatalog.h"
+#include "../../TerminalStrip/terminalcolor.h"
+#include "../../TerminalStrip/realterminal.h"
#include "ui_elementpropertieseditorwidget.h"
#include "../../qet.h"
@@ -36,7 +39,10 @@
#include
#include
#include
+#include
#include
+#include
+#include
#include
#include
#include
@@ -71,6 +77,61 @@ QWidget* EditorDelegate::createEditor(QWidget *parent,
return nullptr;
}
+namespace {
+/**
+ * @brief leadingNumber
+ * Extract the first number of a text like "2,5 mm²" or "5.1 mm - WAGO".
+ * The comma and the dot are both accepted as decimal separator.
+ * @return the number, or 0 if the text is empty or has no number.
+ */
+double leadingNumber(const QString &text)
+{
+ static const QRegularExpression re(QStringLiteral("(\\d+(?:[.,]\\d+)?)"));
+ const auto match = re.match(text);
+ if (!match.hasMatch())
+ return 0;
+ auto number = match.captured(1);
+ number.replace(QLatin1Char(','), QLatin1Char('.'));
+ return number.toDouble();
+}
+
+/// Value of a terminal size combo (picked in the list or typed).
+double comboValue(const QComboBox *cb)
+{
+ return leadingNumber(cb->currentText());
+}
+
+/// Color of a terminal combo as "#rrggbb" or "#rrggbb/#rrggbb" (empty = none).
+/// A text which is not understood keeps the value the combo was loaded with.
+QString colorSpec(const QComboBox *cb)
+{
+ const auto index = cb->findText(cb->currentText());
+ if (index >= 0)
+ return cb->itemData(index).toString();
+
+ QColor main_, stripe_;
+ if (TerminalColor::parse(cb->currentText(), &main_, &stripe_))
+ return TerminalColor::toSpec(main_, stripe_);
+ return cb->property("origSpec").toString();
+}
+
+/// Set the text of an editable combo : select the item with this value or write the value.
+void setComboValue(QComboBox *cb, double value, const QString &suffix)
+{
+ if (value <= 0) {
+ cb->setCurrentIndex(0);
+ return;
+ }
+ for (int i = 1; i < cb->count(); ++i) {
+ if (qFuzzyCompare(1 + cb->itemData(i).toDouble(), 1 + value)) {
+ cb->setCurrentIndex(i);
+ return;
+ }
+ }
+ cb->setCurrentText(QLocale().toString(value, 'g', 6) + suffix);
+}
+}
+
/**
* @brief ElementPropertiesEditorWidget::ElementPropertiesEditorWidget
* @param data
@@ -177,6 +238,12 @@ void ElementPropertiesEditorWidget::upDateInterface()
QET::infoFlagIsTrue(info.value(QStringLiteral("auto_num_locked")).toString()));
ui->m_potential_isolating_cb->setChecked(
QET::infoFlagIsTrue(info.value(QStringLiteral("potential_isolating")).toString()));
+
+ //Section (mm2) and width (mm), stored with the dot as decimal separator
+ populateTerminalSizeCombos(
+ info.value(RealTerminal::sectionInfoKey()).toString().toDouble(),
+ info.value(RealTerminal::widthInfoKey()).toString().toDouble());
+ populateTerminalColorCombo(info.value(RealTerminal::colorInfoKey()).toString());
}
ui->m_exclude_from_bom_cb->setChecked(
@@ -361,6 +428,105 @@ void ElementPropertiesEditorWidget::populateTree()
}
}
+/**
+ @brief ElementPropertiesEditorWidget::populateTerminalSizeCombos
+ Fill the section and width combo boxes of the terminal group box
+ and select @a section (mm2) and @a width (mm), 0 means "none".
+ The combo boxes are editable : a value not in the list can be typed.
+*/
+void ElementPropertiesEditorWidget::populateTerminalSizeCombos(double section, double width)
+{
+ QSignalBlocker blocker(ui->m_terminal_section_cb);
+ ui->m_terminal_section_cb->clear();
+ ui->m_terminal_section_cb->addItem(tr("None (default)"), 0.0);
+ for (const auto section_ : TerminalCatalog::sections()) {
+ ui->m_terminal_section_cb->addItem(tr("%1 mm²").arg(QLocale().toString(section_, 'g', 6)), section_);
+ }
+ setComboValue(ui->m_terminal_section_cb, section, tr(" mm²"));
+
+ connect(ui->m_terminal_section_cb, QOverload::of(&QComboBox::currentIndexChanged),
+ this, [this]() { refreshTerminalWidthCombo(); });
+ connect(ui->m_terminal_section_cb->lineEdit(), &QLineEdit::editingFinished,
+ this, [this]() { refreshTerminalWidthCombo(); });
+
+ refreshTerminalWidthCombo();
+ setComboValue(ui->m_terminal_width_cb, width, tr(" mm"));
+}
+
+/**
+ @brief ElementPropertiesEditorWidget::populateTerminalColorCombo
+ Fill the color combo box with the palette of the terminal strip
+ and select @a spec ("#rrggbb" or "#rrggbb/#rrggbb", empty = none).
+ The combo box is editable : a color can be typed as a name or as "#rrggbb".
+*/
+void ElementPropertiesEditorWidget::populateTerminalColorCombo(const QString &spec)
+{
+ auto *cb = ui->m_terminal_color_cb;
+ cb->setProperty("origSpec", spec);
+ cb->clear();
+ cb->addItem(tr("None (default)"), QString());
+ for (const auto &entry : TerminalColor::palette())
+ {
+ QColor main_, stripe_;
+ TerminalColor::parse(TerminalColor::specOf(entry), &main_, &stripe_);
+ cb->addItem(QIcon(TerminalColor::swatch(main_, stripe_)),
+ TerminalColor::translatedName(entry),
+ TerminalColor::specOf(entry));
+ }
+
+ if (spec.isEmpty()) {
+ cb->setCurrentIndex(0);
+ return;
+ }
+ const auto index = cb->findData(spec);
+ if (index >= 0) {
+ cb->setCurrentIndex(index);
+ } else {
+ //The color is not in the palette, keep it in the list
+ QColor main_, stripe_;
+ TerminalColor::parse(spec, &main_, &stripe_);
+ cb->addItem(QIcon(TerminalColor::swatch(main_, stripe_)), spec, spec);
+ cb->setCurrentIndex(cb->count() - 1);
+ }
+}
+
+/**
+ @brief ElementPropertiesEditorWidget::refreshTerminalWidthCombo
+ List the manufacturer terminals compatible with the selected section.
+ If the section has no match in the catalog (or is not set),
+ all the widths are listed. The current width is kept.
+*/
+void ElementPropertiesEditorWidget::refreshTerminalWidthCombo()
+{
+ const auto current_width = comboValue(ui->m_terminal_width_cb);
+ const auto section = comboValue(ui->m_terminal_section_cb);
+
+ auto item_text = [](const TerminalCatalog::WidthEntry &entry) {
+ return tr("%1 mm").arg(QLocale().toString(entry.mm, 'g', 6))
+ + QStringLiteral(" - ") + QString::fromUtf8(entry.label);
+ };
+
+ bool has_compatible_entry = false;
+ if (section > 0) {
+ for (const auto &entry : TerminalCatalog::widthEntries()) {
+ if (qFuzzyCompare(1 + entry.section, 1 + section)) {
+ has_compatible_entry = true;
+ break;
+ }
+ }
+ }
+
+ QSignalBlocker blocker(ui->m_terminal_width_cb);
+ ui->m_terminal_width_cb->clear();
+ ui->m_terminal_width_cb->addItem(tr("None (default)"), 0.0);
+ for (const auto &entry : TerminalCatalog::widthEntries()) {
+ if (!has_compatible_entry || qFuzzyCompare(1 + entry.section, 1 + section)) {
+ ui->m_terminal_width_cb->addItem(item_text(entry), entry.mm);
+ }
+ }
+ setComboValue(ui->m_terminal_width_cb, current_width, tr(" mm"));
+}
+
/**
@brief ElementPropertiesEditorWidget::on_m_buttonBox_accepted
Action on button accepted : the new information is set
@@ -424,6 +590,25 @@ void ElementPropertiesEditorWidget::on_m_buttonBox_accepted()
m_data.m_informations.addValue(QStringLiteral("potential_isolating"), QStringLiteral("true"));
else
m_data.m_informations.remove(QStringLiteral("potential_isolating"));
+
+ //Section and width : stored with the dot as decimal separator, whatever the locale
+ const auto section_ = comboValue(ui->m_terminal_section_cb);
+ if (section_ > 0)
+ m_data.m_informations.addValue(RealTerminal::sectionInfoKey(), QString::number(section_, 'g', 6));
+ else
+ m_data.m_informations.remove(RealTerminal::sectionInfoKey());
+
+ const auto width_ = comboValue(ui->m_terminal_width_cb);
+ if (width_ > 0)
+ m_data.m_informations.addValue(RealTerminal::widthInfoKey(), QString::number(width_, 'g', 6));
+ else
+ m_data.m_informations.remove(RealTerminal::widthInfoKey());
+
+ const auto color_ = colorSpec(ui->m_terminal_color_cb);
+ if (!color_.isEmpty())
+ m_data.m_informations.addValue(RealTerminal::colorInfoKey(), color_);
+ else
+ m_data.m_informations.remove(RealTerminal::colorInfoKey());
}
if (ui->m_exclude_from_bom_cb->isChecked())
diff --git a/sources/editor/ui/elementpropertieseditorwidget.h b/sources/editor/ui/elementpropertieseditorwidget.h
index e58cdd1b8..7565f880d 100644
--- a/sources/editor/ui/elementpropertieseditorwidget.h
+++ b/sources/editor/ui/elementpropertieseditorwidget.h
@@ -81,6 +81,9 @@ class ElementPropertiesEditorWidget : public QDialog
void createPlcConfigWidgets();
void populatePlcTable();
void readPlcTable();
+ void populateTerminalSizeCombos(double section, double width);
+ void refreshTerminalWidthCombo();
+ void populateTerminalColorCombo(const QString &spec);
//SLOTS
private slots:
diff --git a/sources/editor/ui/elementpropertieseditorwidget.ui b/sources/editor/ui/elementpropertieseditorwidget.ui
index 138cd9dfa..9eb8754e4 100644
--- a/sources/editor/ui/elementpropertieseditorwidget.ui
+++ b/sources/editor/ui/elementpropertieseditorwidget.ui
@@ -259,6 +259,57 @@
+ -
+
+
+ Section (mm²)
+
+
+
+ -
+
+
+ true
+
+
+ QComboBox::NoInsert
+
+
+
+ -
+
+
+ Width / manufacturer
+
+
+
+ -
+
+
+ true
+
+
+ QComboBox::NoInsert
+
+
+
+ -
+
+
+ Color
+
+
+
+ -
+
+
+ true
+
+
+ QComboBox::NoInsert
+
+
+