diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp index 17f218ab9..7d9a80076 100644 --- a/sources/TerminalStrip/terminalstrip.cpp +++ b/sources/TerminalStrip/terminalstrip.cpp @@ -85,12 +85,28 @@ class RealTerminal ElementData::TerminalType type() const { if (m_element) { - return m_element->elementData().m_terminal_type; + return m_element->elementData().terminalType(); } else { return ElementData::TTGeneric; } } + ElementData::TerminalFunction function() const { + if (m_element) { + return m_element->elementData().terminalFunction(); + } else { + return ElementData::TFGeneric; + } + } + + bool led() const { + if (m_element) { + return m_element->elementData().terminalLed(); + } else { + return false; + } + } + /** * @brief elementUuid * @return if this real terminal is an element @@ -585,7 +601,9 @@ RealTerminalData TerminalStrip::realTerminalData(int real_terminal_index) if (real_terminal->isElement()) { rtd.Xref_ = autonum::AssignVariables::genericXref(real_terminal->element()); } - rtd.type_ = real_terminal->type(); + rtd.type_ = real_terminal->type(); + rtd.function_ = real_terminal->function(); + rtd.led_ = real_terminal->led(); rtd.is_element = real_terminal->isElement(); return rtd; @@ -632,6 +650,15 @@ QSharedPointer TerminalStrip::physicalTerminal(QSharedPointer< return pt; } +/** + * @brief TerminalStrip::elementForRealTerminal + * @param rt + * @return the element associated to \p rt, the returned element can be nullptr; + */ +Element *TerminalStrip::elementForRealTerminal(QSharedPointer rt) const { + return rt.data()->element(); +} + /************************************************************************************/ /************************************************************************************/ /************************************************************************************/ diff --git a/sources/TerminalStrip/terminalstrip.h b/sources/TerminalStrip/terminalstrip.h index 61ae60fa4..175a3c4f3 100644 --- a/sources/TerminalStrip/terminalstrip.h +++ b/sources/TerminalStrip/terminalstrip.h @@ -45,6 +45,7 @@ struct RealTerminalData conductor_; ElementData::TerminalType type_; + ElementData::TerminalFunction function_; bool led_ = false, is_element = false; @@ -103,6 +104,7 @@ class TerminalStrip : public QObject private: QSharedPointer realTerminal(Element *terminal); QSharedPointer physicalTerminal(QSharedPointer terminal); + Element *elementForRealTerminal(QSharedPointer rt) const; private: TerminalStripData m_data; diff --git a/sources/TerminalStrip/ui/terminalstripeditor.cpp b/sources/TerminalStrip/ui/terminalstripeditor.cpp index c1fa0f546..909eafc04 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.cpp +++ b/sources/TerminalStrip/ui/terminalstripeditor.cpp @@ -25,6 +25,7 @@ #include "../UndoCommand/addterminalstripcommand.h" #include "../UndoCommand/addterminaltostripcommand.h" #include "../UndoCommand/changeterminalstripdata.h" +#include "../undocommand/changeelementdatacommand.h" #include "terminalstriptreewidget.h" #include "../../qeticons.h" #include "terminalstripmodel.h" @@ -392,9 +393,12 @@ void TerminalStripEditor::on_m_dialog_button_box_clicked(QAbstractButton *button auto role = ui->m_dialog_button_box->buttonRole(button); - if (role == QDialogButtonBox::ApplyRole) { + if (role == QDialogButtonBox::ApplyRole) + { if (m_current_strip) { + m_project->undoStack()->beginMacro(tr("Modifier des propriétés de borniers")); + TerminalStripData data; data.m_installation = ui->m_installation_le->text(); data.m_location = ui->m_location_le->text(); @@ -403,6 +407,16 @@ void TerminalStripEditor::on_m_dialog_button_box_clicked(QAbstractButton *button data.m_description = ui->m_description_te->toPlainText(); m_project->undoStack()->push(new ChangeTerminalStripData(m_current_strip, data, nullptr)); + + if (m_model) + { + auto modified_data = m_model->editedTerminalsData(); + for (auto elmt : modified_data.keys()) { + m_project->undoStack()->push(new ChangeElementDataCommand(elmt, modified_data.value(elmt))); + } + } + + m_project->undoStack()->endMacro(); } } diff --git a/sources/TerminalStrip/ui/terminalstripeditor.ui b/sources/TerminalStrip/ui/terminalstripeditor.ui index c6823a8e1..da0d41634 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.ui +++ b/sources/TerminalStrip/ui/terminalstripeditor.ui @@ -6,8 +6,8 @@ 0 0 - 901 - 465 + 1260 + 579 diff --git a/sources/TerminalStrip/ui/terminalstripmodel.cpp b/sources/TerminalStrip/ui/terminalstripmodel.cpp index 308ffc6b9..89f6a3f04 100644 --- a/sources/TerminalStrip/ui/terminalstripmodel.cpp +++ b/sources/TerminalStrip/ui/terminalstripmodel.cpp @@ -17,6 +17,7 @@ */ #include "terminalstripmodel.h" #include "../terminalstrip.h" +#include "../../qetgraphicsitem/element.h" #include #include #include @@ -33,8 +34,13 @@ const int XREF_CELL = 3; const int CABLE_CELL = 4; const int CABLE_WIRE_CELL = 5; const int TYPE_CELL = 6; -const int LED_CELL = 7; -const int CONDUCTOR_CELL = 8; +const int FUNCTION_CELL = 7; +const int LED_CELL = 8; +const int CONDUCTOR_CELL = 9; + +const int ROW_COUNT = 9; + +static QVector UNMODIFIED_CELL_VECTOR{false, false, false, false, false, false, false, false, false, false}; /** * @brief TerminalStripModel::TerminalStripModel @@ -62,7 +68,7 @@ int TerminalStripModel::rowCount(const QModelIndex &parent) const int TerminalStripModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return 8; + return ROW_COUNT; } QVariant TerminalStripModel::data(const QModelIndex &index, int role) const @@ -77,21 +83,21 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole) { switch (index.column()) { - case POS_CELL : return rtd.pos_; - case LEVEL_CELL : return rtd.level_; - case LABEL_CELL : return rtd.label_; - case XREF_CELL : return rtd.Xref_; - case CABLE_CELL : return rtd.cable_; + case POS_CELL : return rtd.pos_; + case LEVEL_CELL : return rtd.level_; + case LABEL_CELL : return rtd.label_; + case XREF_CELL : return rtd.Xref_; + case CABLE_CELL : return rtd.cable_; case CABLE_WIRE_CELL : return rtd.cable_wire_; - case TYPE_CELL : return ElementData::translatedTerminalType(rtd.type_); - case CONDUCTOR_CELL : return rtd.conductor_; - default : return QVariant(); + case TYPE_CELL : return ElementData::translatedTerminalType(rtd.type_); + case FUNCTION_CELL : return ElementData::translatedTerminalFunction(rtd.function_); + case CONDUCTOR_CELL : return rtd.conductor_; + default : return QVariant(); } } else if (role == Qt::EditRole) { switch (index.column()) { -// case LEVEL_CELL : return rtd.level_; case LABEL_CELL : return rtd.label_; default: return QVariant(); @@ -135,13 +141,13 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value modified_ = true; modified_cell = TYPE_CELL; } -// else if (column_ == LEVEL_CELL && -// role == Qt::EditRole) -// { -// rtd.level_ = value.toInt(); -// modified_ = true; -// modified_cell = LEVEL_CELL; -// } + else if (column_ == FUNCTION_CELL && + role == Qt::EditRole) + { + rtd.function_ = value.value(); + modified_ = true; + modified_cell = FUNCTION_CELL; + } //Set the modification to the terminal data if (modified_) @@ -154,7 +160,7 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value if (m_modified_cell.contains(rtd.m_real_terminal)) { vector_ = m_modified_cell.value(rtd.m_real_terminal); } else { - vector_ = QVector({false, false, false, false, false, false, false, false, false}); + vector_ = UNMODIFIED_CELL_VECTOR; } vector_.replace(modified_cell, true); @@ -173,20 +179,19 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation if (orientation == Qt::Horizontal) { switch (section) { - case POS_CELL: return tr("Position"); - case LEVEL_CELL: return tr("Étage"); - case LABEL_CELL: return tr("Label"); - case XREF_CELL: return tr("Référence croisé"); - case CABLE_CELL: return tr("Câble"); + case POS_CELL: return tr("Position"); + case LEVEL_CELL: return tr("Étage"); + case LABEL_CELL: return tr("Label"); + case XREF_CELL: return tr("Référence croisé"); + case CABLE_CELL: return tr("Câble"); case CABLE_WIRE_CELL: return tr("Couleur / numéro de fil câble"); - case TYPE_CELL: return tr("Type"); - case LED_CELL: return tr("led"); - case CONDUCTOR_CELL: return tr("Numéro de conducteur"); + case TYPE_CELL: return tr("Type"); + case FUNCTION_CELL : return tr("Fonction"); + case LED_CELL: return tr("led"); + case CONDUCTOR_CELL: return tr("Numéro de conducteur"); default : return QVariant(); } - } /*else { - return QString::number(++section); - }*/ + } } return QVariant(); @@ -197,7 +202,7 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; auto c = index.column(); - if (/*c == LEVEL_CELL || */c == LABEL_CELL || c == TYPE_CELL) + if (c == LABEL_CELL || c == TYPE_CELL || c == FUNCTION_CELL) flags = flags | Qt::ItemIsEditable; if (c == LED_CELL) { flags = flags | Qt::ItemIsUserCheckable; @@ -205,6 +210,35 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const return flags; } +/** + * @brief TerminalStripModel::editedTerminals + * @return a hash with for keys the edited element and for value the ElementData with modified properties + */ +QHash TerminalStripModel::editedTerminalsData() const +{ + QHash returned_hash; + + QVector rtd_vector = m_real_terminal_data; + + const auto modified_real_terminal = m_modified_cell.keys(); + for (auto const &rt : modified_real_terminal) //loop over modified real terminal + { + for (auto const &rtd : rtd_vector) //loop over real terminal data to retrieve the data associated with real terminal + { + if (rtd.m_real_terminal == rt) + { + auto element = m_terminal_strip->elementForRealTerminal(rt); + if (element) { + returned_hash.insert(element, modifiedData(element->elementData(), rtd)); + } + break; + } + } + } + + return returned_hash; +} + void TerminalStripModel::fillRealTerminalData() { if (m_terminal_strip) { @@ -214,6 +248,23 @@ void TerminalStripModel::fillRealTerminalData() } } +/** + * @brief TerminalStripModel::modifiedData + * @param previous_data + * @param edited_data + * @return an ElementData with the change made in \p edited_data applied to \p original_data + */ +ElementData TerminalStripModel::modifiedData(const ElementData &original_data, const RealTerminalData &edited_data) +{ + ElementData returned_data = original_data; + + returned_data.setTerminalType(edited_data.type_); + returned_data.setTerminalFunction(edited_data.function_); + returned_data.setTerminalLED(edited_data.led_); + + return returned_data; +} + /*********************************************************** * Alittle delegate for add a combobox to edit type * and a spinbox to edit the level of a terminal @@ -236,13 +287,15 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO return qcb; } -// if (index.column() == LEVEL_CELL) { -// auto qsb = new QSpinBox(parent); -// qsb->setObjectName("terminal_level"); -// qsb->setRange(0, 3); -// qsb->setValue(index.data(Qt::EditRole).toInt()); -// return qsb; -// } + if (index.column() == FUNCTION_CELL) { + auto qcb = new QComboBox(parent); + qcb->setObjectName("terminal_function"); + qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFGeneric), ElementData::TFGeneric); + qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFPhase), ElementData::TFPhase); + qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFNeutral), ElementData::TFNeutral); + + return qcb; + } return QStyledItemDelegate::createEditor(parent, option, index); } @@ -257,11 +310,11 @@ void TerminalStripModelDelegate::setModelData(QWidget *editor, QAbstractItemMode model->setData(index, qcb->currentData(), Qt::EditRole); } } -// else if (editor->objectName() == QLatin1String("terminal_level")) -// { -// if (auto qsb = dynamic_cast(editor)) { -// model->setData(index, qsb->value(), Qt::EditRole); -// } -// } + else if (editor->objectName() == QLatin1String("terminal_function")) + { + if (auto qcb = dynamic_cast(editor)) { + model->setData(index, qcb->currentData(), Qt::EditRole); + } + } } } diff --git a/sources/TerminalStrip/ui/terminalstripmodel.h b/sources/TerminalStrip/ui/terminalstripmodel.h index 09237cbe2..cf96bcb8b 100644 --- a/sources/TerminalStrip/ui/terminalstripmodel.h +++ b/sources/TerminalStrip/ui/terminalstripmodel.h @@ -40,8 +40,11 @@ class TerminalStripModel : public QAbstractTableModel virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; virtual Qt::ItemFlags flags (const QModelIndex &index) const override; + QHash editedTerminalsData() const; + private: void fillRealTerminalData(); + static ElementData modifiedData(const ElementData &original_data, const RealTerminalData &edited_data); private: QPointer m_terminal_strip; @@ -64,9 +67,6 @@ class TerminalStripModelDelegate : public QStyledItemDelegate QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - -// protected: -// bool eventFilter(QObject *object, QEvent *event) override; }; #endif // TERMINALSTRIPMODEL_H diff --git a/sources/properties/elementdata.cpp b/sources/properties/elementdata.cpp index 1f1f0c859..992cc61f7 100644 --- a/sources/properties/elementdata.cpp +++ b/sources/properties/elementdata.cpp @@ -122,6 +122,84 @@ QDomElement ElementData::kindInfoToXml(QDomDocument &document) return returned_elmt; } +/** + * @brief ElementData::setTerminalType + * Override the terminal type by \p t_type + * @param t_type + */ +void ElementData::setTerminalType(ElementData::TerminalType t_type) +{ + if (t_type == m_terminal_type) { + m_terminal_type_is_override = false; + } else { + m_override_terminal_type = t_type; + m_terminal_type_is_override = true; + } +} + +/** + * @brief ElementData::terminalType + * @return the terminal type or overrided terminal type if set + */ +ElementData::TerminalType ElementData::terminalType() const +{ + return m_terminal_type_is_override ? + m_override_terminal_type : + m_terminal_type; +} + +/** + * @brief ElementData::setTerminalFunction + * Override the terminal function by \p t_function + * @param t_function + */ +void ElementData::setTerminalFunction(ElementData::TerminalFunction t_function) +{ + if (t_function == m_terminal_function) { + m_terminal_function_is_override = false; + } else { + m_override_terminal_function = t_function; + m_terminal_function_is_override = true; + } +} + +/** + * @brief ElementData::terminalFunction + * @return the terminal function or overrided terminal function if set + */ +ElementData::TerminalFunction ElementData::terminalFunction() const +{ + return m_terminal_function_is_override ? + m_override_terminal_function : + m_terminal_function; +} + +/** + * @brief ElementData::setTerminalLED + * Override the terminal led by \p led + * @param led + */ +void ElementData::setTerminalLED(bool led) +{ + if (led == m_terminal_led) { + m_terminal_led_is_override = false; + } else { + m_override_terminal_led = led; + m_terminal_led_is_override = true; + } +} + +/** + * @brief ElementData::terminalLed + * @return if terminal have led or overrided led if set + */ +bool ElementData::terminalLed() const +{ + return m_terminal_led_is_override ? + m_override_terminal_led : + m_terminal_led; +} + bool ElementData::operator==(const ElementData &data) const { if (data.m_type != m_type) { @@ -141,8 +219,41 @@ bool ElementData::operator==(const ElementData &data) const } } else if (data.m_type == ElementData::Terminale) { - if (data.m_terminal_type != m_terminal_type || - data.m_terminal_function != m_terminal_function) { + //Check terminal type or overrided terminal type + if (data.m_terminal_type_is_override != m_terminal_type_is_override) { + return false; + } + + if (m_terminal_type_is_override) { + if(data.m_override_terminal_type != m_override_terminal_type) { + return false; + } + } else if (data.m_terminal_type != m_terminal_type) { + return false; + } + + //Check terminal led or override terminal led + if (data.m_terminal_led_is_override != m_terminal_led_is_override) { + return false; + } + if (m_terminal_led_is_override) { + if (data.m_override_terminal_led != m_override_terminal_led) { + return false; + } + } else if (data.m_terminal_led != m_terminal_led) { + return false; + } + + //Check terminal function or overrided terminal function + if (data.m_terminal_function_is_override != m_terminal_function_is_override) { + return false; + } + if (m_terminal_function_is_override) { + if (data.m_override_terminal_function != m_override_terminal_function) { + return false; + } + } + else if (data.m_terminal_function != m_terminal_function) { return false; } } @@ -343,15 +454,15 @@ QString ElementData::translatedTerminalType(ElementData::TerminalType type) { switch (type) { case ElementData::TTGeneric : - return QObject::tr("generique", "generic terminal element type"); + return QObject::tr("Générique", "generic terminal element type"); case ElementData::TTFuse : - return QObject::tr("fusible", "fuse terminal element type"); + return QObject::tr("Fusible", "fuse terminal element type"); case ElementData::TTSectional: - return QObject::tr("sectionable", "sectional terminal element type"); + return QObject::tr("Sectionable", "sectional terminal element type"); case ElementData::TTDiode: - return QObject::tr("diode", "diode terminal element type"); + return QObject::tr("Diode", "diode terminal element type"); case ElementData::TTGround: - return QObject::tr("terre", "ground terminal element type"); + return QObject::tr("Terre", "ground terminal element type"); } } @@ -383,6 +494,15 @@ ElementData::TerminalFunction ElementData::terminalFunctionFromString(const QStr return ElementData::TFGeneric; } +QString ElementData::translatedTerminalFunction(ElementData::TerminalFunction function) +{ + switch (function) { + case TFGeneric : return QObject::tr("Générique", "generic terminal element function"); + case TFPhase : return QObject::tr("Phase", "phase terminal element function" ); + case TFNeutral : return QObject::tr("Neutre", "neutral terminal element function"); + } +} + void ElementData::kindInfoFromXml(const QDomElement &xml_element) { if (m_type == ElementData::Master || diff --git a/sources/properties/elementdata.h b/sources/properties/elementdata.h index e0f9696ec..d2f7819ee 100644 --- a/sources/properties/elementdata.h +++ b/sources/properties/elementdata.h @@ -91,6 +91,15 @@ class ElementData : public PropertiesInterface bool fromXml(const QDomElement &xml_element) override; QDomElement kindInfoToXml(QDomDocument &document); + void setTerminalType(ElementData::TerminalType t_type); + ElementData::TerminalType terminalType() const; + + void setTerminalFunction(ElementData::TerminalFunction t_function); + ElementData::TerminalFunction terminalFunction() const; + + void setTerminalLED(bool led); + bool terminalLed() const; + bool operator==(const ElementData &data) const; bool operator!=(const ElementData &data) const; @@ -112,6 +121,7 @@ class ElementData : public PropertiesInterface static QString terminalFunctionToString(ElementData::TerminalFunction function); static ElementData::TerminalFunction terminalFunctionFromString(const QString &string); + static QString translatedTerminalFunction(ElementData::TerminalFunction function); // must be public, because this class is a private member // of Element/ element editor and they must access this data @@ -130,6 +140,17 @@ class ElementData : public PropertiesInterface NamesList m_names_list; QString m_drawing_information; + private: + ElementData::TerminalType m_override_terminal_type = ElementData::TTGeneric; + bool m_terminal_type_is_override = false; + + ElementData::TerminalFunction m_override_terminal_function = ElementData::TFGeneric; + bool m_terminal_function_is_override = false; + + bool m_terminal_led = false; + bool m_terminal_led_is_override = false; + bool m_override_terminal_led = false; + private: void kindInfoFromXml(const QDomElement &xml_element); }; diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h index ca4d8fa69..ddf19f16d 100644 --- a/sources/qetgraphicsitem/element.h +++ b/sources/qetgraphicsitem/element.h @@ -42,6 +42,7 @@ class ElementTextItemGroup; class Element : public QetGraphicsItem { friend class DiagramEventAddElement; + friend class ChangeElementDataCommand; Q_OBJECT public: diff --git a/sources/undocommand/changeelementdatacommand.cpp b/sources/undocommand/changeelementdatacommand.cpp new file mode 100644 index 000000000..03648de1d --- /dev/null +++ b/sources/undocommand/changeelementdatacommand.cpp @@ -0,0 +1,39 @@ +/* + Copyright 2006-2021 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 "changeelementdatacommand.h" +#include "../qetgraphicsitem/element.h" + +ChangeElementDataCommand::ChangeElementDataCommand(Element *element, ElementData new_data) : + m_element(element), + m_old_data(element->elementData()), + m_new_data(new_data) +{ + setText(QObject::tr("Modifier les propriétés d'un élement")); +} + +void ChangeElementDataCommand::undo() { + if (m_element) { + m_element.data()->m_data = m_old_data; + } +} + +void ChangeElementDataCommand::redo() { + if (m_element) { + m_element.data()->m_data = m_new_data; + } +} diff --git a/sources/undocommand/changeelementdatacommand.h b/sources/undocommand/changeelementdatacommand.h new file mode 100644 index 000000000..ecc4c590f --- /dev/null +++ b/sources/undocommand/changeelementdatacommand.h @@ -0,0 +1,38 @@ +/* + Copyright 2006-2021 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 CHANGEELEMENTDATACOMMAND_H +#define CHANGEELEMENTDATACOMMAND_H + +#include <../properties/elementdata.h> +#include + +class Element; + +class ChangeElementDataCommand : public QUndoCommand +{ + public: + ChangeElementDataCommand(Element *element, ElementData new_data); + void undo() override; + void redo() override; + + private: + QPointer m_element; + ElementData m_old_data, m_new_data; +}; + +#endif // CHANGEELEMENTDATACOMMAND_H