From 5296c1b478bd12a7644ce397cb97c9abf3e067ee Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Mon, 30 Mar 2026 21:13:26 +0200 Subject: [PATCH 01/20] Change initialization of m_max_slaves and m_contact_count --- sources/properties/elementdata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/properties/elementdata.h b/sources/properties/elementdata.h index 5402d064b..9596970b8 100644 --- a/sources/properties/elementdata.h +++ b/sources/properties/elementdata.h @@ -134,7 +134,7 @@ class ElementData : public PropertiesInterface ElementData::Type m_type = ElementData::Simple; ElementData::MasterType m_master_type = ElementData::Coil; - int m_max_slaves = -1; + int m_max_slaves{-1}; ElementData::SlaveType m_slave_type = ElementData::SSimple; ElementData::SlaveState m_slave_state = ElementData::NO; @@ -142,7 +142,7 @@ class ElementData : public PropertiesInterface ElementData::TerminalType m_terminal_type = ElementData::TTGeneric; ElementData::TerminalFunction m_terminal_function = ElementData::TFGeneric; - int m_contact_count = 1; + int m_contact_count{1}; DiagramContext m_informations; NamesList m_names_list; QString m_drawing_information; From 9149128f7afcda6fc47850badd718df620850ce6 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Mon, 30 Mar 2026 21:14:10 +0200 Subject: [PATCH 02/20] Refactor comments and improve code formatting --- sources/ui/masterpropertieswidget.cpp | 332 +++++++++++++------------- 1 file changed, 168 insertions(+), 164 deletions(-) diff --git a/sources/ui/masterpropertieswidget.cpp b/sources/ui/masterpropertieswidget.cpp index d1a346695..3e152c2bd 100644 --- a/sources/ui/masterpropertieswidget.cpp +++ b/sources/ui/masterpropertieswidget.cpp @@ -1,20 +1,20 @@ /* - 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 . -*/ + * 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 "masterpropertieswidget.h" #include "../diagram.h" @@ -25,64 +25,65 @@ #include "ui_masterpropertieswidget.h" #include +#include /** - @brief MasterPropertiesWidget::MasterPropertiesWidget - Default constructor - @param elmt - @param parent -*/ + * @brief MasterPropertiesWidget::MasterPropertiesWidget + * Default constructor + * @param elmt + * @param parent + */ MasterPropertiesWidget::MasterPropertiesWidget(Element *elmt, QWidget *parent) : - AbstractElementPropertiesEditorWidget(parent), - ui(new Ui::MasterPropertiesWidget), - m_project(nullptr) +AbstractElementPropertiesEditorWidget(parent), +ui(new Ui::MasterPropertiesWidget), +m_project(nullptr) { ui->setupUi(this); - + ui->m_free_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu); ui->m_link_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu); - + QStringList list; QSettings settings; if (settings.value("genericpanel/folio", false).toBool()) { list << tr("Vignette") - << tr("Label de folio") - << tr("Titre de folio") - << tr("Position"); + << tr("Label de folio") + << tr("Titre de folio") + << tr("Position"); } else { list << tr("Vignette") - << tr("N° de folio") - << tr("Titre de folio") - << tr("Position"); + << tr("N° de folio") + << tr("Titre de folio") + << tr("Position"); } ui->m_free_tree_widget->setHeaderLabels(list); ui->m_link_tree_widget->setHeaderLabels(list); - + m_context_menu = new QMenu(this); m_link_action = new QAction(tr("Lier l'élément"), this); m_unlink_action = new QAction(tr("Délier l'élément"), this); m_show_qtwi = new QAction(tr("Montrer l'élément"), this); m_show_element = new QAction(tr("Montrer l'élément maître"), this); m_save_header_state = new QAction(tr("Enregistrer la disposition"), this); - + connect(ui->m_free_tree_widget, &QTreeWidget::itemDoubleClicked, - this, &MasterPropertiesWidget::showElementFromTWI); + this, &MasterPropertiesWidget::showElementFromTWI); connect(ui->m_link_tree_widget, &QTreeWidget::itemDoubleClicked, - this, &MasterPropertiesWidget::showElementFromTWI); - + this, &MasterPropertiesWidget::showElementFromTWI); + connect(ui->m_free_tree_widget, &QTreeWidget::customContextMenuRequested, - [this](QPoint point) {this->customContextMenu(point, 1);}); + [this](QPoint point) {this->customContextMenu(point, 1);}); connect(ui->m_link_tree_widget, &QTreeWidget::customContextMenuRequested, - [this](QPoint point) {this->customContextMenu(point, 2);}); - + [this](QPoint point) {this->customContextMenu(point, 2);}); + connect(m_link_action, &QAction::triggered, - this, &MasterPropertiesWidget::on_link_button_clicked); + this, &MasterPropertiesWidget::on_link_button_clicked); connect(m_unlink_action, &QAction::triggered, - this, &MasterPropertiesWidget::on_unlink_button_clicked); + this, &MasterPropertiesWidget::on_unlink_button_clicked); connect(m_show_qtwi, &QAction::triggered, - [this]() {this->showElementFromTWI(this->m_qtwi_at_context_menu,0);}); - + [this]() {this->showElementFromTWI(this->m_qtwi_at_context_menu,0);}); + connect(m_show_element, &QAction::triggered, [this]() { this->m_element->diagram()->showMe(); @@ -90,46 +91,46 @@ MasterPropertiesWidget::MasterPropertiesWidget(Element *elmt, QWidget *parent) : if(this->m_showed_element) m_showed_element->setHighlighted(false); }); - + QHeaderView *qhv = ui->m_free_tree_widget->header(); qhv->setContextMenuPolicy(Qt::CustomContextMenu); connect(qhv, &QHeaderView::customContextMenuRequested, - this, &MasterPropertiesWidget::headerCustomContextMenuRequested); + this, &MasterPropertiesWidget::headerCustomContextMenuRequested); connect(m_save_header_state, &QAction::triggered, [qhv]() { QByteArray qba = qhv->saveState(); QSettings settings; settings.setValue("link-element-widget/master-state", qba); }); - + setElement(elmt); } /** - @brief MasterPropertiesWidget::~MasterPropertiesWidget - Destructor -*/ + * @brief MasterPropertiesWidget::~MasterPropertiesWidget + * Destructor + */ MasterPropertiesWidget::~MasterPropertiesWidget() { if (m_showed_element) m_showed_element->setHighlighted(false); - + if(m_element) m_element->setHighlighted(false); - + delete ui; } /** - @brief MasterPropertiesWidget::setElement - Set the element to be edited - @param element -*/ + * @brief MasterPropertiesWidget::setElement + * Set the element to be edited + * @param element + */ void MasterPropertiesWidget::setElement(Element *element) { if (m_element == element) return; - + if (m_showed_element) { m_showed_element->setHighlighted(false); @@ -137,40 +138,40 @@ void MasterPropertiesWidget::setElement(Element *element) } if (m_element) m_element->setHighlighted(false); - + if (m_project) disconnect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), - this, SLOT(diagramWasdeletedFromProject())); + this, SLOT(diagramWasdeletedFromProject())); - if(Q_LIKELY(element->diagram() && element->diagram()->project())) - { - m_project = element->diagram()->project(); - connect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), - this, SLOT(diagramWasdeletedFromProject())); - } - else - m_project = nullptr; + if(Q_LIKELY(element->diagram() && element->diagram()->project())) + { + m_project = element->diagram()->project(); + connect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), + this, SLOT(diagramWasdeletedFromProject())); + } + else + m_project = nullptr; //Keep up to date this widget when the linked elements of m_element change if (m_element) disconnect(m_element.data(), &Element::linkedElementChanged, - this, &MasterPropertiesWidget::updateUi); - - m_element = element; + this, &MasterPropertiesWidget::updateUi); + + m_element = element; connect(m_element.data(), &Element::linkedElementChanged, - this, &MasterPropertiesWidget::updateUi); + this, &MasterPropertiesWidget::updateUi); updateUi(); } /** - @brief MasterPropertiesWidget::apply - If link between edited element and other change, - apply the change with a QUndoCommand (got with method associatedUndo) - pushed to the stack of element project. - Return true if link change, else false - @note is void no Return ??? -*/ + * @brief MasterPropertiesWidget::apply + * If link between edited element and other change, + * apply the change with a QUndoCommand (got with method associatedUndo) + * pushed to the stack of element project. + * Return true if link change, else false + * @note is void no Return ??? + */ void MasterPropertiesWidget::apply() { if (QUndoCommand *undo = associatedUndo()) @@ -178,25 +179,25 @@ void MasterPropertiesWidget::apply() } /** - @brief MasterPropertiesWidget::reset - Reset current widget, clear eveything and rebuild widget. -*/ + * @brief MasterPropertiesWidget::reset + * Reset current widget, clear eveything and rebuild widget. + */ void MasterPropertiesWidget::reset() { foreach (QTreeWidgetItem *qtwi, m_qtwi_hash.keys()) delete qtwi; - + m_qtwi_hash.clear(); updateUi(); } /** - @brief MasterPropertiesWidget::associatedUndo - If link between the edited element and other change, - return a QUndoCommand with this change. - If no change return nullptr. - @return -*/ + * @brief MasterPropertiesWidget::associatedUndo + * If link between the edited element and other change, + * return a QUndoCommand with this change. + * If no change return nullptr. + * @return + */ QUndoCommand* MasterPropertiesWidget::associatedUndo() const { QList to_link; @@ -205,7 +206,7 @@ QUndoCommand* MasterPropertiesWidget::associatedUndo() const for (int i=0; im_link_tree_widget->topLevelItemCount(); i++) to_link << m_qtwi_hash[ui->m_link_tree_widget->topLevelItem(i)]; - //The two list contain the same element, there is no change + //The two list contain the same element, there is no change if (to_link.size() == linked_.size()) { bool equal = true; @@ -229,11 +230,11 @@ QUndoCommand* MasterPropertiesWidget::associatedUndo() const } /** - @brief MasterPropertiesWidget::setLiveEdit - @param live_edit = true : live edit is enable - else false : live edit is disable. - @return always true because live edit is handled by this editor widget -*/ + * @brief MasterPropertiesWidget::setLiveEdit + * @param live_edit = true : live edit is enable + * else false : live edit is disable. + * @return always true because live edit is handled by this editor widget + */ bool MasterPropertiesWidget::setLiveEdit(bool live_edit) { m_live_edit = live_edit; @@ -241,9 +242,9 @@ bool MasterPropertiesWidget::setLiveEdit(bool live_edit) } /** - @brief MasterPropertiesWidget::updateUi - Build the interface of the widget -*/ + * @brief MasterPropertiesWidget::updateUi + * Build the interface of the widget + */ void MasterPropertiesWidget::updateUi() { ui->m_free_tree_widget->clear(); @@ -256,75 +257,75 @@ void MasterPropertiesWidget::updateUi() ElementProvider elmt_prov(m_project); QSettings settings; - //Build the list of free available element + //Build the list of free available element QList items_list; for(const auto &elmt : elmt_prov.freeElement(ElementData::Slave)) { QTreeWidgetItem *qtwi = new QTreeWidgetItem(ui->m_free_tree_widget); qtwi->setIcon(0, elmt->pixmap()); - + if(settings.value("genericpanel/folio", false).toBool()) { autonum::sequentialNumbers seq; QString F =autonum::AssignVariables::formulaToLabel( - elmt->diagram()->border_and_titleblock.folio(), - seq, - elmt->diagram(), - elmt); + elmt->diagram()->border_and_titleblock.folio(), + seq, + elmt->diagram(), + elmt); qtwi->setText(1, F); } else { qtwi->setText(1, QString::number( - elmt->diagram()->folioIndex() - + 1)); + elmt->diagram()->folioIndex() + + 1)); } - + qtwi->setText(2, elmt->diagram()->title()); qtwi->setText(4, elmt->diagram()->convertPosition( - elmt->scenePos()).toString()); + elmt->scenePos()).toString()); items_list.append(qtwi); m_qtwi_hash.insert(qtwi, elmt); } - + ui->m_free_tree_widget->addTopLevelItems(items_list); items_list.clear(); - //Build the list of already linked element + //Build the list of already linked element const QList link_list = m_element->linkedElements(); for(Element *elmt : link_list) { QTreeWidgetItem *qtwi = new QTreeWidgetItem(ui->m_link_tree_widget); qtwi->setIcon(0, elmt->pixmap()); - + if(settings.value("genericpanel/folio", false).toBool()) { autonum::sequentialNumbers seq; QString F =autonum::AssignVariables::formulaToLabel( - elmt->diagram()->border_and_titleblock.folio(), - seq, - elmt->diagram(), - elmt); + elmt->diagram()->border_and_titleblock.folio(), + seq, + elmt->diagram(), + elmt); qtwi->setText(1, F); } else { qtwi->setText(1, QString::number( - elmt->diagram()->folioIndex() - + 1)); + elmt->diagram()->folioIndex() + + 1)); } qtwi->setText(2, elmt->diagram()->title()); qtwi->setText(3, elmt->diagram()->convertPosition( - elmt->scenePos()).toString()); + elmt->scenePos()).toString()); items_list.append(qtwi); m_qtwi_hash.insert(qtwi, elmt); } - + if(items_list.count()) ui->m_link_tree_widget->addTopLevelItems(items_list); - + QVariant v = settings.value("link-element-widget/master-state"); if(!v.isNull()) { @@ -334,9 +335,9 @@ void MasterPropertiesWidget::updateUi() } /** - @brief MasterPropertiesWidget::headerCustomContextMenuRequested - @param pos -*/ + * @brief MasterPropertiesWidget::headerCustomContextMenuRequested + * @param pos + */ void MasterPropertiesWidget::headerCustomContextMenuRequested(const QPoint &pos) { m_context_menu->clear(); @@ -344,31 +345,33 @@ void MasterPropertiesWidget::headerCustomContextMenuRequested(const QPoint &pos) m_context_menu->popup(ui->m_free_tree_widget->header()->mapToGlobal(pos)); } -/** - @brief MasterPropertiesWidget::on_link_button_clicked - move current item in the free_list to linked_list -*/ /** * @brief MasterPropertiesWidget::on_link_button_clicked - * move current item in the free_list to linked_list + * Moves the current item from the free_list to the linked_list, + * provided the master's slave limit has not been reached. */ void MasterPropertiesWidget::on_link_button_clicked() { - // --- NEU: Prüfen, ob das Master-Limit im UI bereits erreicht ist --- + // Get the maximum number of allowed slaves from the element's information QVariant max_slaves_variant = m_element->kindInformations().value("max_slaves"); if (max_slaves_variant.isValid() && !max_slaves_variant.toString().isEmpty()) { int max_slaves = max_slaves_variant.toInt(); + int current_slaves = ui->m_link_tree_widget->topLevelItemCount(); - // Wir zählen, wie viele Elemente schon in der "Verbunden"-Liste liegen - if (max_slaves != -1 && ui->m_link_tree_widget->topLevelItemCount() >= max_slaves) { - // Limit erreicht! Wir brechen die Aktion einfach ab. + // If a limit is set and reached + if (max_slaves != -1 && current_slaves >= max_slaves) { + + + // Show a message box with the actual window as parent to ensure it's on top + QMessageBox::warning(this->window(), + tr("Maximum Slaves Reached"), + tr("This master element cannot accept any new slaves because it is full (Limit: %1).").arg(max_slaves)); return; } } - // ------------------------------------------------------------------- - //take the current item from free_list and push it to linked_list + // Move current item from free_list to linked_list QTreeWidgetItem *qtwi = ui->m_free_tree_widget->currentItem(); if (qtwi) { @@ -381,18 +384,19 @@ void MasterPropertiesWidget::on_link_button_clicked() } } + /** - @brief MasterPropertiesWidget::on_unlink_button_clicked - move current item in linked_list to free_list -*/ + * @brief MasterPropertiesWidget::on_unlink_button_clicked + * move current item in linked_list to free_list + */ void MasterPropertiesWidget::on_unlink_button_clicked() { - //take the current item from linked_list and push it to free_list + //take the current item from linked_list and push it to free_list QTreeWidgetItem *qtwi = ui->m_link_tree_widget->currentItem(); if(qtwi) { ui->m_link_tree_widget->takeTopLevelItem( - ui->m_link_tree_widget->indexOfTopLevelItem(qtwi)); + ui->m_link_tree_widget->indexOfTopLevelItem(qtwi)); ui->m_free_tree_widget->insertTopLevelItem(0, qtwi); if(m_live_edit) @@ -401,18 +405,18 @@ void MasterPropertiesWidget::on_unlink_button_clicked() } /** - @brief MasterPropertiesWidget::showElementFromTWI - Show the element corresponding to the given QTreeWidgetItem - @param qtwi - @param column -*/ + * @brief MasterPropertiesWidget::showElementFromTWI + * Show the element corresponding to the given QTreeWidgetItem + * @param qtwi + * @param column + */ void MasterPropertiesWidget::showElementFromTWI(QTreeWidgetItem *qtwi, int column) { Q_UNUSED(column); if (m_showed_element) { disconnect(m_showed_element, SIGNAL(destroyed()), - this, SLOT(showedElementWasDeleted())); + this, SLOT(showedElementWasDeleted())); m_showed_element -> setHighlighted(false); } if (m_element) @@ -422,23 +426,23 @@ void MasterPropertiesWidget::showElementFromTWI(QTreeWidgetItem *qtwi, int colum m_showed_element->diagram()->showMe(); m_showed_element->setHighlighted(true); connect(m_showed_element, SIGNAL(destroyed()), - this, SLOT(showedElementWasDeleted())); + this, SLOT(showedElementWasDeleted())); } /** - @brief MasterPropertiesWidget::showedElementWasDeleted - Set to nullptr the current showed element when he was deleted -*/ + * @brief MasterPropertiesWidget::showedElementWasDeleted + * Set to nullptr the current showed element when he was deleted + */ void MasterPropertiesWidget::showedElementWasDeleted() { m_showed_element = nullptr; } /** - @brief MasterPropertiesWidget::diagramWasdeletedFromProject - This slot is called when a diagram is removed from the parent project - of edited element to update the content of this widget -*/ + * @brief MasterPropertiesWidget::diagramWasdeletedFromProject + * This slot is called when a diagram is removed from the parent project + * of edited element to update the content of this widget + */ void MasterPropertiesWidget::diagramWasdeletedFromProject() { // We use a timer because if the removed diagram @@ -449,11 +453,11 @@ void MasterPropertiesWidget::diagramWasdeletedFromProject() } /** - @brief MasterPropertiesWidget::customContextMenu - Display a context menu - @param pos - @param i : the tree widget where the context menu was requested. -*/ + * @brief MasterPropertiesWidget::customContextMenu + * Display a context menu + * @param pos + * @param i : the tree widget where the context menu was requested. + */ void MasterPropertiesWidget::customContextMenu(const QPoint &pos, int i) { // add the size of the header to display the topleft of the QMenu @@ -462,14 +466,14 @@ void MasterPropertiesWidget::customContextMenu(const QPoint &pos, int i) // section related to QAbstractScrollArea QPoint point = pos; point.ry()+=ui->m_free_tree_widget->header()->height(); - + m_context_menu->clear(); - + if (i == 1) { point = ui->m_free_tree_widget->mapToGlobal(point); - - //Context at for free tree widget + + //Context at for free tree widget if (ui->m_free_tree_widget->currentItem()) { m_qtwi_at_context_menu = ui->m_free_tree_widget->currentItem(); @@ -480,8 +484,8 @@ void MasterPropertiesWidget::customContextMenu(const QPoint &pos, int i) else { point = ui->m_link_tree_widget->mapToGlobal(point); - - //context at for link tre widget + + //context at for link tre widget if (ui->m_link_tree_widget->currentItem()) { m_qtwi_at_context_menu = ui->m_link_tree_widget->currentItem(); @@ -489,7 +493,7 @@ void MasterPropertiesWidget::customContextMenu(const QPoint &pos, int i) m_context_menu->addAction(m_show_qtwi); } } - + m_context_menu->addAction(m_show_element); m_context_menu->popup(point); } From 9344515d2abb4970e6ee6f8eef51235f202faec7 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Mon, 30 Mar 2026 21:14:48 +0200 Subject: [PATCH 03/20] Refactor isFull method to simplify max_slaves logic --- sources/qetgraphicsitem/masterelement.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/sources/qetgraphicsitem/masterelement.cpp b/sources/qetgraphicsitem/masterelement.cpp index 9d5f59f82..64504bb09 100644 --- a/sources/qetgraphicsitem/masterelement.cpp +++ b/sources/qetgraphicsitem/masterelement.cpp @@ -190,27 +190,20 @@ void MasterElement::aboutDeleteXref() */ bool MasterElement::isFull() const { - // Lese das Limit aus den XML-Daten (kindInformations) - // Die value() Funktion im DiagramContext nimmt nur einen Parameter! + // Set default value to -1 (unlimited slaves) + int max_slaves = -1; QVariant max_slaves_variant = kindInformations().value("max_slaves"); - // Wenn der Wert nicht existiert oder leer ist, ist das Bauteil nie voll - if (!max_slaves_variant.isValid() || max_slaves_variant.toString().isEmpty()) { - return false; + // Overwrite default if a valid limit is defined in the element's XML + if (max_slaves_variant.isValid() && !max_slaves_variant.toString().isEmpty()) { + max_slaves = max_slaves_variant.toInt(); } - // In Integer umwandeln - int max_slaves = max_slaves_variant.toInt(); - - // Wenn Limit -1 ist, ist der Master nie voll + // If no limit is set (-1), the master is never full if (max_slaves == -1) { return false; } - // Wenn die Anzahl der verbundenen Elemente größer oder gleich dem Limit ist, ist er voll - if (connected_elements.size() >= max_slaves) { - return true; - } - - return false; + // Return true if current connected elements reached or exceeded the limit + return connected_elements.size() >= max_slaves; } From 0cd71cbe16802da5a45ddac0111c22faaaedcc41 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Mon, 30 Mar 2026 21:15:15 +0200 Subject: [PATCH 04/20] Conditionally save max_slaves if limit is set --- sources/properties/elementdata.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sources/properties/elementdata.cpp b/sources/properties/elementdata.cpp index 944ce3c08..6620afc65 100644 --- a/sources/properties/elementdata.cpp +++ b/sources/properties/elementdata.cpp @@ -77,13 +77,15 @@ QDomElement ElementData::kindInfoToXml(QDomDocument &document) returned_elmt.appendChild(xml_type); - // NEU: max_slaves speichern - auto xml_max_slaves = document.createElement(QStringLiteral("kindInformation")); - xml_max_slaves.setAttribute(QStringLiteral("name"), QStringLiteral("max_slaves")); - auto max_slaves_txt = document.createTextNode(QString::number(m_max_slaves)); - xml_max_slaves.appendChild(max_slaves_txt); + // Save max_slaves only if a specific limit is set (not default -1) + if (m_max_slaves != -1) { + auto xml_max_slaves = document.createElement(QStringLiteral("kindInformation")); + xml_max_slaves.setAttribute(QStringLiteral("name"), QStringLiteral("max_slaves")); + auto max_slaves_txt = document.createTextNode(QString::number(m_max_slaves)); + xml_max_slaves.appendChild(max_slaves_txt); - returned_elmt.appendChild(xml_max_slaves); + returned_elmt.appendChild(xml_max_slaves); + } } else if (m_type == ElementData::Slave) { From 378aa8899f5feaa13e64ea03b4dcb9cc83cfc654 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Mon, 30 Mar 2026 21:16:00 +0200 Subject: [PATCH 05/20] Remove resizing of first column in properties editor Removed resizing of the first column in the information tree. --- sources/editor/ui/elementpropertieseditorwidget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sources/editor/ui/elementpropertieseditorwidget.cpp b/sources/editor/ui/elementpropertieseditorwidget.cpp index e88282fd7..a4eba4e02 100644 --- a/sources/editor/ui/elementpropertieseditorwidget.cpp +++ b/sources/editor/ui/elementpropertieseditorwidget.cpp @@ -164,7 +164,6 @@ void ElementPropertiesEditorWidget::setUpInterface() //Disable the edition of the first column of the information tree //by this little workaround ui->m_tree->setItemDelegate(new EditorDelegate(this)); - ui->m_tree->header()->resizeSection(0, 150); // NEU: Checkbox mit der Zahlenbox verbinden (Aktivieren/Deaktivieren) connect(ui->max_slaves_checkbox, SIGNAL(toggled(bool)), ui->max_slaves_spinbox, SLOT(setEnabled(bool))); From c220d84fcb011430c539825eda88ae9e407b3125 Mon Sep 17 00:00:00 2001 From: Laurent Trinques Date: Tue, 31 Mar 2026 16:23:05 +0200 Subject: [PATCH 06/20] Update elementdata.h --- sources/properties/elementdata.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sources/properties/elementdata.h b/sources/properties/elementdata.h index a0854eb2f..1180e58d2 100644 --- a/sources/properties/elementdata.h +++ b/sources/properties/elementdata.h @@ -134,10 +134,9 @@ class ElementData : public PropertiesInterface ElementData::Type m_type = ElementData::Simple; ElementData::MasterType m_master_type = ElementData::Coil; -<<<<<<< master + int m_max_slaves{-1}; -======= ->>>>>>> master + ElementData::SlaveType m_slave_type = ElementData::SSimple; ElementData::SlaveState m_slave_state = ElementData::NO; From 1bbb374094c1aa2a7431775fcfadaf44cd306d94 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:47:45 +0200 Subject: [PATCH 07/20] Update height and add max slaves options in UI --- .../ui/elementpropertieseditorwidget.ui | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sources/editor/ui/elementpropertieseditorwidget.ui b/sources/editor/ui/elementpropertieseditorwidget.ui index 6c3b33344..f7bf44641 100644 --- a/sources/editor/ui/elementpropertieseditorwidget.ui +++ b/sources/editor/ui/elementpropertieseditorwidget.ui @@ -7,7 +7,7 @@ 0 0 527 - 442 + 492 @@ -104,6 +104,23 @@ + + + + max. Slaves definieren + + + + + + + false + + + 1 + + + From 52f61ab500b6f65c6faaaee4f132d36bb4d55ca5 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:49:21 +0200 Subject: [PATCH 08/20] Refactor max_slaves handling in ElementPropertiesEditor --- .../ui/elementpropertieseditorwidget.cpp | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/sources/editor/ui/elementpropertieseditorwidget.cpp b/sources/editor/ui/elementpropertieseditorwidget.cpp index 218d3be46..a4eba4e02 100644 --- a/sources/editor/ui/elementpropertieseditorwidget.cpp +++ b/sources/editor/ui/elementpropertieseditorwidget.cpp @@ -1,4 +1,4 @@ -/* +/* Copyright 2006-2026 The QElectroTech Team This file is part of QElectroTech. @@ -96,8 +96,18 @@ void ElementPropertiesEditorWidget::upDateInterface() } else if (m_data.m_type == ElementData::Master) { ui->m_master_type_cb->setCurrentIndex( - ui->m_master_type_cb->findData ( - m_data.m_master_type)); + ui->m_master_type_cb->findData ( + m_data.m_master_type)); + + // NEU: Checkbox und Zahlenbox für max_slaves einstellen + if (m_data.m_max_slaves == -1) { + ui->max_slaves_checkbox->setChecked(false); + ui->max_slaves_spinbox->setEnabled(false); + } else { + ui->max_slaves_checkbox->setChecked(true); + ui->max_slaves_spinbox->setEnabled(true); + ui->max_slaves_spinbox->setValue(m_data.m_max_slaves); + } } else if (m_data.m_type == ElementData::Terminal) { ui->m_terminal_type_cb->setCurrentIndex( ui->m_terminal_type_cb->findData( @@ -151,17 +161,14 @@ void ElementPropertiesEditorWidget::setUpInterface() ui->m_terminal_func_cb->addItem(tr("Phase"), ElementData::TFPhase); ui->m_terminal_func_cb->addItem(tr("Neutre"), ElementData::TFNeutral); - //Disable the edition of the first column of the information tree - //by this little workaround -//Disable the edition of the first column of the information tree - //by this little workaround - ui->m_tree->setItemDelegate(new EditorDelegate(this)); - ui->m_tree->header()->resizeSection(0, 150); + //Disable the edition of the first column of the information tree + //by this little workaround + ui->m_tree->setItemDelegate(new EditorDelegate(this)); - // NEU: Checkbox mit der Zahlenbox verbinden (Aktivieren/Deaktivieren) - connect(ui->max_slaves_checkbox, SIGNAL(toggled(bool)), ui->max_slaves_spinbox, SLOT(setEnabled(bool))); + // NEU: Checkbox mit der Zahlenbox verbinden (Aktivieren/Deaktivieren) + connect(ui->max_slaves_checkbox, SIGNAL(toggled(bool)), ui->max_slaves_spinbox, SLOT(setEnabled(bool))); - populateTree(); + populateTree(); } void ElementPropertiesEditorWidget::updateTree() @@ -232,6 +239,13 @@ void ElementPropertiesEditorWidget::on_m_buttonBox_accepted() } else if (m_data.m_type == ElementData::Master) { m_data.m_master_type = ui->m_master_type_cb->currentData().value(); + + // NEU: Wenn Häkchen gesetzt, speichere die Zahl, ansonsten -1 (unendlich) + if (ui->max_slaves_checkbox->isChecked()) { + m_data.m_max_slaves = ui->max_slaves_spinbox->value(); + } else { + m_data.m_max_slaves = -1; + } } else if (m_data.m_type == ElementData::Terminal) { From 79edc3fbb7848226002d7591b7e65520d9725f3b Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:50:22 +0200 Subject: [PATCH 09/20] Clean up whitespace in elementdata.h Removed unnecessary blank lines in elementdata.h --- sources/properties/elementdata.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sources/properties/elementdata.h b/sources/properties/elementdata.h index 1180e58d2..9596970b8 100644 --- a/sources/properties/elementdata.h +++ b/sources/properties/elementdata.h @@ -134,10 +134,8 @@ class ElementData : public PropertiesInterface ElementData::Type m_type = ElementData::Simple; ElementData::MasterType m_master_type = ElementData::Coil; - int m_max_slaves{-1}; - ElementData::SlaveType m_slave_type = ElementData::SSimple; ElementData::SlaveState m_slave_state = ElementData::NO; From 89a4aaac28bac9042cd8eee05d046c35eea82a73 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:50:46 +0200 Subject: [PATCH 10/20] Refactor conditional checks for Master type --- sources/properties/elementdata.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sources/properties/elementdata.cpp b/sources/properties/elementdata.cpp index ceef593d8..6620afc65 100644 --- a/sources/properties/elementdata.cpp +++ b/sources/properties/elementdata.cpp @@ -568,9 +568,12 @@ void ElementData::kindInfoFromXml(const QDomElement &xml_element) } auto name = dom_elmt.attribute(QStringLiteral("name")); - if (m_type == ElementData::Master && - name == QLatin1String("type")) { - m_master_type = masterTypeFromString(dom_elmt.text()); + if (m_type == ElementData::Master) { + if (name == QLatin1String("type")) { + m_master_type = masterTypeFromString(dom_elmt.text()); + } else if (name == QLatin1String("max_slaves")) { + m_max_slaves = dom_elmt.text().toInt(); + } } else if (m_type == ElementData::Slave ) { if (name == QLatin1String("type")) { From 246dd0a42f279f221bddad6fba3582d2e4965585 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:51:32 +0200 Subject: [PATCH 11/20] Refactor MasterElement::isFull for clarity --- sources/qetgraphicsitem/masterelement.cpp | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/sources/qetgraphicsitem/masterelement.cpp b/sources/qetgraphicsitem/masterelement.cpp index f18e307df..64504bb09 100644 --- a/sources/qetgraphicsitem/masterelement.cpp +++ b/sources/qetgraphicsitem/masterelement.cpp @@ -181,7 +181,7 @@ void MasterElement::aboutDeleteXref() delete m_Xref_item; m_Xref_item = nullptr; return; -} + } } /** @@ -190,20 +190,20 @@ void MasterElement::aboutDeleteXref() */ bool MasterElement::isFull() const { - // Set default value to -1 (unlimited slaves) - int max_slaves = -1; - QVariant max_slaves_variant = kindInformations().value("max_slaves"); + // Set default value to -1 (unlimited slaves) + int max_slaves = -1; + QVariant max_slaves_variant = kindInformations().value("max_slaves"); - // Overwrite default if a valid limit is defined in the element's XML - if (max_slaves_variant.isValid() && !max_slaves_variant.toString().isEmpty()) { - max_slaves = max_slaves_variant.toInt(); - } + // Overwrite default if a valid limit is defined in the element's XML + if (max_slaves_variant.isValid() && !max_slaves_variant.toString().isEmpty()) { + max_slaves = max_slaves_variant.toInt(); + } - // If no limit is set (-1), the master is never full - if (max_slaves == -1) { - return false; - } + // If no limit is set (-1), the master is never full + if (max_slaves == -1) { + return false; + } - // Return true if current connected elements reached or exceeded the limit - return connected_elements.size() >= max_slaves; + // Return true if current connected elements reached or exceeded the limit + return connected_elements.size() >= max_slaves; } From ecee2209e637a15e7de8a93dc0c519a53ba33b13 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:51:53 +0200 Subject: [PATCH 12/20] Add isFull method to check Slave-Limit --- sources/qetgraphicsitem/masterelement.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/qetgraphicsitem/masterelement.h b/sources/qetgraphicsitem/masterelement.h index 19ceb9aaf..89927161a 100644 --- a/sources/qetgraphicsitem/masterelement.h +++ b/sources/qetgraphicsitem/masterelement.h @@ -44,6 +44,8 @@ class MasterElement : public Element void unlinkElement (Element *elmt) override; void initLink (QETProject *project) override; QRectF XrefBoundingRect() const; + + bool isFull() const; // Check Slave-Limit protected: QVariant itemChange( From 3795ddb1f5070b1957477b0aa7dfb10e47f7425d Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:52:26 +0200 Subject: [PATCH 13/20] Refactor context menu and link button logic --- sources/ui/masterpropertieswidget.cpp | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sources/ui/masterpropertieswidget.cpp b/sources/ui/masterpropertieswidget.cpp index 5d36c684a..3e152c2bd 100644 --- a/sources/ui/masterpropertieswidget.cpp +++ b/sources/ui/masterpropertieswidget.cpp @@ -342,7 +342,7 @@ void MasterPropertiesWidget::headerCustomContextMenuRequested(const QPoint &pos) { m_context_menu->clear(); m_context_menu->addAction(m_save_header_state); -m_context_menu->popup(ui->m_free_tree_widget->header()->mapToGlobal(pos)); + m_context_menu->popup(ui->m_free_tree_widget->header()->mapToGlobal(pos)); } /** @@ -352,33 +352,33 @@ m_context_menu->popup(ui->m_free_tree_widget->header()->mapToGlobal(pos)); */ void MasterPropertiesWidget::on_link_button_clicked() { - // Get the maximum number of allowed slaves from the element's information - QVariant max_slaves_variant = m_element->kindInformations().value("max_slaves"); + // Get the maximum number of allowed slaves from the element's information + QVariant max_slaves_variant = m_element->kindInformations().value("max_slaves"); - if (max_slaves_variant.isValid() && !max_slaves_variant.toString().isEmpty()) { - int max_slaves = max_slaves_variant.toInt(); - int current_slaves = ui->m_link_tree_widget->topLevelItemCount(); + if (max_slaves_variant.isValid() && !max_slaves_variant.toString().isEmpty()) { + int max_slaves = max_slaves_variant.toInt(); + int current_slaves = ui->m_link_tree_widget->topLevelItemCount(); - // If a limit is set and reached - if (max_slaves != -1 && current_slaves >= max_slaves) { + // If a limit is set and reached + if (max_slaves != -1 && current_slaves >= max_slaves) { - // Show a message box with the actual window as parent to ensure it's on top - QMessageBox::warning(this->window(), - tr("Maximum Slaves Reached"), - tr("This master element cannot accept any new slaves because it is full (Limit: %1).").arg(max_slaves)); - return; - } - } + // Show a message box with the actual window as parent to ensure it's on top + QMessageBox::warning(this->window(), + tr("Maximum Slaves Reached"), + tr("This master element cannot accept any new slaves because it is full (Limit: %1).").arg(max_slaves)); + return; + } + } - // Move current item from free_list to linked_list - QTreeWidgetItem *qtwi = ui->m_free_tree_widget->currentItem(); + // Move current item from free_list to linked_list + QTreeWidgetItem *qtwi = ui->m_free_tree_widget->currentItem(); if (qtwi) { ui->m_free_tree_widget->takeTopLevelItem( - ui->m_free_tree_widget->indexOfTopLevelItem(qtwi)); + ui->m_free_tree_widget->indexOfTopLevelItem(qtwi)); ui->m_link_tree_widget->insertTopLevelItem(0, qtwi); - + if(m_live_edit) apply(); } From 605392cf9bca4eb534774b2ec304d1444ef3fe7d Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 17:53:01 +0200 Subject: [PATCH 14/20] Filter out full MasterElements from elmt_vector Added filtering for full MasterElements from the list of elements. --- sources/ui/linksingleelementwidget.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/sources/ui/linksingleelementwidget.cpp b/sources/ui/linksingleelementwidget.cpp index 0247989bd..4a7def2c3 100644 --- a/sources/ui/linksingleelementwidget.cpp +++ b/sources/ui/linksingleelementwidget.cpp @@ -16,7 +16,7 @@ along with QElectroTech. If not, see . */ #include "linksingleelementwidget.h" - +#include "../qetgraphicsitem/masterelement.h" #include "../qetgraphicsitem/conductor.h" #include "../diagram.h" #include "../diagramposition.h" @@ -386,7 +386,22 @@ QVector > LinkSingleElementWidget::availableElements() //If element is linked, remove is parent from the list if(!m_element->isFree()) elmt_vector.removeAll(m_element->linkedElements().first()); - + // NEU: Filtere volle Master-Elemente aus der Liste heraus + for (int i = elmt_vector.size() - 1; i >= 0; --i) { + Element *elmt = elmt_vector.at(i); + + // Wenn das Element in der Liste ein Master ist + if (elmt->linkType() == Element::Master) { + + // Wir wandeln den generischen Element-Pointer in einen MasterElement-Pointer um + MasterElement *master = static_cast(elmt); + + // Wenn der Master voll ist, werfen wir ihn aus der Liste! + if (master->isFull()) { + elmt_vector.removeAt(i); + } + } + } return elmt_vector; } From 780cf8b0541b8257de2f72a7afd081a0a4350eec Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 19:57:45 +0200 Subject: [PATCH 15/20] Set default text color for slave Xref item --- sources/qetgraphicsitem/dynamicelementtextitem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp index 09e812118..7efff4811 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp +++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp @@ -1351,6 +1351,7 @@ void DynamicElementTextItem::updateXref() { m_slave_Xref_item = new QGraphicsTextItem(xref_label, this); m_slave_Xref_item->setFont(QETApp::diagramTextsFont(5)); + m_slave_Xref_item->setDefaultTextColor(Qt::black); m_slave_Xref_item->installSceneEventFilter(this); m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::xChanged, this, &DynamicElementTextItem::updateXref); From 825eeb77e40d1f807fd135fc5c1fc0619a5d7db7 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 20:14:51 +0200 Subject: [PATCH 16/20] Translate comments to English and clarify filtering logic --- sources/ui/linksingleelementwidget.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/ui/linksingleelementwidget.cpp b/sources/ui/linksingleelementwidget.cpp index 4a7def2c3..7fdf68f8d 100644 --- a/sources/ui/linksingleelementwidget.cpp +++ b/sources/ui/linksingleelementwidget.cpp @@ -386,17 +386,17 @@ QVector > LinkSingleElementWidget::availableElements() //If element is linked, remove is parent from the list if(!m_element->isFree()) elmt_vector.removeAll(m_element->linkedElements().first()); - // NEU: Filtere volle Master-Elemente aus der Liste heraus + // Filter out all master elements from the list for (int i = elmt_vector.size() - 1; i >= 0; --i) { Element *elmt = elmt_vector.at(i); - // Wenn das Element in der Liste ein Master ist + // If the item in the list is a master if (elmt->linkType() == Element::Master) { - // Wir wandeln den generischen Element-Pointer in einen MasterElement-Pointer um + // We convert the generic element pointer into a MasterElement pointer MasterElement *master = static_cast(elmt); - // Wenn der Master voll ist, werfen wir ihn aus der Liste! + // If the master is full, we'll remove it from the list! if (master->isFull()) { elmt_vector.removeAt(i); } From f5857bb1fda2b9aeed1cb3c3438c6b36d73c5db0 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 20:15:35 +0200 Subject: [PATCH 17/20] Update comment for clarity in element properties editor --- sources/editor/ui/elementpropertieseditorwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/editor/ui/elementpropertieseditorwidget.cpp b/sources/editor/ui/elementpropertieseditorwidget.cpp index a4eba4e02..54bb447ba 100644 --- a/sources/editor/ui/elementpropertieseditorwidget.cpp +++ b/sources/editor/ui/elementpropertieseditorwidget.cpp @@ -240,7 +240,7 @@ void ElementPropertiesEditorWidget::on_m_buttonBox_accepted() else if (m_data.m_type == ElementData::Master) { m_data.m_master_type = ui->m_master_type_cb->currentData().value(); - // NEU: Wenn Häkchen gesetzt, speichere die Zahl, ansonsten -1 (unendlich) + //If the checkbox is checked, save the number; otherwise, -1 (infinity) if (ui->max_slaves_checkbox->isChecked()) { m_data.m_max_slaves = ui->max_slaves_spinbox->value(); } else { From 62dbaddab25d8c28a3181881f9f223eb1b0bef2b Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 20:21:03 +0200 Subject: [PATCH 18/20] Update checkbox text for max slaves setting --- sources/editor/ui/elementpropertieseditorwidget.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/editor/ui/elementpropertieseditorwidget.ui b/sources/editor/ui/elementpropertieseditorwidget.ui index f7bf44641..a7a8a7d49 100644 --- a/sources/editor/ui/elementpropertieseditorwidget.ui +++ b/sources/editor/ui/elementpropertieseditorwidget.ui @@ -107,7 +107,7 @@ - max. Slaves definieren + Définir le nombre maximal d'esclaves From 225edec09134779088137b2be567885c718f2251 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Tue, 31 Mar 2026 20:33:44 +0200 Subject: [PATCH 19/20] Translate warning message to French --- sources/ui/masterpropertieswidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/ui/masterpropertieswidget.cpp b/sources/ui/masterpropertieswidget.cpp index 3e152c2bd..9230c3549 100644 --- a/sources/ui/masterpropertieswidget.cpp +++ b/sources/ui/masterpropertieswidget.cpp @@ -365,8 +365,8 @@ void MasterPropertiesWidget::on_link_button_clicked() // Show a message box with the actual window as parent to ensure it's on top QMessageBox::warning(this->window(), - tr("Maximum Slaves Reached"), - tr("This master element cannot accept any new slaves because it is full (Limit: %1).").arg(max_slaves)); + tr("Nombre maximal d'esclaves atteint."), + tr("Cet élément maître ne peut accepter aucun nouvel esclave car il est plein (Limit: %1).").arg(max_slaves)); return; } } From 9b77b4d4fa19e608a72cded2b1ac52841f0afc79 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Wed, 1 Apr 2026 16:51:41 +0200 Subject: [PATCH 20/20] Update rectangle height and add QLabel for hidden masters --- sources/ui/linksingleelementwidget.ui | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sources/ui/linksingleelementwidget.ui b/sources/ui/linksingleelementwidget.ui index a4b340e9f..b31f7c10d 100644 --- a/sources/ui/linksingleelementwidget.ui +++ b/sources/ui/linksingleelementwidget.ui @@ -7,7 +7,7 @@ 0 0 389 - 442 + 460 @@ -64,6 +64,23 @@ + + + + + Remarque : les éléments maîtres ayant atteint leur nombre maximal d'esclaves sont masqués. + + + true + + + + true + + + + +