mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-25 23:54:22 +01:00
Improve terminal_strip
This commit is contained in:
@@ -20,8 +20,12 @@
|
||||
#include "../../qetgraphicsitem/element.h"
|
||||
#include "../physicalterminal.h"
|
||||
#include "../realterminal.h"
|
||||
#include "../terminalcolor.h"
|
||||
#include "../terminalstripbridge.h"
|
||||
#include <QColor>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QLocale>
|
||||
#include <QBrush>
|
||||
#include <QVector>
|
||||
#include <QComboBox>
|
||||
@@ -47,10 +51,37 @@ 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 COLUMN_COUNT = 15;
|
||||
const int COLUMN_COUNT = 18;
|
||||
|
||||
static QVector<bool> UNMODIFIED_CELL_VECTOR{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
|
||||
static QVector<bool> UNMODIFIED_CELL_VECTOR(COLUMN_COUNT, false);
|
||||
|
||||
/**
|
||||
* @brief parsePositiveNumber
|
||||
* Convert the text written by the user to a number >= 0
|
||||
* (a section in mm2 or a width in mm).
|
||||
* The comma and the dot are both accepted as decimal separator.
|
||||
* @param text
|
||||
* @param ok : true if the text is valid (empty text is valid and mean 0)
|
||||
* @return
|
||||
*/
|
||||
static qreal parsePositiveNumber(const QString &text, bool *ok)
|
||||
{
|
||||
auto text_ = text.trimmed();
|
||||
text_.replace(QLatin1Char(','), QLatin1Char('.'));
|
||||
if (text_.isEmpty()) {
|
||||
*ok = true;
|
||||
return 0;
|
||||
}
|
||||
const auto value_ = text_.toDouble(ok);
|
||||
if (*ok && value_ < 0) {
|
||||
*ok = false;
|
||||
}
|
||||
return *ok ? value_ : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TerminalStripModel::levelForColumn
|
||||
@@ -95,6 +126,9 @@ TerminalStripModel::Column TerminalStripModel::columnTypeForIndex(const QModelIn
|
||||
case 12 : return Function;
|
||||
case 13 : return Led;
|
||||
case 14 : return Shield;
|
||||
case 15 : return Color;
|
||||
case 16 : return Section;
|
||||
case 17 : return Width;
|
||||
default : return Invalid;
|
||||
}
|
||||
}
|
||||
@@ -172,6 +206,9 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
|
||||
case CABLE_WIRE_CELL : return mrtd.cable_wire;
|
||||
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_);
|
||||
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();
|
||||
default : return QVariant();
|
||||
}
|
||||
}
|
||||
@@ -181,6 +218,9 @@ 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 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();
|
||||
default: return QVariant();
|
||||
|
||||
}
|
||||
@@ -203,6 +243,13 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
|
||||
return QBrush(Qt::yellow);
|
||||
}
|
||||
}
|
||||
else if (role == Qt::DecorationRole &&
|
||||
index.column() == COLOR_CELL)
|
||||
{
|
||||
if (mrtd.color_.isValid()) {
|
||||
return TerminalColor::swatch(mrtd.color_, mrtd.stripe_color_);
|
||||
}
|
||||
}
|
||||
else if (role == Qt::DecorationRole &&
|
||||
(index.column() == LEVEL_0_CELL ||
|
||||
index.column() == LEVEL_1_CELL ||
|
||||
@@ -279,6 +326,46 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value
|
||||
modified_ = true;
|
||||
modified_cell = SHIELD_CELL;
|
||||
}
|
||||
else if (column_ == COLOR_CELL &&
|
||||
role == Qt::EditRole)
|
||||
{
|
||||
//An empty text remove the color, an unknown text is ignored.
|
||||
//The text can be a name of the palette (gray, blue, green/yellow...),
|
||||
//or a color "#rrggbb" or "#rrggbb/#rrggbb"
|
||||
QColor color_, stripe_;
|
||||
if (TerminalColor::parse(value.toString(), &color_, &stripe_) &&
|
||||
(mrtd.color_ != color_ || mrtd.stripe_color_ != stripe_))
|
||||
{
|
||||
mrtd.color_ = color_;
|
||||
mrtd.stripe_color_ = stripe_;
|
||||
modified_ = true;
|
||||
modified_cell = COLOR_CELL;
|
||||
}
|
||||
}
|
||||
else if (column_ == SECTION_CELL &&
|
||||
role == Qt::EditRole)
|
||||
{
|
||||
bool ok_ = false;
|
||||
const auto section_ = parsePositiveNumber(value.toString(), &ok_);
|
||||
if (ok_ && !qFuzzyCompare(1 + mrtd.section_, 1 + section_))
|
||||
{
|
||||
mrtd.section_ = section_;
|
||||
modified_ = true;
|
||||
modified_cell = SECTION_CELL;
|
||||
}
|
||||
}
|
||||
else if (column_ == WIDTH_CELL &&
|
||||
role == Qt::EditRole)
|
||||
{
|
||||
bool ok_ = false;
|
||||
const auto width_ = parsePositiveNumber(value.toString(), &ok_);
|
||||
if (ok_ && !qFuzzyCompare(1 + mrtd.width_mm_, 1 + width_))
|
||||
{
|
||||
mrtd.width_mm_ = width_;
|
||||
modified_ = true;
|
||||
modified_cell = WIDTH_CELL;
|
||||
}
|
||||
}
|
||||
|
||||
//Set the modification to the terminal data
|
||||
if (modified_)
|
||||
@@ -326,6 +413,9 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation
|
||||
case FUNCTION_CELL : return tr("Function");
|
||||
case LED_CELL: return tr("led");
|
||||
case SHIELD_CELL: return tr("Shield");
|
||||
case COLOR_CELL: return tr("Color");
|
||||
case SECTION_CELL: return tr("Section (mm²)");
|
||||
case WIDTH_CELL: return tr("Width (mm)");
|
||||
default : return QVariant();
|
||||
}
|
||||
}
|
||||
@@ -340,7 +430,8 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const
|
||||
|
||||
auto c = index.column();
|
||||
if (c == LABEL_CELL || c == TYPE_CELL || c == FUNCTION_CELL
|
||||
|| c == CABLE_CELL || c == CABLE_WIRE_CELL)
|
||||
|| 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) {
|
||||
flags = flags | Qt::ItemIsUserCheckable;
|
||||
@@ -819,6 +910,40 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
|
||||
* and a spinbox to edit the level of a terminal
|
||||
**********************************************************/
|
||||
|
||||
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; };
|
||||
const WidthEntry WIDTH_ENTRIES[] {
|
||||
{5.1, "Weidmüller WDU 2.5"},
|
||||
{5.2, "WAGO 2002 (TOPJOB S)"},
|
||||
{6.0, "ABB Entrelec M 4/6"},
|
||||
{6.1, "Weidmüller WDU 4"},
|
||||
{6.2, "Phoenix Contact UT 4"},
|
||||
{8.0, "ABB Entrelec M 6/8, M 4/8"},
|
||||
{8.2, "Phoenix Contact UT 6"},
|
||||
{10.0, "ABB Entrelec M 10/10"},
|
||||
{10.2, "Phoenix Contact UT 10"},
|
||||
{11.9, "Weidmüller WDU 16/ZA"},
|
||||
{12.2, "Phoenix Contact UT 16"},
|
||||
{16.0, "Phoenix Contact UT 35, Weidmüller WDU 35N"},
|
||||
{26.0, "ABB Entrelec M 35/26.FF"},
|
||||
{31.0, "ABB Entrelec M 70/31.AF"},
|
||||
{35.0, "ABB Entrelec M 120/35.F"},
|
||||
{42.0, "ABB Entrelec M 300/42.FF"}
|
||||
};
|
||||
|
||||
QString widthItemText(double mm, const QString &label = QString())
|
||||
{
|
||||
const auto text_ = QCoreApplication::translate("TerminalStripModelDelegate", "%1 mm").arg(QLocale().toString(mm, 'g', 6));
|
||||
return label.isEmpty() ? text_ : text_ + QStringLiteral(" - ") + label;
|
||||
}
|
||||
}
|
||||
|
||||
TerminalStripModelDelegate::TerminalStripModelDelegate(QObject *parent) :
|
||||
QStyledItemDelegate(parent)
|
||||
{}
|
||||
@@ -850,10 +975,125 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO
|
||||
|
||||
return qcb;
|
||||
}
|
||||
if (index.column() == SECTION_CELL) {
|
||||
auto qcb = new QComboBox(parent);
|
||||
qcb->setObjectName(QStringLiteral("terminal_section"));
|
||||
qcb->addItem(tr("None (default)"), 0.0);
|
||||
//Usual sections, in mm2
|
||||
static const QVector<double> sections_ {0.5, 0.75, 1, 1.5, 2.5, 4, 6, 10, 16, 25, 35, 50, 70, 95, 120, 150, 185, 240};
|
||||
for (const auto section_ : sections_) {
|
||||
qcb->addItem(tr("%1 mm²").arg(QLocale().toString(section_, 'g', 6)), section_);
|
||||
}
|
||||
|
||||
return qcb;
|
||||
}
|
||||
if (index.column() == WIDTH_CELL) {
|
||||
auto qcb = new QComboBox(parent);
|
||||
qcb->setObjectName(QStringLiteral("terminal_width"));
|
||||
qcb->addItem(tr("None (default)"), 0.0);
|
||||
for (const auto &entry : WIDTH_ENTRIES) {
|
||||
qcb->addItem(widthItemText(entry.mm, QString::fromUtf8(entry.label)), entry.mm);
|
||||
}
|
||||
|
||||
return qcb;
|
||||
}
|
||||
if (index.column() == COLOR_CELL) {
|
||||
auto qcb = new QComboBox(parent);
|
||||
qcb->setObjectName(QStringLiteral("terminal_color"));
|
||||
qcb->addItem(tr("None (default)"), QString());
|
||||
for (const auto &entry : TerminalColor::palette())
|
||||
{
|
||||
const auto spec_ = TerminalColor::specOf(entry);
|
||||
QColor main_, stripe_;
|
||||
TerminalColor::parse(spec_, &main_, &stripe_);
|
||||
qcb->addItem(QIcon(TerminalColor::swatch(main_, stripe_)),
|
||||
TerminalColor::translatedName(entry),
|
||||
spec_);
|
||||
}
|
||||
|
||||
return qcb;
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||
}
|
||||
|
||||
void TerminalStripModelDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid() &&
|
||||
editor->objectName() == QLatin1String("terminal_color"))
|
||||
{
|
||||
if (auto qcb = dynamic_cast<QComboBox *>(editor))
|
||||
{
|
||||
const auto spec_ = index.data(Qt::EditRole).toString();
|
||||
auto pos_ = qcb->findData(spec_);
|
||||
if (pos_ < 0)
|
||||
{
|
||||
//The color is not in the palette (typed or pasted), keep it in the list
|
||||
QColor main_, stripe_;
|
||||
TerminalColor::parse(spec_, &main_, &stripe_);
|
||||
qcb->addItem(QIcon(TerminalColor::swatch(main_, stripe_)), spec_, spec_);
|
||||
pos_ = qcb->count() - 1;
|
||||
}
|
||||
qcb->setCurrentIndex(pos_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (index.isValid() &&
|
||||
editor->objectName() == QLatin1String("terminal_section"))
|
||||
{
|
||||
if (auto qcb = dynamic_cast<QComboBox *>(editor))
|
||||
{
|
||||
bool ok_ = false;
|
||||
const auto section_ = parsePositiveNumber(index.data(Qt::EditRole).toString(), &ok_);
|
||||
auto pos_ = -1;
|
||||
for (auto i = 0 ; i < qcb->count() ; ++i)
|
||||
{
|
||||
if (qFuzzyCompare(1 + qcb->itemData(i).toDouble(), 1 + section_)) {
|
||||
pos_ = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos_ < 0)
|
||||
{
|
||||
//The section is not in the list (typed or pasted), keep it in the list
|
||||
qcb->addItem(tr("%1 mm²").arg(QLocale().toString(section_, 'g', 6)), section_);
|
||||
pos_ = qcb->count() - 1;
|
||||
}
|
||||
qcb->setCurrentIndex(pos_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (index.isValid() &&
|
||||
editor->objectName() == QLatin1String("terminal_width"))
|
||||
{
|
||||
if (auto qcb = dynamic_cast<QComboBox *>(editor))
|
||||
{
|
||||
bool ok_ = false;
|
||||
const auto width_ = parsePositiveNumber(index.data(Qt::EditRole).toString(), &ok_);
|
||||
auto pos_ = -1;
|
||||
for (auto i = 0 ; i < qcb->count() ; ++i)
|
||||
{
|
||||
if (qFuzzyCompare(1 + qcb->itemData(i).toDouble(), 1 + width_)) {
|
||||
pos_ = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos_ < 0)
|
||||
{
|
||||
//The width is not in the list (typed or pasted), keep it in the list
|
||||
qcb->addItem(widthItemText(width_), width_);
|
||||
pos_ = qcb->count() - 1;
|
||||
}
|
||||
qcb->setCurrentIndex(pos_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QStyledItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
|
||||
void TerminalStripModelDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
@@ -870,6 +1110,24 @@ void TerminalStripModelDelegate::setModelData(QWidget *editor, QAbstractItemMode
|
||||
model->setData(index, qcb->currentData(), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
else if (editor->objectName() == QLatin1String("terminal_section"))
|
||||
{
|
||||
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
|
||||
model->setData(index, qcb->currentData().toDouble(), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
else if (editor->objectName() == QLatin1String("terminal_width"))
|
||||
{
|
||||
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
|
||||
model->setData(index, qcb->currentData().toDouble(), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
else if (editor->objectName() == QLatin1String("terminal_color"))
|
||||
{
|
||||
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
|
||||
model->setData(index, qcb->currentData(), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
else {
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user