Implement slave contact groups — label transfer, terminal assignment and UI fixes

This commit is contained in:
Kellermorph
2026-07-17 09:47:32 +02:00
parent b543adcb46
commit b025bd205d
29 changed files with 1305 additions and 31 deletions
+100 -14
View File
@@ -49,18 +49,7 @@ bool ElementData::fromXml(const QDomElement &xml_element)
return false;
}
// --- OUR DEBUG BLOCK STARTS HERE ---
// We retrieve the string from the XML and store it temporarily
QString raw_type_string = xml_element.attribute(QStringLiteral("link_type"), QStringLiteral("simple"));
qDebug() << "\n=== NEW COMPONENT IS LOADING ===";
qDebug() << "[XML Parser] Raw “link_type” string from the .elmt file:" << raw_type_string;
// Now well pass it on to your translation function
m_type = typeFromString(raw_type_string);
qDebug() << "[XML Parser] Translated ElementData type:" << typeToString(m_type);
// --- THIS IS WHERE OUR DEBUG BLOCK ENDS ---
m_type = typeFromString(xml_element.attribute(QStringLiteral("link_type"), QStringLiteral("simple")));
kindInfoFromXml(xml_element);
m_informations.fromXml(xml_element.firstChildElement(QStringLiteral("elementInformations")),
@@ -98,6 +87,31 @@ QDomElement ElementData::kindInfoToXml(QDomDocument &document)
returned_elmt.appendChild(xml_max_slaves);
}
// Save slave contact groups if enabled
if (m_slave_contact_groups_enabled) {
auto xml_groups = document.createElement(QStringLiteral("slaveContactGroups"));
for (const auto &group : m_slave_contact_groups) {
auto xml_group = document.createElement(QStringLiteral("group"));
xml_group.setAttribute(QStringLiteral("type"),
slaveStateToString(group.type));
xml_group.setAttribute(QStringLiteral("subtype"),
slaveTypeToString(group.subtype));
xml_group.setAttribute(QStringLiteral("contactCount"),
group.contactCount);
xml_group.setAttribute(QStringLiteral("terminalCount"),
group.terminalCount);
for (const auto &label : group.labels) {
auto xml_label = document.createElement(QStringLiteral("label"));
auto label_txt = document.createTextNode(label);
xml_label.appendChild(label_txt);
xml_group.appendChild(xml_label);
}
xml_groups.appendChild(xml_group);
}
returned_elmt.appendChild(xml_groups);
}
}
else if (m_type == ElementData::Slave)
{
@@ -247,6 +261,15 @@ bool ElementData::operator==(const ElementData &data) const
if(data.m_master_type != m_master_type) {
return false;
}
if (data.m_max_slaves != m_max_slaves) {
return false;
}
if (data.m_slave_contact_groups_enabled != m_slave_contact_groups_enabled) {
return false;
}
if (data.m_slave_contact_groups != m_slave_contact_groups) {
return false;
}
}
else if (data.m_type == ElementData::Slave) {
if (data.m_slave_state != m_slave_state ||
@@ -591,7 +614,7 @@ void ElementData::kindInfoFromXml(const QDomElement &xml_element)
m_max_slaves = dom_elmt.text().toInt();
}
}
else if (m_type == ElementData::Slave ) {
else if (m_type == ElementData::Slave) {
if (name == QLatin1String("type")) {
m_slave_type = slaveTypeFromString(dom_elmt.text());
} else if (name == QLatin1String("state")) {
@@ -606,8 +629,71 @@ void ElementData::kindInfoFromXml(const QDomElement &xml_element)
} else if (name == QLatin1String("function")) {
m_terminal_function = terminalFunctionFromString(dom_elmt.text());
}
}
}
}
// Parse slave contact groups for Master elements
if (m_type == ElementData::Master) {
auto xml_kind = xml_element.firstChildElement(QStringLiteral("kindInformations"));
auto xml_groups = xml_kind.firstChildElement(QStringLiteral("slaveContactGroups"));
if (!xml_groups.isNull()) {
m_slave_contact_groups_enabled = true;
auto group_list = QETXML::findInDomElement(xml_groups, QStringLiteral("group"));
for (const auto &xml_group : group_list) {
SlaveContactGroup group;
group.type = slaveStateFromString(
xml_group.attribute(QStringLiteral("type"), QStringLiteral("NO")));
group.subtype = slaveTypeFromString(
xml_group.attribute(QStringLiteral("subtype"), QStringLiteral("simple")));
group.contactCount = xml_group.attribute(
QStringLiteral("contactCount"), QStringLiteral("1")).toInt();
group.terminalCount = xml_group.attribute(
QStringLiteral("terminalCount"), QStringLiteral("1")).toInt();
auto label_list = QETXML::findInDomElement(xml_group, QStringLiteral("label"));
for (const auto &xml_label : label_list) {
group.labels.append(xml_label.text());
}
m_slave_contact_groups.append(group);
}
}
}
}
/**
* @brief ElementData::slaveContactGroupTypeToString
* Convert a SlaveState to string for XML storage in slave contact groups.
* Maps: NO -> "NO", NC -> "NC", SW -> "SW", Other -> "Other"
*/
QString ElementData::slaveContactGroupTypeToString(ElementData::SlaveState type)
{
return slaveStateToString(type);
}
/**
* @brief ElementData::slaveContactGroupTypeFromString
* Convert a string from XML to SlaveState for slave contact groups.
*/
ElementData::SlaveState ElementData::slaveContactGroupTypeFromString(const QString &string)
{
return slaveStateFromString(string);
}
/**
* @brief ElementData::slaveContactGroupSubtypeToString
* Convert a SlaveType to string for XML storage in slave contact groups.
*/
QString ElementData::slaveContactGroupSubtypeToString(ElementData::SlaveType type)
{
return slaveTypeToString(type);
}
/**
* @brief ElementData::slaveContactGroupSubtypeFromString
* Convert a string from XML to SlaveType for slave contact groups.
*/
ElementData::SlaveType ElementData::slaveContactGroupSubtypeFromString(const QString &string)
{
return slaveTypeFromString(string);
}
+35
View File
@@ -22,6 +22,9 @@
#include "../diagramcontext.h"
#include "../NameList/nameslist.h"
#include <QStringList>
#include <QVector>
/**
* @brief The ElementData class
* WARNING
@@ -86,6 +89,31 @@ class ElementData : public PropertiesInterface
};
Q_ENUM(TerminalFunction)
/**
* @brief The SlaveContactGroup struct
* Defines a contact group that a master element provides for slave elements.
* Each group specifies the type, subtype, number of displayed contacts,
* number of terminals, and the labels for each terminal (T1-T20).
*/
struct SlaveContactGroup {
SlaveState type = NO; ///< Contact type (NO/NC/SW/Other)
SlaveType subtype = SSimple; ///< Contact subtype (Simple/Power/Delay*)
int contactCount = 1; ///< Number of displayed contacts
int terminalCount = 1; ///< Number of terminals (Anschlüsse)
QStringList labels; ///< Terminal labels (T1-T20), max 20 entries
bool operator==(const SlaveContactGroup &other) const {
return type == other.type
&& subtype == other.subtype
&& contactCount == other.contactCount
&& terminalCount == other.terminalCount
&& labels == other.labels;
}
bool operator!=(const SlaveContactGroup &other) const {
return !(*this == other);
}
};
ElementData() {}
~ElementData() override {}
@@ -130,12 +158,19 @@ class ElementData : public PropertiesInterface
static ElementData::TerminalFunction terminalFunctionFromString(const QString &string);
static QString translatedTerminalFunction(ElementData::TerminalFunction function);
static QString slaveContactGroupTypeToString(ElementData::SlaveState type);
static ElementData::SlaveState slaveContactGroupTypeFromString(const QString &string);
static QString slaveContactGroupSubtypeToString(ElementData::SlaveType type);
static ElementData::SlaveType slaveContactGroupSubtypeFromString(const QString &string);
// must be public, because this class is a private member
// of Element/ element editor and they must access this data
ElementData::Type m_type = ElementData::Simple;
ElementData::MasterType m_master_type = ElementData::Coil;
int m_max_slaves{-1};
bool m_slave_contact_groups_enabled{false}; ///< Whether slave contact groups table is active
QVector<SlaveContactGroup> m_slave_contact_groups; ///< Contact groups defined by master
ElementData::SlaveType m_slave_type = ElementData::SSimple;
ElementData::SlaveState m_slave_state = ElementData::NO;
+10
View File
@@ -125,6 +125,12 @@ QDomElement TerminalData::toXml(QDomDocument &xml_document) const
xml_element.setAttribute("label_color", m_label_color.name());
}
// Save master label override settings
if (m_use_master_label) {
xml_element.setAttribute("use_master_label", "true");
xml_element.setAttribute("master_label_index", m_master_label_index);
}
return(xml_element);
}
@@ -197,6 +203,10 @@ bool TerminalData::fromXml (const QDomElement &xml_element)
m_label_color = QColor(color_str);
}
// Read master label override settings
m_use_master_label = (xml_element.attribute("use_master_label") == QLatin1String("true"));
m_master_label_index = xml_element.attribute("master_label_index", "0").toInt();
return true;
}
+5
View File
@@ -134,6 +134,11 @@ class TerminalData : public PropertiesInterface
/// Color of the text label
QColor m_label_color = Qt::black;
/// Whether this terminal uses a label from the master's contact group
bool m_use_master_label = false;
/// Index into the master's contact group labels (T1=0, T2=1, ..., T20=19)
int m_master_label_index = 0;
private:
QGraphicsObject* q{nullptr};
};