diff --git a/sources/TerminalStrip/UndoCommand/addterminalstripcommand.cpp b/sources/TerminalStrip/UndoCommand/addterminalstripcommand.cpp index 46fe13bdd..338aadb6d 100644 --- a/sources/TerminalStrip/UndoCommand/addterminalstripcommand.cpp +++ b/sources/TerminalStrip/UndoCommand/addterminalstripcommand.cpp @@ -19,6 +19,7 @@ #include "../../qetproject.h" #include "../terminalstrip.h" #include "../qetgraphicsitem/element.h" +#include "../realterminal.h" #include @@ -57,9 +58,13 @@ RemoveTerminalStripCommand::RemoveTerminalStripCommand(TerminalStrip *strip, QUndoCommand *parent) : QUndoCommand(parent), m_strip(strip), - m_project(project), - m_elements(strip->terminalElement()) + m_project(project) { + for (const auto &real_t : strip->realTerminals()) + { + if (real_t->element()) + m_elements.append(real_t->element()); + } setText(QObject::tr("Supprimer un groupe de bornes")); } diff --git a/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.cpp b/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.cpp index f5e59239f..f63afc516 100644 --- a/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.cpp +++ b/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.cpp @@ -17,6 +17,8 @@ */ #include "addterminaltostripcommand.h" #include "../../qetgraphicsitem/terminalelement.h" +#include "../realterminal.h" +#include "../physicalterminal.h" /** * @brief AddTerminalToStripCommand::AddTerminalToStripCommand @@ -25,13 +27,12 @@ * @param strip : terminal strip where terminal must be added * @param parent : parent undo command */ -AddTerminalToStripCommand::AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *strip, QUndoCommand *parent) : +AddTerminalToStripCommand::AddTerminalToStripCommand(QSharedPointer terminal, TerminalStrip *strip, QUndoCommand *parent) : QUndoCommand(parent), m_terminal(terminal), - m_new_strip(strip), - m_operation(Operation::add) + m_new_strip(strip) { - auto t_label = terminal->actualLabel(); + auto t_label = terminal->label(); auto ts_name = strip->name(); auto str_1 = t_label.isEmpty() ? QObject::tr("Ajouter une borne") : @@ -43,37 +44,6 @@ AddTerminalToStripCommand::AddTerminalToStripCommand(TerminalElement *terminal, setText(str_1 + " " + str_2); } -/** - * @brief AddTerminalToStripCommand::AddTerminalToStripCommand - * Move \p terminal from \p old_strip to \p new_strip - * @param terminal : terminal to move - * @param old_strip : terminal where start the move - * @param new_strip : terminal where finish the move - * @param parent : parent undo command - */ -AddTerminalToStripCommand::AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *old_strip, - TerminalStrip *new_strip, QUndoCommand *parent) : - QUndoCommand(parent), - m_terminal(terminal), - m_old_strip(old_strip), - m_new_strip(new_strip), - m_operation(Operation::move) -{ - auto t_label = terminal->actualLabel(); - auto old_ts_name = old_strip->name(); - auto new_ts_name = new_strip->name(); - - auto str_1 = t_label.isEmpty() ? QObject::tr("Déplacer une borne") : - QObject::tr("Déplacer la borne %1").arg(t_label); - - auto str_2 = old_ts_name.isEmpty() ? QObject::tr("d'un groupe de bornes") : - QObject::tr("du groupe de bornes %1").arg(old_ts_name); - - auto str_3 = new_ts_name.isEmpty() ? QObject::tr("à un autre groupe de bornes") : - QObject::tr("au groupe de bornes %1").arg(new_ts_name); - - setText(str_1 + " " + str_2 + " " + str_3); -} AddTerminalToStripCommand::~AddTerminalToStripCommand() {} @@ -88,13 +58,7 @@ void AddTerminalToStripCommand::undo() !m_new_strip) { return; } - m_new_strip->removeTerminal(m_terminal); - - if ( m_operation == Operation::move && - m_old_strip) { - m_old_strip->addTerminal(m_terminal); - } } /** @@ -107,12 +71,6 @@ void AddTerminalToStripCommand::redo() !m_new_strip) { return; } - - if (m_operation == Operation::move && - m_old_strip) { - m_old_strip->removeTerminal(m_terminal); - } - m_new_strip->addTerminal(m_terminal); } @@ -122,14 +80,20 @@ void AddTerminalToStripCommand::redo() * @param strip * @param parent */ -RemoveTerminalFromStripCommand::RemoveTerminalFromStripCommand(TerminalElement *terminal, +RemoveTerminalFromStripCommand::RemoveTerminalFromStripCommand(QSharedPointer terminal, TerminalStrip *strip, QUndoCommand *parent) : QUndoCommand(parent), - m_terminal(terminal), + m_terminals(terminal->realTerminals()), m_strip(strip) -{ - auto t_label = terminal->actualLabel(); +{ + QString t_label; + for (const auto &real_t : m_terminals) { + if (!t_label.isEmpty()) + t_label.append(", "); + t_label.append(real_t->label()); + } + auto strip_name = strip->name(); auto str_1 = t_label.isEmpty() ? QObject::tr("Enlever une borne") : @@ -142,15 +106,85 @@ RemoveTerminalFromStripCommand::RemoveTerminalFromStripCommand(TerminalElement * void RemoveTerminalFromStripCommand::undo() { - if (m_terminal && m_strip) { - m_strip->addTerminal(m_terminal); + if (m_strip) + { + for (const auto &real_t : m_terminals) { + m_strip->addTerminal(real_t); + } + auto phy_t = m_terminals.first()->physicalTerminal(); + if (phy_t) { + m_strip->groupTerminals(phy_t, m_terminals); + } } } void RemoveTerminalFromStripCommand::redo() { - if (m_terminal && m_strip) { - m_strip->removeTerminal(m_terminal); + if (m_strip) + { + for (const auto & real_t : m_terminals) { + m_strip->removeTerminal(real_t); + } } } +/** + * @brief MoveTerminalCommand::MoveTerminalCommand + * @param terminal + * @param old_strip + * @param new_strip + * @param parent + */ +MoveTerminalCommand::MoveTerminalCommand(QSharedPointer terminal, TerminalStrip *old_strip, + TerminalStrip *new_strip, QUndoCommand *parent) : + QUndoCommand (parent), + m_terminal(terminal), + m_old_strip(old_strip), + m_new_strip(new_strip) +{ + QString t_label; + for (auto real_t : terminal->realTerminals()) { + if (!t_label.isEmpty()) + t_label.append(", "); + t_label.append(real_t->label()); + } + + auto strip_name = old_strip->name(); + auto new_strip_name = new_strip->name(); + + auto str_1 = t_label.isEmpty() ? QObject::tr("Déplacer une borne") : + QObject::tr("Déplacer la borne %1").arg(t_label); + + auto str_2 = strip_name.isEmpty() ? QObject::tr(" d'un groupe de bornes") : + QObject::tr(" du groupe de bornes %1").arg(strip_name); + + auto str_3 = new_strip_name.isEmpty() ? QObject::tr("vers un groupe de bornes") : + QObject::tr("vers le groupe de bornes %1").arg(new_strip_name); + setText(str_1 + " " + str_2 + " " + str_3); +} + +void MoveTerminalCommand::undo() +{ + if (m_terminal) + { + if (m_new_strip) { + m_new_strip->removeTerminal(m_terminal); + } + if (m_old_strip) { + m_old_strip->addTerminal(m_terminal); + } + } +} + +void MoveTerminalCommand::redo() +{ + if (m_terminal) + { + if (m_old_strip) { + m_old_strip->removeTerminal(m_terminal); + } + if (m_new_strip) { + m_new_strip->addTerminal(m_terminal); + } + } +} diff --git a/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.h b/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.h index bf2313fb1..31f75d7c7 100644 --- a/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.h +++ b/sources/TerminalStrip/UndoCommand/addterminaltostripcommand.h @@ -23,6 +23,8 @@ class TerminalElement; class TerminalStrip; +class RealTerminal; +class PhysicalTerminal; /** * @brief The AddTerminalToStripCommand class @@ -34,27 +36,15 @@ class TerminalStrip; class AddTerminalToStripCommand : public QUndoCommand { public: - AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr); - AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *old_strip, - TerminalStrip *new_strip, QUndoCommand *parent = nullptr); + AddTerminalToStripCommand(QSharedPointer terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr); ~AddTerminalToStripCommand() override; void undo() override; void redo() override; private: - enum Operation{ - none, - add, - move, - }; - - QPointer m_terminal; - QPointer m_old_strip; + QSharedPointer m_terminal; QPointer m_new_strip; - Operation m_operation = Operation::none; - - }; /** @@ -65,15 +55,30 @@ class AddTerminalToStripCommand : public QUndoCommand class RemoveTerminalFromStripCommand : public QUndoCommand { public: - RemoveTerminalFromStripCommand (TerminalElement *terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr); + RemoveTerminalFromStripCommand (QSharedPointer terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr); ~RemoveTerminalFromStripCommand() override {} void undo() override; void redo() override; private: - QPointer m_terminal; + QVector> m_terminals; QPointer m_strip; }; +class MoveTerminalCommand : public QUndoCommand +{ + public: + MoveTerminalCommand (QSharedPointer terminal, TerminalStrip *old_strip, + TerminalStrip *new_strip, QUndoCommand *parent = nullptr); + + void undo() override; + void redo() override; + + private: + const QSharedPointer m_terminal; + QPointer m_old_strip, m_new_strip; + +}; + #endif // ADDTERMINALTOSTRIPCOMMAND_H diff --git a/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp b/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp index f93176ea3..611ea2a8e 100644 --- a/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp +++ b/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp @@ -17,6 +17,7 @@ */ #include "groupterminalscommand.h" #include "../physicalterminal.h" +#include "../realterminal.h" /** * @brief GroupTerminalsCommand::GroupTerminalsCommand @@ -87,8 +88,7 @@ void UnGroupTerminalsCommand::setUp(const QVector> { for (const auto &rt_ : to_ungroup) { - auto phy_t = m_terminal_strip->physicalTerminal(rt_); - if (phy_t) + if (auto phy_t = rt_->physicalTerminal()) { //Physical have only one real terminal, no need to ungroup it if (phy_t->realTerminalCount() <= 1) { diff --git a/sources/TerminalStrip/physicalterminal.cpp b/sources/TerminalStrip/physicalterminal.cpp index f633d45f1..f29e7bfa3 100644 --- a/sources/TerminalStrip/physicalterminal.cpp +++ b/sources/TerminalStrip/physicalterminal.cpp @@ -30,7 +30,13 @@ PhysicalTerminal::PhysicalTerminal(TerminalStrip *parent_strip, QVector> terminals) : m_parent_terminal_strip(parent_strip), m_real_terminal(terminals) -{} +{ + for (const auto &real_t : m_real_terminal) { + if (real_t) { + real_t->setPhysicalTerminal(sharedRef()); + } + } +} /** * @brief PhysicalTerminal::sharedRef @@ -80,6 +86,11 @@ QDomElement PhysicalTerminal::toXml(QDomDocument &parent_document) const */ void PhysicalTerminal::setTerminals(const QVector> &terminals) { m_real_terminal = terminals; + for (const auto &real_t : m_real_terminal) { + if (real_t) { + real_t->setPhysicalTerminal(sharedRef()); + } + } } /** @@ -90,6 +101,7 @@ void PhysicalTerminal::setTerminals(const QVector> */ void PhysicalTerminal::addTerminal(const QSharedPointer &terminal) { m_real_terminal.append(terminal); + terminal->setPhysicalTerminal(sharedRef()); } /** @@ -98,8 +110,13 @@ void PhysicalTerminal::addTerminal(const QSharedPointer &terminal) * @param terminal * @return true if sucessfully removed */ -bool PhysicalTerminal::removeTerminal(const QSharedPointer &terminal) { - return m_real_terminal.removeOne(terminal); +bool PhysicalTerminal::removeTerminal(const QSharedPointer &terminal) +{ + if (m_real_terminal.removeOne(terminal)) { + terminal->setPhysicalTerminal(QSharedPointer()); + return true; + } + return false; } /** @@ -124,6 +141,28 @@ bool PhysicalTerminal::setLevelOf(const QSharedPointer &terminal, return false; } +void PhysicalTerminal::setParentStrip(TerminalStrip *strip) +{ + m_parent_terminal_strip = strip; +} + +PhysicalTerminal::~PhysicalTerminal() +{ + for (const auto &real_t : m_real_terminal) { + if (real_t) { + real_t->setPhysicalTerminal(QSharedPointer()); + } + } +} + +/** + * @brief PhysicalTerminal::terminalStrip + * @return The parent terminal strip ornullptr + */ +TerminalStrip *PhysicalTerminal::terminalStrip() const { + return m_parent_terminal_strip.data(); +} + /** * @brief levelCount * @return the number of level of this terminal diff --git a/sources/TerminalStrip/physicalterminal.h b/sources/TerminalStrip/physicalterminal.h index 44379f328..13f1cd70b 100644 --- a/sources/TerminalStrip/physicalterminal.h +++ b/sources/TerminalStrip/physicalterminal.h @@ -61,6 +61,7 @@ class TerminalStrip; class PhysicalTerminal { friend class TerminalStrip; + friend class RealTerminal; private: PhysicalTerminal(TerminalStrip *parent_strip, QVector> terminals); @@ -75,9 +76,13 @@ class PhysicalTerminal bool setLevelOf(const QSharedPointer &terminal, int level); + void setParentStrip(TerminalStrip *strip); + public: PhysicalTerminal(){} + ~PhysicalTerminal(); + TerminalStrip* terminalStrip() const; int levelCount() const; int levelOf(const QSharedPointer &terminal) const; QVector> realTerminals() const; diff --git a/sources/TerminalStrip/realterminal.cpp b/sources/TerminalStrip/realterminal.cpp index b23a42361..b2774cea0 100644 --- a/sources/TerminalStrip/realterminal.cpp +++ b/sources/TerminalStrip/realterminal.cpp @@ -25,12 +25,17 @@ * @param parent_strip : parent terminal strip * @param terminal : terminal element (if any) in a folio */ -RealTerminal::RealTerminal(TerminalStrip *parent_strip, - Element *terminal) : - m_element(terminal), - m_parent_terminal_strip(parent_strip) +RealTerminal::RealTerminal(Element *terminal) : + m_element(terminal) {} +RealTerminal::~RealTerminal() +{ + if (m_physical_terminal) { + m_physical_terminal->removeTerminal(sharedRef()); + } +} + /** * @brief RealTerminal::sharedRef * @return a QSharedPointer of this @@ -47,6 +52,16 @@ QSharedPointer RealTerminal::sharedRef() return this_shared; } +/** + * @brief RealTerminal::sharedRef + * @return a shared reference of this, not that because + * this method is const, the shared reference can be null if not already + * used in another part of the code. + */ +QSharedPointer RealTerminal::sharedRef() const { + return QSharedPointer(m_this_weak); +} + /** * @brief RealTerminal::weakRef * @return a QWeakPointer of this, weak pointer can be bull @@ -55,35 +70,6 @@ QWeakPointer RealTerminal::weakRef() { return m_this_weak; } -/** - * @brief fromXml - * @param xml_element - * @return - */ -bool RealTerminal::fromXml(QDomElement xml_element, const QVector &terminal_vector) -{ - if (xml_element.tagName() != xmlTagName()) { - return true; - } - - m_uuid = QUuid(xml_element.attribute(QStringLiteral("uuid"))); - - if (xml_element.hasAttribute(QStringLiteral("element_uuid"))) - { - QUuid uuid_(xml_element.attribute(QStringLiteral("element_uuid"))); - - for (auto terminal : terminal_vector) { - if (terminal->uuid() == uuid_) - { - m_element = terminal; - break; - } - } - } - - return true; -} - /** * @brief toXml * @param parent_document @@ -92,7 +78,6 @@ bool RealTerminal::fromXml(QDomElement xml_element, const QVectorxmlTagName()); - root_elmt.setAttribute(QStringLiteral("uuid"), m_uuid.toString()); if (m_element) root_elmt.setAttribute(QStringLiteral("element_uuid"), m_element->uuid().toString()); @@ -100,11 +85,33 @@ QDomElement RealTerminal::toXml(QDomDocument &parent_document) const } /** - * @brief parentStrip - * @return parent terminal strip - */ -TerminalStrip *RealTerminal::parentStrip() const { - return m_parent_terminal_strip.data(); + * @brief RealTerminal::setPhysicalTerminal + * Set the parent physical terminal of this real terminal + * @param phy_t + */ +void RealTerminal::setPhysicalTerminal(const QSharedPointer &phy_t) { + m_physical_terminal = phy_t; +} + +/** +* @brief parentStrip +* @return parent terminal strip or nullptr +*/ +TerminalStrip *RealTerminal::parentStrip() const noexcept { + if (m_physical_terminal) { + return m_physical_terminal->terminalStrip(); + } else { + return nullptr; + } +} + +/** + * @brief RealTerminal::physicalTerminal + * @return The parent physical terminal of this terminal. + * The returned QSharedPointer can be null + */ +QSharedPointer RealTerminal::physicalTerminal() const noexcept{ + return m_physical_terminal; } /** @@ -113,11 +120,9 @@ TerminalStrip *RealTerminal::parentStrip() const { */ int RealTerminal::level() const { - if (m_parent_terminal_strip) { - const auto phy_t = m_parent_terminal_strip->physicalTerminal(m_this_weak); - if (phy_t) { - return phy_t->levelOf(m_this_weak); - } + if (m_physical_terminal && + sharedRef()) { + return m_physical_terminal->levelOf(sharedRef()); } return -1; @@ -224,8 +229,8 @@ bool RealTerminal::isElement() const { */ bool RealTerminal::isBridged() const { - if (m_parent_terminal_strip) { - return !m_parent_terminal_strip->isBridged(m_this_weak.toStrongRef()).isNull(); + if (parentStrip()) { + return !parentStrip()->isBridged(m_this_weak.toStrongRef()).isNull(); } else { return false; } @@ -237,8 +242,8 @@ bool RealTerminal::isBridged() const */ QSharedPointer RealTerminal::bridge() const { - if (m_parent_terminal_strip) { - return m_parent_terminal_strip->isBridged(m_this_weak.toStrongRef()); + if (parentStrip()) { + return parentStrip()->isBridged(m_this_weak.toStrongRef()); } else { return QSharedPointer(); } @@ -267,14 +272,6 @@ QUuid RealTerminal::elementUuid() const { } } -/** - * @brief uuid - * @return the uuid of this real terminal - */ -QUuid RealTerminal::uuid() const { - return m_uuid; -} - /** * @brief RealTerminal::RealTerminal::xmlTagName * @return diff --git a/sources/TerminalStrip/realterminal.h b/sources/TerminalStrip/realterminal.h index 36f0cc924..7b13345f3 100644 --- a/sources/TerminalStrip/realterminal.h +++ b/sources/TerminalStrip/realterminal.h @@ -41,19 +41,25 @@ class TerminalStripBridge; */ class RealTerminal { - friend class TerminalStrip; + friend class TerminalElement; friend class PhysicalTerminal; private: - RealTerminal(TerminalStrip *strip, Element *element = nullptr); + RealTerminal(Element *element); + QSharedPointer sharedRef(); + QSharedPointer sharedRef() const; QWeakPointer weakRef(); - bool fromXml(QDomElement xml_element, const QVector &terminal_vector); - QDomElement toXml(QDomDocument &parent_document) const; + void setPhysicalTerminal(const QSharedPointer &phy_t); public: - TerminalStrip *parentStrip() const; + ~RealTerminal(); + TerminalStrip *parentStrip() const noexcept; + QSharedPointer physicalTerminal() const noexcept; + + QDomElement toXml(QDomDocument &parent_document) const; + int level() const; QString label() const; QString Xref() const; @@ -72,15 +78,13 @@ class RealTerminal Element* element() const; QUuid elementUuid() const; - QUuid uuid() const; static QString xmlTagName(); private : QPointer m_element; - QPointer m_parent_terminal_strip; - QUuid m_uuid = QUuid::createUuid(); QWeakPointer m_this_weak; + QSharedPointer m_physical_terminal; }; #endif // REALTERMINAL_H diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp index 62c14c1e1..b66daa0eb 100644 --- a/sources/TerminalStrip/terminalstrip.cpp +++ b/sources/TerminalStrip/terminalstrip.cpp @@ -94,6 +94,49 @@ void TerminalStrip::setData(const TerminalStripData &data) { m_data = data; } +bool TerminalStrip::addTerminal(QSharedPointer real_t) +{ + //Check if terminal is already owned by a strip + //return if this strip or false if another strip + if (real_t->parentStrip()) { + if (real_t->parentStrip() != this) + return false; + else + return true; + } + + //Create a new single level physical terminal + auto raw_phy_ptr = new PhysicalTerminal(this, QVector>{real_t}); + m_physical_terminals.append(raw_phy_ptr->sharedRef()); + + emit orderChanged(); + return true; +} + +bool TerminalStrip::removeTerminal(QSharedPointer real_t) +{ + if (real_t->parentStrip() != this) { + return false; + } + + if (auto bridge_ = real_t->bridge()) { + bridge_->removeTerminal(real_t); + } + + if (auto phy_t = real_t->physicalTerminal()) + { + phy_t->removeTerminal(real_t); + if (phy_t->realTerminalCount() == 0) { + m_physical_terminals.removeOne(phy_t); + } + + emit orderChanged(); + return true; + } + + return false; +} + /** * @brief TerminalStrip::addTerminal * Add terminal to this terminal strip @@ -104,26 +147,22 @@ void TerminalStrip::setData(const TerminalStripData &data) { */ bool TerminalStrip::addTerminal(Element *terminal) { - if (m_terminal_elements_vector.contains(terminal)) { - return false; + for (const auto &real_t : realTerminals()) { + if (real_t->element() == terminal) { + return false; + } } + if (terminal->elementData().m_type != ElementData::Terminale) { return false; } - m_terminal_elements_vector.append(terminal); - - //Create the real terminal - auto raw_real_ptr = new RealTerminal(this, terminal); - auto real_terminal = raw_real_ptr->sharedRef(); - m_real_terminals.append(real_terminal); + auto casted_ = static_cast(terminal); //Create a new single level physical terminal - auto raw_phy_ptr = new PhysicalTerminal(this, QVector>{real_terminal}); + auto raw_phy_ptr = new PhysicalTerminal(this, QVector>{casted_->realTerminal()}); m_physical_terminals.append(raw_phy_ptr->sharedRef()); - static_cast(terminal)->setParentTerminalStrip(this); - return true; } @@ -135,33 +174,71 @@ bool TerminalStrip::addTerminal(Element *terminal) */ bool TerminalStrip::removeTerminal(Element *terminal) { - if (m_terminal_elements_vector.contains(terminal)) + for (const auto &real_t : realTerminals()) { - m_terminal_elements_vector.removeOne(terminal); - //Get the real and physical terminal associated to @terminal - if (auto real_terminal = realTerminal(terminal)) + if (real_t->element() == terminal) { - if (auto physical_terminal = physicalTerminal(real_terminal)) + if (auto physical_t = real_t->physicalTerminal()) { - if (physical_terminal->levelCount() == 1) { - m_physical_terminals.removeOne(physical_terminal); - } else { - auto v = physical_terminal->realTerminals(); - v.removeOne(real_terminal); - physical_terminal->setTerminals(v); + physical_t->removeTerminal(real_t); + if (physical_t->realTerminalCount() == 0) { + m_physical_terminals.removeOne(physical_t); } } - m_real_terminals.removeOne(real_terminal); - static_cast(terminal)->setParentTerminalStrip(nullptr); - - rebuildRealVector(); return true; } - - //There is no reason to be here, but in case of.... - return false; } + + return false; +} + +/** + * @brief TerminalStrip::addTerminal + * Add @a phy_t in this terminal strip. + * @param phy_t + * @return true if successfully added. A terminal can't be added is already + * belong to another terminal strip. + */ +bool TerminalStrip::addTerminal(QSharedPointer phy_t) +{ + if (phy_t->terminalStrip()) { + if (phy_t->terminalStrip() == this) + return true; + else + return false; + } + + m_physical_terminals.append(phy_t); + phy_t->setParentStrip(this); + + emit orderChanged(); + return true; + +} + +/** + * @brief TerminalStrip::removeTerminal + * Remove @a phy_t from this terminal strip. + * @param phy_t + * @return true if successfully removed. Return false if can't be removed + * because not owned by this strip + */ +bool TerminalStrip::removeTerminal(QSharedPointer phy_t) +{ + if (m_physical_terminals.removeOne(phy_t)) + { + for (const auto &real_t : phy_t->realTerminals()) { + if (auto bridge_ = real_t->bridge()) { + bridge_->removeTerminal(real_t); + } + } + + phy_t->setParentStrip(nullptr); + emit orderChanged(); + return true; + } + return false; } @@ -201,20 +278,17 @@ QSharedPointer TerminalStrip::physicalTerminal(int index) cons } /** - * @brief TerminalStrip::physicalTerminalData - * @param real_terminal - * @return the parent PhysicalTerminal of \p real_terminal. - * the PhysicalTerminal can be null if \p real_terminal don't belong to this strip + * @brief TerminalStrip::physicalTerminal + * @param uuid + * @return the the physicalTerminal with the uuid @a uuid or a empty + * QSharedPointer if empty. */ -QSharedPointer TerminalStrip::physicalTerminal (const QSharedPointer &real_terminal) const +QSharedPointer TerminalStrip::physicalTerminal(const QUuid &uuid) const { - if (real_terminal.isNull()) { - return QSharedPointer(); - } - - for (auto &physical : qAsConst(m_physical_terminals)) { - if (physical->realTerminals().contains(real_terminal)) { - return physical; + for (const auto &phy_t : m_physical_terminals) + { + if (phy_t->uuid() == uuid) { + return phy_t; } } @@ -230,23 +304,6 @@ QVector> TerminalStrip::physicalTerminal() cons return m_physical_terminals; } -/** - * @brief TerminalStrip::realTerminal - * @param terminal - * @return the real terminal linked to \p terminal - * the returned QSharedPointer can be null. - */ -QSharedPointer TerminalStrip::realTerminal(Element *terminal) const -{ - for (const auto &real : qAsConst(m_real_terminals)) { - if (real->element() == terminal) { - return real; - } - } - - return shared_real_terminal(); -} - /** * @brief TerminalStrip::realTerminalForUuid * @param uuid @@ -254,8 +311,8 @@ QSharedPointer TerminalStrip::realTerminal(Element *terminal) cons */ QSharedPointer TerminalStrip::realTerminalForUuid(const QUuid &uuid) const { - for (const auto &t : qAsConst(m_real_terminals)) { - if (t->uuid() == uuid) { + for (const auto &t : realTerminals()) { + if (t->elementUuid() == uuid) { return t; } } @@ -263,6 +320,19 @@ QSharedPointer TerminalStrip::realTerminalForUuid(const QUuid &uui return QSharedPointer(); } +/** + * @brief TerminalStrip::realTerminals + * @return All real terminal owned by this strip + */ +QVector> TerminalStrip::realTerminals() const +{ + QVector> vector_; + for (const auto &phy : qAsConst(m_physical_terminals)) { + vector_.append(phy->realTerminals()); + } + return vector_; +} + /** * @brief TerminalStrip::setSortedTo @@ -299,7 +369,6 @@ bool TerminalStrip::setOrderTo(const QVector> & } m_physical_terminals = new_order; - rebuildRealVector(); emit orderChanged(); return true; } @@ -329,9 +398,9 @@ bool TerminalStrip::groupTerminals(const QSharedPointer &recei continue; } - auto physical_ = physicalTerminal(added_terminal); - physical_->removeTerminal(added_terminal); - + if (auto phy_t = added_terminal->physicalTerminal()) { + phy_t->removeTerminal(added_terminal); + } receiver_terminal->addTerminal(added_terminal); have_grouped = true; } @@ -345,7 +414,6 @@ bool TerminalStrip::groupTerminals(const QSharedPointer &recei } } - rebuildRealVector(); emit orderChanged(); } return true; @@ -363,7 +431,7 @@ void TerminalStrip::unGroupTerminals(const QVector> { if (real_terminal) { - if (auto physical_terminal = physicalTerminal(real_terminal)) //Get the physical terminal + if (auto physical_terminal = real_terminal->physicalTerminal()) //Get the physical terminal { if (physical_terminal->realTerminals().size() > 1) //Check if physical have more than one real terminal { @@ -377,7 +445,6 @@ void TerminalStrip::unGroupTerminals(const QVector> } if (ungrouped) { - rebuildRealVector(); emit orderChanged(); } } @@ -392,13 +459,11 @@ bool TerminalStrip::setLevel(const QSharedPointer &real_terminal, { if (real_terminal) { - auto physical_terminal = physicalTerminal(real_terminal); - if (physical_terminal) + if (auto physical_terminal = real_terminal->physicalTerminal()) { if (physical_terminal->realTerminals().size() > 1 && physical_terminal->setLevelOf(real_terminal, level)) { - rebuildRealVector(); emit orderChanged(); return true; } @@ -433,7 +498,7 @@ bool TerminalStrip::isBridgeable(const QVector> &re const int level_ = first_real_terminal->level(); // Get the physical terminal and pos - auto first_physical_terminal = physicalTerminal(first_real_terminal); + auto first_physical_terminal = first_real_terminal->physicalTerminal(); QVector physical_vector{first_physical_terminal}; QVector pos_vector{m_physical_terminals.indexOf(first_physical_terminal)}; @@ -456,7 +521,7 @@ bool TerminalStrip::isBridgeable(const QVector> &re } // Not to the same physical terminal of a previous checked real terminal - const auto physical_terminal = physicalTerminal(real_terminal); + const auto physical_terminal = real_terminal->physicalTerminal(); if (physical_vector.contains(physical_terminal)) { return false; } else { @@ -604,7 +669,7 @@ bool TerminalStrip::canUnBridge(const QVector > &re if (compar_bridge != isBridged(real_t)) { return false; } else { - sorted_terminal.insert(m_physical_terminals.indexOf(physicalTerminal(real_t)), + sorted_terminal.insert(m_physical_terminals.indexOf(real_t->physicalTerminal()), real_t); } } @@ -698,7 +763,7 @@ QSharedPointer TerminalStrip::bridgeFor(const QVector TerminalStrip::previousTerminalInLevel(const QSharedPointer &real_terminal) const { - const auto phy_t = physicalTerminal(real_terminal); + const auto phy_t = real_terminal->physicalTerminal(); if (real_terminal && phy_t) { const auto level_ = phy_t->levelOf(real_terminal); @@ -723,7 +788,7 @@ QSharedPointer TerminalStrip::previousTerminalInLevel(const QShare */ QSharedPointer TerminalStrip::nextTerminalInLevel(const QSharedPointer &real_terminal) const { - const auto phy_t = physicalTerminal(real_terminal); + const auto phy_t = real_terminal->physicalTerminal(); if (real_terminal && phy_t) { const auto level_ = phy_t->levelOf(real_terminal); @@ -742,30 +807,24 @@ QSharedPointer TerminalStrip::nextTerminalInLevel(const QSharedPoi QSharedPointer TerminalStrip::previousRealTerminal(const QSharedPointer &real_terminal) const { - const auto index = m_real_terminals.indexOf(real_terminal); + const auto real_t_vector = realTerminals(); + const auto index = real_t_vector.indexOf(real_terminal); if (index) { - return m_real_terminals.at(index-1); + return real_t_vector.at(index-1); } return QSharedPointer(); } QSharedPointer TerminalStrip::nextRealTerminal(const QSharedPointer &real_terminal) const { - const auto index = m_real_terminals.indexOf(real_terminal); - if (index != m_real_terminals.size()-1) { - return m_real_terminals.at(index+1); + const auto real_t_vector = realTerminals(); + const auto index = real_t_vector.indexOf(real_terminal); + if (index != real_t_vector.size()-1) { + return real_t_vector.at(index+1); } return QSharedPointer(); } -/** - * @brief TerminalStrip::terminalElement - * @return A vector of all terminal element owned by this strip - */ -QVector > TerminalStrip::terminalElement() const { - return m_terminal_elements_vector; -} - /** * @brief TerminalStrip::toXml * @param parent_document @@ -814,7 +873,7 @@ bool TerminalStrip::fromXml(QDomElement &xml_element) { //Get all free elements terminal of the project const ElementProvider ep(m_project); - const auto free_terminals = ep.freeTerminal(); + auto free_terminals = ep.freeTerminal(); //Read each physical terminal for(auto &xml_physical : QETXML::findInDomElement(xml_layout, PhysicalTerminal::xmlTagName())) @@ -824,20 +883,22 @@ bool TerminalStrip::fromXml(QDomElement &xml_element) //Read each real terminal of the current physical terminal of the loop for (auto &xml_real : QETXML::findInDomElement(xml_physical, RealTerminal::xmlTagName())) { - auto raw_ptr = new RealTerminal(this); - auto real_t = raw_ptr->sharedRef(); - real_t->fromXml(xml_real, free_terminals); - if(real_t->isElement()) + const auto uuid_ = QUuid(xml_real.attribute(QStringLiteral("element_uuid"))); + for (auto terminal_elmt : qAsConst(free_terminals)) { - m_terminal_elements_vector.append(real_t->element()); - static_cast(real_t->element())->setParentTerminalStrip(this); + if (terminal_elmt->uuid() == uuid_) + { + real_t_vector.append(terminal_elmt->realTerminal()); + //Remove the actual terminal element from the vector, they dicrease the size + //of the vector and so each iteration have less terminal element to check + free_terminals.removeOne(terminal_elmt); + break; + } } - real_t_vector.append(real_t); } auto raw_ptr = new PhysicalTerminal(this, real_t_vector); m_physical_terminals.append(raw_ptr->sharedRef()); - m_real_terminals.append(real_t_vector); } } @@ -854,16 +915,3 @@ bool TerminalStrip::fromXml(QDomElement &xml_element) return true; } - -/** - * @brief TerminalStrip::rebuildRealVector - * Rebuild the real terminal vector - * to be ordered - */ -void TerminalStrip::rebuildRealVector() -{ - m_real_terminals.clear(); - for (const auto &phy : qAsConst(m_physical_terminals)) { - m_real_terminals.append(phy->realTerminals()); - } -} diff --git a/sources/TerminalStrip/terminalstrip.h b/sources/TerminalStrip/terminalstrip.h index 928cf01da..da4765a22 100644 --- a/sources/TerminalStrip/terminalstrip.h +++ b/sources/TerminalStrip/terminalstrip.h @@ -77,16 +77,20 @@ class TerminalStrip : public QObject TerminalStripData data() const; void setData(const TerminalStripData &data); + bool addTerminal (QSharedPointer real_t); + bool removeTerminal (QSharedPointer real_t); bool addTerminal (Element *terminal); bool removeTerminal (Element *terminal); + bool addTerminal (QSharedPointer phy_t); + bool removeTerminal(QSharedPointer phy_t); int pos(const QSharedPointer &terminal) const; int physicalTerminalCount() const; QSharedPointer physicalTerminal(int index) const; - QSharedPointer physicalTerminal (const QSharedPointer &real_terminal) const; + QSharedPointer physicalTerminal(const QUuid &uuid) const; QVector> physicalTerminal() const; - QSharedPointer realTerminal(Element *terminal) const; QSharedPointer realTerminalForUuid(const QUuid &uuid) const; + QVector> realTerminals() const; bool setOrderTo(const QVector> &sorted_vector); bool groupTerminals(const QSharedPointer &receiver_terminal, const QVector> &added_terminals); @@ -107,20 +111,13 @@ class TerminalStrip : public QObject QSharedPointer previousRealTerminal(const QSharedPointer &real_terminal) const; QSharedPointer nextRealTerminal(const QSharedPointer &real_terminal) const; - QVector> terminalElement() const; - static QString xmlTagName() {return QStringLiteral("terminal_strip");} QDomElement toXml(QDomDocument &parent_document); bool fromXml(QDomElement &xml_element); - private: - void rebuildRealVector(); - private: TerminalStripData m_data; QPointer m_project; - QVector> m_terminal_elements_vector; - QVector> m_real_terminals; QVector> m_physical_terminals; QVector> m_bridge; }; diff --git a/sources/TerminalStrip/terminalstripbridge.cpp b/sources/TerminalStrip/terminalstripbridge.cpp index 81e203542..368bf956c 100644 --- a/sources/TerminalStrip/terminalstripbridge.cpp +++ b/sources/TerminalStrip/terminalstripbridge.cpp @@ -90,7 +90,7 @@ QDomElement TerminalStripBridge::toXml(QDomDocument &parent_document) const if (real_t) { auto terminal_elmt = parent_document.createElement(QStringLiteral("real_terminal")); - terminal_elmt.setAttribute(QStringLiteral("uuid"), real_t->uuid().toString()); + terminal_elmt.setAttribute(QStringLiteral("uuid"), real_t->elementUuid().toString()); terminals_elmt.appendChild(terminal_elmt); } } @@ -163,3 +163,7 @@ void TerminalStripBridge::removeTerminals(const QVector &real_terminal) { + m_real_terminals.removeOne(real_terminal); +} diff --git a/sources/TerminalStrip/terminalstripbridge.h b/sources/TerminalStrip/terminalstripbridge.h index 61be0cdd7..ef53db5f2 100644 --- a/sources/TerminalStrip/terminalstripbridge.h +++ b/sources/TerminalStrip/terminalstripbridge.h @@ -50,6 +50,7 @@ class TerminalStripBridge private: bool addTerminals(const QVector> &real_terminals); void removeTerminals(const QVector> &real_terminals); + void removeTerminal(const QSharedPointer &real_terminal); private: diff --git a/sources/TerminalStrip/ui/freeterminaleditor.cpp b/sources/TerminalStrip/ui/freeterminaleditor.cpp new file mode 100644 index 000000000..674b1540a --- /dev/null +++ b/sources/TerminalStrip/ui/freeterminaleditor.cpp @@ -0,0 +1,258 @@ +/* + Copyright 2006-2022 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 "freeterminaleditor.h" +#include "ui_freeterminaleditor.h" + +#include "../undocommand/changeelementdatacommand.h" +#include "../../diagram.h" +#include "../../elementprovider.h" +#include "freeterminalmodel.h" +#include "../terminalstrip.h" +#include "../UndoCommand/addterminaltostripcommand.h" + +/** + * @brief FreeTerminalEditor::FreeTerminalEditor + * @param project + * @param parent + */ +FreeTerminalEditor::FreeTerminalEditor(QETProject *project, QWidget *parent) : + QWidget(parent), + ui(new Ui::FreeTerminalEditor), + m_project(project) +{ + ui->setupUi(this); + ui->m_table_view->setItemDelegate(new FreeTerminalModelDelegate(ui->m_table_view)); + + m_model = new FreeTerminalModel(m_project, this); + ui->m_table_view->setModel(m_model); + ui->m_table_view->setCurrentIndex(m_model->index(0,0)); + + //Disabled the move if the table is currently edited (yellow cell) + connect(m_model, &FreeTerminalModel::dataChanged, this, [=] { + this->setDisabledMove(); + }); + + connect(ui->m_table_view, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index) + { + if (m_model->columnTypeForIndex(index) == FreeTerminalModel::XRef) + { + auto mrtd = m_model->dataAtRow(index.row()); + if (mrtd.element_) + { + auto elmt = mrtd.element_; + auto diagram = elmt->diagram(); + if (diagram) + { + diagram->showMe(); + if (diagram->views().size()) + { + auto fit_view = elmt->sceneBoundingRect(); + fit_view.adjust(-200,-200,200,200); + diagram->views().at(0)->fitInView(fit_view, Qt::KeepAspectRatioByExpanding); + } + } + } + } + }); +} + +/** + * @brief FreeTerminalEditor::~FreeTerminalEditor + */ +FreeTerminalEditor::~FreeTerminalEditor() +{ + delete ui; +} + +/** + * @brief FreeTerminalEditor::reload + * Reload the editor to be up to date with + * the current state of the project. + * Every not applied change will be lost. + */ +void FreeTerminalEditor::reload() +{ + m_model->clear(); + ui->m_move_in_cb->clear(); + + if (m_project) + { + const auto strip_vector = m_project->terminalStrip(); + for (const auto &strip : strip_vector) + { + QString str(strip->installation() + " " + strip->location() + " " + strip->name()); + ui->m_move_in_cb->addItem(str, strip->uuid()); + } + setDisabledMove(false); + } +} + +/** + * @brief FreeTerminalEditor::apply + * Applu current edited values + */ +void FreeTerminalEditor::apply() +{ + const auto modified_data = m_model->modifiedModelRealTerminalData(); + if (modified_data.size()) + { + m_project->undoStack()->beginMacro(tr("Modifier des propriétés de borniers")); + + for (const auto &data_ : modified_data) + { + if (auto element_ = data_.element_) + { + auto current_data = element_->elementData(); + current_data.setTerminalType(data_.type_); + current_data.setTerminalFunction(data_.function_); + current_data.setTerminalLED(data_.led_); + current_data.m_informations.addValue(QStringLiteral("label"), data_.label_); + + if (element_->elementData() != current_data) { + m_project->undoStack()->push(new ChangeElementDataCommand(element_, current_data)); + } + } + } + + m_project->undoStack()->endMacro(); + } + + reload(); +} + +void FreeTerminalEditor::on_m_type_cb_activated(int index) +{ + if (m_model) + { + const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes(); + + for (auto model_index : index_list) + { + auto type_index = m_model->index(model_index.row(), FreeTerminalModel::Type, model_index.parent()); + if (type_index.isValid()) + { + ElementData::TerminalType override_type; + switch (index) { + case 0: + override_type = ElementData::TTGeneric; break; + case 1: + override_type = ElementData::TTFuse; break; + case 2: + override_type = ElementData::TTSectional; break; + case 3: + override_type = ElementData::TTDiode; break; + case 4: + override_type = ElementData::TTGround; break; + default: + override_type = ElementData::TTGeneric; break; + } + m_model->setData(type_index, override_type); + } + } + } +} + + +void FreeTerminalEditor::on_m_function_cb_activated(int index) +{ + if (m_model) + { + const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes(); + + for (auto model_index : index_list) + { + auto function_index = m_model->index(model_index.row(), FreeTerminalModel::Function, model_index.parent()); + if (function_index.isValid()) + { + ElementData::TerminalFunction override_function; + switch (index) { + case 0: + override_function = ElementData::TFGeneric; break; + case 1: + override_function = ElementData::TFPhase; break; + case 2: + override_function = ElementData::TFNeutral; break; + default: + override_function = ElementData::TFGeneric; break; + } + m_model->setData(function_index, override_function); + } + } + } +} + + +void FreeTerminalEditor::on_m_led_cb_activated(int index) +{ + if (m_model) + { + const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes(); + + for (auto model_index : index_list) + { + auto led_index = m_model->index(model_index.row(), FreeTerminalModel::Led, model_index.parent()); + + if (led_index.isValid()) { + m_model->setData(led_index, + index == 0 ? false : true); + } + } + } +} + + +void FreeTerminalEditor::on_m_move_pb_clicked() +{ + //Get the selected real terminal + const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes(); + const auto real_t_vector = m_model->realTerminalForIndex(index_list); + if (real_t_vector.isEmpty()) { + return; + } + + //Get the terminal strip who receive the real terminal + const auto strip_uuid = ui->m_move_in_cb->currentData().toUuid(); + TerminalStrip *terminal_strip{nullptr}; + for (const auto &strip : m_project->terminalStrip()) { + if (strip->uuid() == strip_uuid) { + terminal_strip = strip; + break; + } + } + + if (!terminal_strip) { + return; + } + + //Apply action with an undo command + auto parent_undo = new QUndoCommand(tr("Déplacer des bornes à un groupe de bornes")); + for (const auto &rt_ : real_t_vector) { + new AddTerminalToStripCommand(rt_, terminal_strip, parent_undo); + } + m_project->undoStack()->push(parent_undo); + + reload(); +} + +void FreeTerminalEditor::setDisabledMove(bool b) +{ + ui->m_move_label->setDisabled(b); + ui->m_move_in_cb->setDisabled(b); + ui->m_move_pb->setDisabled(b); +} + diff --git a/sources/TerminalStrip/ui/freeterminaleditor.h b/sources/TerminalStrip/ui/freeterminaleditor.h new file mode 100644 index 000000000..3460778c4 --- /dev/null +++ b/sources/TerminalStrip/ui/freeterminaleditor.h @@ -0,0 +1,58 @@ +/* + Copyright 2006-2022 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 FREETERMINALEDITOR_H +#define FREETERMINALEDITOR_H + +#include + +class QETProject; +class RealTerminal; +class FreeTerminalModel; +class QTableView; + +namespace Ui { + class FreeTerminalEditor; +} + +class FreeTerminalEditor : public QWidget +{ + Q_OBJECT + + public: + explicit FreeTerminalEditor(QETProject *project, QWidget *parent = nullptr); + ~FreeTerminalEditor(); + + void reload(); + void apply(); + + private slots: + void on_m_type_cb_activated(int index); + void on_m_function_cb_activated(int index); + void on_m_led_cb_activated(int index); + void on_m_move_pb_clicked(); + + private: + void selectionChanged(); + void setDisabledMove(bool b=true); + + private: + Ui::FreeTerminalEditor *ui; + QETProject *m_project = nullptr; + FreeTerminalModel *m_model = nullptr; +}; +#endif // FREETERMINALEDITOR_H diff --git a/sources/TerminalStrip/ui/freeterminaleditor.ui b/sources/TerminalStrip/ui/freeterminaleditor.ui new file mode 100644 index 000000000..f464b3e1d --- /dev/null +++ b/sources/TerminalStrip/ui/freeterminaleditor.ui @@ -0,0 +1,167 @@ + + + FreeTerminalEditor + + + + 0 + 0 + 727 + 279 + + + + Form + + + + + + Déplacer dans : + + + + + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + true + + + + + + + Type : + + + + + + + Fonction : + + + + + + + LED : + + + + + + + Appliquer le déplacement + + + + + + + :/ico/22x22/dialog-ok.png:/ico/22x22/dialog-ok.png + + + + + + + Qt::Horizontal + + + + + + + + Générique + + + + + Fusible + + + + + Sectionnable + + + + + Diode + + + + + Terre + + + + + + + + + Générique + + + + + Phase + + + + + Neutre + + + + + + + + + Sans + + + + + Avec + + + + + + + + + + + diff --git a/sources/TerminalStrip/ui/freeterminalmodel.cpp b/sources/TerminalStrip/ui/freeterminalmodel.cpp new file mode 100644 index 000000000..a05542b12 --- /dev/null +++ b/sources/TerminalStrip/ui/freeterminalmodel.cpp @@ -0,0 +1,376 @@ +/* + Copyright 2006-2022 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 + +#include "freeterminalmodel.h" +#include "../../elementprovider.h" +#include "../../utils/qetutils.h" +#include "../../qetgraphicsitem/terminalelement.h" +#include "../realterminal.h" + +const int LABEL_CELL = 0; +const int XREF_CELL = 1; +const int TYPE_CELL = 2; +const int FUNCTION_CELL = 3; +const int LED_CELL = 4; + +const int ROW_COUNT = 5; + +static QVector UNMODIFIED_CELL_VECTOR{false, false, false, false, false}; + +FreeTerminalModel::Column FreeTerminalModel::columnTypeForIndex(const QModelIndex &index) +{ + if (index.isValid()) + { + switch (index.column()) { + case 0 : return Label; + case 1 : return XRef; + case 2 : return Type; + case 3 : return Function; + case 4 : return Led; + default : return Invalid; + } + } + return Invalid; +} + +/** + * @brief FreeTerminalModel::FreeTerminalModel + * @param project + * @param parent + */ +FreeTerminalModel::FreeTerminalModel(QETProject *project, QObject *parent) : + QAbstractTableModel(parent), + m_project(project) +{ + fillTerminalVector(); +} + +/** + * @brief FreeTerminalModel::rowCount + * @param parent + */ +int FreeTerminalModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return m_terminal_vector.size(); +} + +/** + * @brief FreeTerminalModel::columnCount + * @param parent + */ +int FreeTerminalModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return ROW_COUNT; +} + +/** + * @brief FreeTerminalModel::data + * @param index + * @param role + * @return + */ +QVariant FreeTerminalModel::data(const QModelIndex &index, int role) const +{ + if (index.row() >= rowCount(QModelIndex())) { + return QVariant(); + } + + const auto real_t_data = m_real_t_data.at(index.row()); + + if (role == Qt::DisplayRole) + { + + switch (index.column()) + { + case LABEL_CELL: return real_t_data.label_; + case XREF_CELL : return real_t_data.Xref_; + case TYPE_CELL : return ElementData::translatedTerminalType(real_t_data.type_); + case FUNCTION_CELL: return ElementData::translatedTerminalFunction(real_t_data.function_); + default : return QVariant(); + } + } + else if (role == Qt::EditRole) + { + switch (index.column()) { + case LABEL_CELL : return real_t_data.label_; + default : return QVariant(); + } + } + else if (role == Qt::CheckStateRole && + index.column() == LED_CELL) { + return real_t_data.led_ ? Qt::Checked : Qt::Unchecked; + } + else if (role == Qt::BackgroundRole && index.column() <= LED_CELL) + { + if (m_modified_cell.contains(real_t_data.real_terminal) && + m_modified_cell.value(real_t_data.real_terminal).at(index.column())) + { + return QBrush(Qt::yellow); + } + } + + return QVariant(); +} + +bool FreeTerminalModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + auto mrtd = dataAtRow(index.row()); + bool modified_ = false; + int modified_cell = -1; + auto column_ = index.column(); + + + if (column_ == LABEL_CELL && + role == Qt::EditRole && + mrtd.label_ != value.toString()) + { + mrtd.label_ = value.toString(); + modified_ = true; + modified_cell = LABEL_CELL; + } + else if (column_ == TYPE_CELL && + role == Qt::EditRole) + { + mrtd.type_ = value.value(); + modified_ = true; + modified_cell = TYPE_CELL; + } + else if (column_ == FUNCTION_CELL && + role == Qt::EditRole) + { + mrtd.function_ = value.value(); + modified_ = true; + modified_cell = FUNCTION_CELL; + } + else if (column_ == LED_CELL) + { + mrtd.led_ = value.toBool(); + modified_ = true; + modified_cell = LED_CELL; + } + + //Set the modification to the terminal data + if (modified_) + { + m_real_t_data.replace(index.row(), mrtd); + + QVector vector_; + if (m_modified_cell.contains(mrtd.real_terminal)) { + vector_ = m_modified_cell.value(mrtd.real_terminal); + } else { + vector_ = UNMODIFIED_CELL_VECTOR; + } + + vector_.replace(modified_cell, true); + m_modified_cell.insert(mrtd.real_terminal, vector_); + emit dataChanged(index, index); + return true; + } + + return false; +} + +/** + * @brief FreeTerminalModel::headerData + * @param section + * @param orientation + * @param role + * @return + */ +QVariant FreeTerminalModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole) + { + if (orientation == Qt::Horizontal) + { + switch (section) { + case LABEL_CELL: return tr("Label"); + case XREF_CELL: return tr("Référence croisé"); + case TYPE_CELL: return tr("Type"); + case FUNCTION_CELL: return tr("Fonction"); + case LED_CELL: return tr("led"); + default : return QVariant(); + } + } + } + + return QVariant(); +} + +Qt::ItemFlags FreeTerminalModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + auto c = index.column(); + if (c == LABEL_CELL || c == TYPE_CELL || c == FUNCTION_CELL) + flags = flags | Qt::ItemIsEditable; + if (c == LED_CELL) { + flags = flags | Qt::ItemIsUserCheckable; + } + return flags; +} + +/** + * @brief FreeTerminalModel::clear + * Clear the model and set it as the current + * state of the project + */ +void FreeTerminalModel::clear() +{ + beginResetModel(); + m_terminal_vector.clear(); + m_real_t_data.clear(); + m_modified_cell.clear(); + fillTerminalVector(); + endResetModel(); +} + +/** + * @brief FreeTerminalModel::modifiedModelRealTerminalData + * @return a vector of modified terminal. + */ +QVector FreeTerminalModel::modifiedModelRealTerminalData() const +{ + QVector returned_vector; + + for (const auto &real_t_data : m_real_t_data) { + if (m_modified_cell.contains(real_t_data.real_terminal)) { + returned_vector.append(real_t_data); + } + } + + return returned_vector; +} + +/** + * @brief FreeTerminalModel::dataAtRow + * @param row + * @return the current data at row @a row + */ +modelRealTerminalData FreeTerminalModel::dataAtRow(int row) const +{ + if (row >= m_terminal_vector.size()) { + return modelRealTerminalData(); + } else { + return m_real_t_data.at(row); + } +} + +/** + * @brief FreeTerminalModel::realTerminalForIndex + * @param index_list + * @return The QSharedPointer associated with the index found in @a index_list + */ +QVector > FreeTerminalModel::realTerminalForIndex(const QModelIndexList &index_list) const +{ + QVector> vector_; + for (const auto &index : index_list) + { + if (index.isValid() + && index.model() == this + && index.row() < m_terminal_vector.size()) + { + const auto rt_ = m_terminal_vector.at(index.row()); + if (!vector_.contains(rt_)) { + vector_.append(m_terminal_vector.at(index.row())); + } + } + } + + return vector_; +} + +/** + * @brief FreeTerminalModel::fillTerminalVector + */ +void FreeTerminalModel::fillTerminalVector() +{ + ElementProvider provider_(m_project); + auto free_terminal_vector = provider_.freeTerminal(); + + std::sort(free_terminal_vector.begin(), free_terminal_vector.end(), + [](TerminalElement *a, TerminalElement *b) + { + return QETUtils::sortBeginIntString(a->actualLabel(), b->actualLabel()); + }); + + for (const auto &terminal_ : free_terminal_vector) { + m_terminal_vector.append(terminal_->realTerminal()); + m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal())); + } +} + +/**************************************************************** + * A little delegate for add a combobox to edit type and function + ****************************************************************/ + +FreeTerminalModelDelegate::FreeTerminalModelDelegate(QObject *parent) : + QStyledItemDelegate(parent) +{} + +QWidget *FreeTerminalModelDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (index.column() == TYPE_CELL) { + auto qcb = new QComboBox(parent); + qcb->setObjectName(QLatin1String("terminal_type")); + qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGeneric), ElementData::TTGeneric); + qcb->addItem(ElementData::translatedTerminalType(ElementData::TTFuse), ElementData::TTFuse); + qcb->addItem(ElementData::translatedTerminalType(ElementData::TTSectional), ElementData::TTSectional); + qcb->addItem(ElementData::translatedTerminalType(ElementData::TTDiode), ElementData::TTDiode); + qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGround), ElementData::TTGround); + + return qcb; + } + if (index.column() == FUNCTION_CELL) { + auto qcb = new QComboBox(parent); + qcb->setObjectName(QLatin1String("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); +} + +void FreeTerminalModelDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if (index.isValid()) + { + if (editor->objectName() == QLatin1String("terminal_type")) + { + if (auto qcb = dynamic_cast(editor)) { + model->setData(index, qcb->currentData(), Qt::EditRole); + } + } + else if (editor->objectName() == QLatin1String("terminal_function")) + { + if (auto qcb = dynamic_cast(editor)) { + model->setData(index, qcb->currentData(), Qt::EditRole); + } + } + else { + QStyledItemDelegate::setModelData(editor, model, index); + } + } +} diff --git a/sources/TerminalStrip/ui/freeterminalmodel.h b/sources/TerminalStrip/ui/freeterminalmodel.h new file mode 100644 index 000000000..2e7235217 --- /dev/null +++ b/sources/TerminalStrip/ui/freeterminalmodel.h @@ -0,0 +1,84 @@ +/* + Copyright 2006-2022 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 FREETERMINALMODEL_H +#define FREETERMINALMODEL_H + +#include +#include +#include + +#include "modelTerminalData.h" +#include "../../qetproject.h" + +class RealTerminal; + +/** + * @brief The FreeTerminalModel class + */ +class FreeTerminalModel : public QAbstractTableModel +{ + public: + enum Column { + Label = 0, + XRef = 1, + Type = 2, + Function = 3, + Led = 4, + Invalid = 99 + }; + + static FreeTerminalModel::Column columnTypeForIndex(const QModelIndex &index); + Q_OBJECT + + public: + explicit FreeTerminalModel(QETProject *project, QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void clear(); + QVector modifiedModelRealTerminalData() const; + modelRealTerminalData dataAtRow(int row) const; + QVector> realTerminalForIndex(const QModelIndexList &index_list) const; + + private: + void fillTerminalVector(); + + private: + QPointer m_project; + QVector> m_terminal_vector; + QVector m_real_t_data; + QHash, QVector> m_modified_cell; +}; + +class FreeTerminalModelDelegate : public QStyledItemDelegate +{ + Q_OBJECT + + public: + FreeTerminalModelDelegate(QObject *parent = nullptr); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; +}; + +#endif // FREETERMINALMODEL_H diff --git a/sources/TerminalStrip/ui/modelTerminalData.h b/sources/TerminalStrip/ui/modelTerminalData.h new file mode 100644 index 000000000..fd58b66f5 --- /dev/null +++ b/sources/TerminalStrip/ui/modelTerminalData.h @@ -0,0 +1,76 @@ +/* + 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 MODELTERMINALDATA_H +#define MODELTERMINALDATA_H + +#include +#include "../../qetgraphicsitem/element.h" +#include "../realterminal.h" + +struct modelRealTerminalData +{ + static modelRealTerminalData data(const QSharedPointer &real_t) + { + modelRealTerminalData mrtd; + if (!real_t.isNull()) + { + mrtd.level_ = real_t->level(); + mrtd.label_ = real_t->label(); + mrtd.Xref_ = real_t->Xref(); + mrtd.cable_ = real_t->cable(); + mrtd.cable_wire = real_t->cableWire(); + mrtd.conductor_ = real_t->conductor(); + mrtd.led_ = real_t->isLed(); + mrtd.type_ = real_t->type(); + mrtd.function_ = real_t->function(); + mrtd.element_ = real_t->element(); + mrtd.real_terminal = real_t.toWeakRef(); + mrtd.bridged_ = real_t->isBridged(); + } + + return mrtd; + } + + int level_ = -1; + QString label_; + QString Xref_; + QString cable_; + QString cable_wire; + QString conductor_; + bool led_ = false; + bool bridged_ = false; + + ElementData::TerminalType type_ = ElementData::TerminalType::TTGeneric; + ElementData::TerminalFunction function_ = ElementData::TerminalFunction::TFGeneric; + QPointer element_; + + QWeakPointer real_terminal; +}; + +struct modelPhysicalTerminalData +{ + QVector real_data; + int pos_ = -1; + QUuid uuid_; +}; + +inline bool operator == (const modelPhysicalTerminalData &data_1, const modelPhysicalTerminalData &data_2) { + return data_1.uuid_ == data_2.uuid_; +} + +#endif // MODELTERMINALDATA_H diff --git a/sources/TerminalStrip/ui/terminalstripeditor.cpp b/sources/TerminalStrip/ui/terminalstripeditor.cpp index dd867a02e..e40a51a87 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.cpp +++ b/sources/TerminalStrip/ui/terminalstripeditor.cpp @@ -1,4 +1,4 @@ -/* +/* Copyright 2006-2021 The QElectroTech Team This file is part of QElectroTech. @@ -17,17 +17,10 @@ */ #include "terminalstripeditor.h" #include "ui_terminalstripeditor.h" -#include "terminalstripcreatordialog.h" #include "../../qetproject.h" #include "../terminalstrip.h" -#include "../elementprovider.h" -#include "../qetgraphicsitem/terminalelement.h" -#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" #include "../diagram.h" #include "../UndoCommand/sortterminalstripcommand.h" @@ -36,38 +29,25 @@ #include "../UndoCommand/bridgeterminalscommand.h" #include "../UndoCommand/changeterminalstripcolor.h" #include "../physicalterminal.h" -#include "../realterminal.h" #include "../terminalstripbridge.h" -#include - /** * @brief TerminalStripEditor::TerminalStripEditor * @param project : Project to manage the terminal strip * @param parent : paent widget */ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) : - QDialog(parent), - ui(new Ui::TerminalStripEditor), - m_project(project) + QWidget{parent}, + ui{new Ui::TerminalStripEditor}, + m_project{project} { ui->setupUi(this); - ui->m_table_widget->setItemDelegate(new TerminalStripModelDelegate(ui->m_terminal_strip_tw)); - - ui->m_remove_terminal_strip_pb->setDisabled(true); - buildTree(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - ui->m_terminal_strip_tw->expandRecursively(ui->m_terminal_strip_tw->rootIndex()); -#else - ui->m_terminal_strip_tw->expandAll(); -#endif + ui->m_table_widget->setItemDelegate(new TerminalStripModelDelegate{this}); //Setup the bridge color ui->m_bridge_color_cb->setColors(TerminalStripBridge::bridgeColor().toList()); - setUpUndoConnections(); - //Call for update the state of child widgets selectionChanged(); @@ -103,190 +83,6 @@ TerminalStripEditor::~TerminalStripEditor() { delete ui; } -void TerminalStripEditor::setUpUndoConnections() -{ - connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalAddedToStrip, this, - [=](QUuid terminal_uuid, QUuid strip_uuid) - { - auto terminal = m_uuid_terminal_H.value(terminal_uuid); - auto strip = m_uuid_strip_H.value(strip_uuid); - - if (!terminal || !strip) { - return; - } - - auto undo = new AddTerminalToStripCommand(terminal, strip); - m_project->undoStack()->push(undo); - }); - - connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalMovedFromStripToStrip, this, - [=] (QUuid terminal_uuid, QUuid old_strip_uuid, QUuid new_strip_uuid) - { - auto terminal = m_uuid_terminal_H.value(terminal_uuid); - auto old_strip = m_uuid_strip_H.value(old_strip_uuid); - auto new_strip = m_uuid_strip_H.value(new_strip_uuid); - - if (!terminal || !old_strip || !new_strip) { - return; - } - - auto undo = new AddTerminalToStripCommand(terminal, old_strip, new_strip); - m_project->undoStack()->push(undo); - }); - - connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalRemovedFromStrip, this, - [=] (QUuid terminal_uuid, QUuid old_strip_uuid) - { - auto terminal_ = m_uuid_terminal_H.value(terminal_uuid); - auto strip_ = m_uuid_strip_H.value(old_strip_uuid); - - if (!terminal_ || !strip_) { - return; - } - - auto undo = new RemoveTerminalFromStripCommand(terminal_, strip_); - m_project->undoStack()->push(undo); - }); -} - -/** - * @brief TerminalStripEditor::buildTree - * Build the tree widget use to explore terminal strip - */ -void TerminalStripEditor::buildTree() -{ - ui->m_terminal_strip_tw->clear(); - - auto title = m_project->title(); - if (title.isEmpty()) { - title = tr("Projet sans titre"); - } - - QStringList strl{title}; - new QTreeWidgetItem(ui->m_terminal_strip_tw, strl, TerminalStripTreeWidget::Root); - - QStringList ftstrl(tr("Bornes indépendante")); - new QTreeWidgetItem(ui->m_terminal_strip_tw, ftstrl, TerminalStripTreeWidget::FreeTerminal); - - auto ts_vector = m_project->terminalStrip(); - std::sort(ts_vector.begin(), ts_vector.end(), [](TerminalStrip *a, TerminalStrip *b) { - return a->name() < b->name();}); - - for (const auto ts : qAsConst(ts_vector)) { - addTerminalStrip(ts); - } - addFreeTerminal(); -} - -/** - * @brief TerminalStripEditor::addTerminalStrip - * Add a new terminal strip to the list of displayed terminal strip - * in the tree widget - * @param terminal_strip - * @return the QTreeWidgetItem who represent the terminal strip - * both if created or already exist - */ -QTreeWidgetItem* TerminalStripEditor::addTerminalStrip(TerminalStrip *terminal_strip) -{ - if (auto item = m_item_strip_H.key(terminal_strip)) { - return item; - } - - auto root_item = ui->m_terminal_strip_tw->topLevelItem(0); - - //Check if installation already exist - //if not create a new one - auto installation_str = terminal_strip->installation(); - QTreeWidgetItem *inst_qtwi = nullptr; - for (int i = 0 ; ichildCount() ; ++i) { - auto child_inst = root_item->child(i); - if (child_inst->data(0, Qt::DisplayRole).toString() == installation_str) { - inst_qtwi = child_inst; - break; - } - } - if (!inst_qtwi) { - QStringList inst_strl{installation_str}; - inst_qtwi = new QTreeWidgetItem(root_item, inst_strl, TerminalStripTreeWidget::Installation); - } - - //Check if location already exist - //if not create a new one - auto location_str = terminal_strip->location(); - QTreeWidgetItem *loc_qtwi = nullptr; - for (int i = 0 ; ichildCount() ; ++i) { - auto child_loc = inst_qtwi->child(i); - if (child_loc->data(0, Qt::DisplayRole).toString() == location_str) { - loc_qtwi = child_loc; - break; - } - } - if (!loc_qtwi) { - QStringList loc_strl{location_str}; - loc_qtwi = new QTreeWidgetItem(inst_qtwi, loc_strl, TerminalStripTreeWidget::Location); - } - - //Add the terminal strip - QStringList name{terminal_strip->name()}; - auto strip_item = new QTreeWidgetItem(loc_qtwi, name, TerminalStripTreeWidget::Strip); - strip_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, terminal_strip->uuid()); - strip_item->setIcon(0, QET::Icons::TerminalStrip); - - //Add child terminal of the strip - for (auto i=0 ; iphysicalTerminalCount() ; ++i) - { - auto phy_t = terminal_strip->physicalTerminal(i); - if (phy_t->realTerminalCount()) - { - const auto real_t = phy_t->realTerminals().at(0); - auto terminal_item = new QTreeWidgetItem(strip_item, QStringList(real_t->label()), TerminalStripTreeWidget::Terminal); - terminal_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, real_t->elementUuid()); - terminal_item->setIcon(0, QET::Icons::ElementTerminal); - - if (real_t->element()) { - m_uuid_terminal_H.insert(real_t->elementUuid(), qgraphicsitem_cast(real_t->element())); - } - } - } - - m_item_strip_H.insert(strip_item, terminal_strip); - m_uuid_strip_H.insert(terminal_strip->uuid(), terminal_strip); - return strip_item; -} - -/** - * @brief TerminalStripEditor::addFreeTerminal - * Add free terminal (aka terminal which not belong to a terminal strip) - * in the tree widget - */ -void TerminalStripEditor::addFreeTerminal() -{ - ElementProvider ep(m_project); - auto vector_ = ep.freeTerminal(); - - if (vector_.isEmpty()) { - return; - } - - //Sort the terminal element by label - std::sort(vector_.begin(), vector_.end(), [](TerminalElement *a, TerminalElement *b) { - return a->actualLabel() < b->actualLabel(); - }); - - auto free_terminal_item = ui->m_terminal_strip_tw->topLevelItem(1); - - for (const auto terminal : qAsConst(vector_)) - { - QUuid uuid_ = terminal->uuid(); - QStringList strl{terminal->actualLabel()}; - auto item = new QTreeWidgetItem(free_terminal_item, strl, TerminalStripTreeWidget::Terminal); - item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, uuid_.toString()); - item->setIcon(0, QET::Icons::ElementTerminal); - - m_uuid_terminal_H.insert(uuid_, terminal); - } -} - /** * @brief TerminalStripEditor::setCurrentStrip * Set the current terminal strip edited to \p strip_ @@ -299,8 +95,8 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_) } if (m_current_strip) { - disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); - disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); + disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload); + disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload); } if (!strip_) @@ -328,20 +124,92 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_) m_current_strip = strip_; if (m_model) - m_model->deleteLater(); + { + m_model->setTerminalStrip(strip_); + connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged); + } + else + { + m_model = new TerminalStripModel{strip_, this}; + ui->m_table_widget->setModel(m_model); + m_model->buildBridgePixmap(setUpBridgeCellWidth()); + } - m_model = new TerminalStripModel(strip_, this); - ui->m_table_widget->setModel(m_model); - m_model->buildBridgePixmap(setUpBridgeCellWidth()); spanMultiLevelTerminals(); selectionChanged(); //Used to update child widgets - connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); - connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); - connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged); + connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload); + connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload); } } +/** + * @brief TerminalStripEditor::reload + * Reload this editor and and reset all + * unapplied change. + */ +void TerminalStripEditor::reload() +{ + if (m_current_strip) + { + ui->m_installation_le ->setText(m_current_strip->installation()); + ui->m_location_le ->setText(m_current_strip->location()); + ui->m_name_le ->setText(m_current_strip->name()); + ui->m_comment_le ->setText(m_current_strip->comment()); + ui->m_description_te ->setPlainText(m_current_strip->description()); + } + if (m_model) + { + m_model->reload(); + } +} + +/** + * @brief TerminalStripEditor::apply + * Apply current edited values. + */ +void TerminalStripEditor::apply() +{ + + 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(); + data.m_name = ui->m_name_le->text(); + data.m_comment = ui->m_comment_le->text(); + data.m_description = ui->m_description_te->toPlainText(); + + m_project->undoStack()->push(new ChangeTerminalStripData(m_current_strip, data, nullptr)); + + if (m_model) + { + for (const auto &data_ : m_model->modifiedmodelRealTerminalData()) + { + if (auto element = data_.element_) + { + auto current_data = element->elementData(); + current_data.setTerminalType(data_.type_); + current_data.setTerminalFunction(data_.function_); + current_data.setTerminalLED(data_.led_); + current_data.m_informations.addValue(QStringLiteral("label"), data_.label_); + + if (element->elementData() != current_data) + m_project->undoStack()->push(new ChangeElementDataCommand(element, current_data)); + if (data_.level_ != data_.real_terminal.toStrongRef()->level()) + m_project->undoStack()->push(new ChangeTerminalLevel(m_current_strip, data_.real_terminal, data_.level_)); + } + } + } + + m_project->undoStack()->endMacro(); + } + + reload(); +} + /** * @brief TerminalStripEditor::spanMultiLevelTerminals * Span row of m_table_widget for multi-level terminal @@ -527,165 +395,6 @@ QPair > TerminalStrip return qMakePair(TerminalStripModel::Invalid, QVector()); } -/** - * @brief TerminalStripEditor::on_m_add_terminal_strip_pb_clicked - * Action when user click on add terminal strip button - */ -void TerminalStripEditor::on_m_add_terminal_strip_pb_clicked() -{ - QScopedPointer dialog(new TerminalStripCreatorDialog(m_project, this)); - - if (auto item = ui->m_terminal_strip_tw->currentItem()) - { - if (item->type() == TerminalStripTreeWidget::Strip) { - item = item->parent(); - } - if (item->type() == TerminalStripTreeWidget::Location) { - dialog->setLocation(item->data(0, Qt::DisplayRole).toString()); - item = item->parent(); - } - if (item->type() == TerminalStripTreeWidget::Installation) { - dialog->setInstallation(item->data(0, Qt::DisplayRole).toString()); - } - } - - if (dialog->exec() == QDialog::Accepted) - { - auto ts = dialog->generatedTerminalStrip(); - m_project->undoStack()->push(new AddTerminalStripCommand(ts, m_project)); - - auto item = addTerminalStrip(ts); - ui->m_terminal_strip_tw->setCurrentItem(item); - } -} - -/** - * @brief TerminalStripEditor::on_m_remove_terminal_strip_pb_clicked - * Action when user click on remove terminal strip button - */ -void TerminalStripEditor::on_m_remove_terminal_strip_pb_clicked() -{ - auto item = ui->m_terminal_strip_tw->currentItem(); - if (auto strip = m_item_strip_H.value(item)) - { - m_item_strip_H.remove(item); - m_uuid_strip_H.remove(strip->uuid()); - delete item; - - m_project->undoStack()->push(new RemoveTerminalStripCommand(strip, m_project)); - } - - on_m_reload_pb_clicked(); -} - -/** - * @brief TerminalStripEditor::on_m_reload_pb_clicked - */ -void TerminalStripEditor::on_m_reload_pb_clicked() -{ - auto current_ = m_current_strip; - - ui->m_terminal_strip_tw->clear(); - m_item_strip_H.clear(); - m_uuid_terminal_H.clear(); - m_uuid_strip_H.clear(); - - qDeleteAll(m_item_strip_H.keyBegin(), m_item_strip_H.keyEnd()); - - buildTree(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - ui->m_terminal_strip_tw->expandRecursively(ui->m_terminal_strip_tw->rootIndex()); -#else - ui->m_terminal_strip_tw->expandAll(); -#endif - - //Reselect the tree widget item of the current edited strip - auto item = m_item_strip_H.key(current_); - if (item) { - ui->m_terminal_strip_tw->setCurrentItem(item); - } -} - -/** - * @brief TerminalStripEditor::on_m_terminal_strip_tw_currentItemChanged - * @param current - * @param previous - */ -void TerminalStripEditor::on_m_terminal_strip_tw_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) -{ - Q_UNUSED(previous) - - if (!current) { - setCurrentStrip(nullptr); - ui->m_remove_terminal_strip_pb->setDisabled(true); - return; - } - - TerminalStrip *strip_ = nullptr; - if (current->type() == TerminalStripTreeWidget::Strip) { - strip_ = m_item_strip_H.value(current); - ui->m_remove_terminal_strip_pb->setEnabled(true); - } - else if (current->type() == TerminalStripTreeWidget::Terminal - && current->parent() - && current->parent()->type() == TerminalStripTreeWidget::Strip) { - strip_ = m_item_strip_H.value(current->parent()); - ui->m_remove_terminal_strip_pb->setDisabled(true); - } else { - ui->m_remove_terminal_strip_pb->setDisabled(true); - } - - setCurrentStrip(strip_); -} - -void TerminalStripEditor::on_m_dialog_button_box_clicked(QAbstractButton *button) -{ - Q_UNUSED(button) - - auto role = ui->m_dialog_button_box->buttonRole(button); - - 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(); - data.m_name = ui->m_name_le->text(); - data.m_comment = ui->m_comment_le->text(); - data.m_description = ui->m_description_te->toPlainText(); - - m_project->undoStack()->push(new ChangeTerminalStripData(m_current_strip, data, nullptr)); - - if (m_model) - { - for (const auto &data_ : m_model->modifiedmodelRealTerminalData()) - { - if (auto element = data_.element_) - { - auto current_data = element->elementData(); - current_data.setTerminalType(data_.type_); - current_data.setTerminalFunction(data_.function_); - current_data.setTerminalLED(data_.led_); - current_data.m_informations.addValue(QStringLiteral("label"), data_.label_); - - if (element->elementData() != current_data) - m_project->undoStack()->push(new ChangeElementDataCommand(element, current_data)); - if (data_.level_ != data_.real_terminal.toStrongRef()->level()) - m_project->undoStack()->push(new ChangeTerminalLevel(m_current_strip, data_.real_terminal, data_.level_)); - } - } - } - - m_project->undoStack()->endMacro(); - } - } - - on_m_reload_pb_clicked(); -} - /** * @brief TerminalStripEditor::on_m_auto_pos_pb_clicked */ @@ -707,7 +416,7 @@ void TerminalStripEditor::on_m_group_terminals_pb_clicked() if (mrtd_vector.size() >= 2) { //At this step get the first physical terminal as receiver - auto receiver_ = m_current_strip->physicalTerminal(mrtd_vector.first().real_terminal); + auto receiver_ = mrtd_vector.first().real_terminal.toStrongRef()->physicalTerminal(); QVector> vector_; int count_ = 0; @@ -718,11 +427,11 @@ void TerminalStripEditor::on_m_group_terminals_pb_clicked() //Get the better physical terminal as receiver //(physical terminal with the max of real terminal) - const auto current_physical = m_current_strip->physicalTerminal(real_t); + const auto current_physical = real_t->physicalTerminal(); int real_t_count = current_physical->realTerminalCount(); if (real_t_count > 1 && real_t_count > count_) { count_ = real_t_count; - receiver_ = m_current_strip->physicalTerminal(real_t); + receiver_ = real_t->physicalTerminal(); } } diff --git a/sources/TerminalStrip/ui/terminalstripeditor.h b/sources/TerminalStrip/ui/terminalstripeditor.h index ed7a21c7c..1a6b11c77 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.h +++ b/sources/TerminalStrip/ui/terminalstripeditor.h @@ -18,7 +18,7 @@ #ifndef TERMINALSTRIPEDITOR_H #define TERMINALSTRIPEDITOR_H -#include +#include #include "terminalstripmodel.h" @@ -28,29 +28,24 @@ namespace Ui { class QETProject; class TerminalStrip; -class QTreeWidgetItem; -class TerminalElement; -class QAbstractButton; /** * @brief The TerminalStripEditor class * Main dialog used to edit terminal strip * of a project */ -class TerminalStripEditor : public QDialog +class TerminalStripEditor : public QWidget { Q_OBJECT public: explicit TerminalStripEditor(QETProject *project, QWidget *parent = nullptr); ~TerminalStripEditor() override; + void setCurrentStrip(TerminalStrip *strip_); + void reload(); + void apply(); private: - void setUpUndoConnections(); - void buildTree(); - QTreeWidgetItem* addTerminalStrip(TerminalStrip *terminal_strip); - void addFreeTerminal(); - void setCurrentStrip(TerminalStrip *strip_); void spanMultiLevelTerminals(); void selectionChanged(); QSize setUpBridgeCellWidth(); @@ -58,11 +53,6 @@ class TerminalStripEditor : public QDialog QPair> singleColumnData() const; private slots: - void on_m_add_terminal_strip_pb_clicked(); - void on_m_remove_terminal_strip_pb_clicked(); - void on_m_reload_pb_clicked(); - void on_m_terminal_strip_tw_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - void on_m_dialog_button_box_clicked(QAbstractButton *button); void on_m_auto_ordering_pb_clicked(); void on_m_group_terminals_pb_clicked(); void on_m_ungroup_pb_clicked(); @@ -76,13 +66,9 @@ class TerminalStripEditor : public QDialog private: Ui::TerminalStripEditor *ui; - QETProject *m_project = nullptr; - - QHash m_item_strip_H; - QHash> m_uuid_terminal_H; - QHash> m_uuid_strip_H; - TerminalStrip *m_current_strip = nullptr; - TerminalStripModel *m_model = nullptr; + QETProject *m_project {nullptr}; + TerminalStrip *m_current_strip {nullptr}; + TerminalStripModel *m_model {nullptr}; }; #endif // TERMINALSTRIPEDITOR_H diff --git a/sources/TerminalStrip/ui/terminalstripeditor.ui b/sources/TerminalStrip/ui/terminalstripeditor.ui index 410adace0..f6fb25552 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.ui +++ b/sources/TerminalStrip/ui/terminalstripeditor.ui @@ -1,191 +1,163 @@ TerminalStripEditor - + 0 0 - 1206 - 645 + 922 + 516 - Gestionnaire de borniers + Form - - - - - Qt::Horizontal + + + + + 0 - - - - 0 - 0 - - - - false - - - QAbstractItemView::InternalMove - - - 500 - - - true - - - - Explorateur de bornier - - - - - - - 1 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - + + + Disposition + + - - - - 1 - 0 - + + + + + + + Propriétés + + + + + + Nom : - - 0 - - - - Disposition - - - - - - - 0 - 0 - - - - true - - - false - - - - - - - - Propriétés - - - - - - Nom : - - - - - - - - - - Description - - - - - - - - - - - - - Commentaire - - - - - - - - - - Installation : - - - - - - - Qt::Horizontal - - - - - - - - - - Localisation : - - - - - - - - - QDialogButtonBox::Apply|QDialogButtonBox::Reset + + + + Commentaire : + + + + Installation : + + + + + + + + + + + + + + + + Localisation : + + + + + + + Description + + + + + + + Qt::Horizontal + + + + + + + + + - + - + + + + + Type : + + + + + + Fonction : + + + + + + + Ponter les bornes + + + + + + + Position automatique + + + + + + + Déponter les bornes + + + + + + + Grouper les bornes + + + + Étage : - + + + + + + + LED : + + + + @@ -214,96 +186,7 @@ - - - - LED : - - - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Position automatique - - - - - - - Fonction : - - - - - - - Couleur pont : - - - - - - - Grouper les bornes - - - - - - - Degrouper les bornes - - - - - - - Type : - - - - - - - - Sans - - - - - Avec - - - - - - - - @@ -322,80 +205,57 @@ - - - - Ponter les bornes - - - - - - - Déponter les bornes - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Ajouter un bornier - - - - :/ico/16x16/list-add.png:/ico/16x16/list-add.png - - - - - - - Supprimer le bornier - - - - :/ico/16x16/list-remove.png:/ico/16x16/list-remove.png - - - - - - - - - - - :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png - - - - - + + Qt::Horizontal + + + + + + 6 + + + + + + + Degrouper les bornes + + + + + + + + Sans + + + + + Avec + + + + + + + + Couleur pont : + + + + + + + Qt::Vertical + - 40 - 20 + 20 + 40 @@ -411,31 +271,7 @@ QComboBox
kcolorcombo.h
- - TerminalStripTreeWidget - QTreeWidget -
terminalstriptreewidget.h
-
- - m_add_terminal_strip_pb - m_remove_terminal_strip_pb - m_reload_pb - m_auto_ordering_pb - m_group_terminals_pb - m_ungroup_pb - m_level_sb - m_terminal_strip_tw - m_table_widget - m_description_te - m_comment_le - m_name_le - m_tab_widget - m_installation_le - m_location_le - - - - +
diff --git a/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp b/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp new file mode 100644 index 000000000..425eef77b --- /dev/null +++ b/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp @@ -0,0 +1,185 @@ +/* + Copyright 2006-2022 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 "ui_terminalstripeditorwindow.h" + +#include "../UndoCommand/addterminalstripcommand.h" +#include "freeterminaleditor.h" +#include "../../qetproject.h" +#include "../realterminal.h" +#include "../terminalstrip.h" +#include "terminalstripcreatordialog.h" +#include "terminalstripeditor.h" +#include "terminalstripeditorwindow.h" +#include "terminalstriptreedockwidget.h" + +static const int EMPTY_PAGE = 0; +static const int FREE_TERMINAL_PAGE = 1; +static const int TERMINAL_STRIP_PAGE = 2; +/** + * @brief TerminalStripEditorWindow::TerminalStripEditorWindow + * @param project + * @param parent + */ +TerminalStripEditorWindow::TerminalStripEditorWindow(QETProject *project, QWidget *parent) : + QMainWindow(parent), + ui(new Ui::TerminalStripEditorWindow), + m_project(project) +{ + ui->setupUi(this); + ui->m_remove_terminal->setDisabled(true); + addTreeDockWidget(); + + m_free_terminal_editor = new FreeTerminalEditor(m_project, this); + m_terminal_strip_editor = new TerminalStripEditor{m_project, this}; + + connect(m_tree_dock, &TerminalStripTreeDockWidget::currentStripChanged, this, &TerminalStripEditorWindow::currentStripChanged); + + ui->m_stacked_widget->insertWidget(EMPTY_PAGE, new QWidget(ui->m_stacked_widget)); + ui->m_stacked_widget->insertWidget(FREE_TERMINAL_PAGE, m_free_terminal_editor); + ui->m_stacked_widget->insertWidget(TERMINAL_STRIP_PAGE, m_terminal_strip_editor); +} + +/** + * @brief TerminalStripEditorWindow::~TerminalStripEditorWindow + */ +TerminalStripEditorWindow::~TerminalStripEditorWindow() +{ + delete ui; +} + +/** + * @brief TerminalStripEditorWindow::addTreeDockWidget + */ +void TerminalStripEditorWindow::addTreeDockWidget() +{ + m_tree_dock = new TerminalStripTreeDockWidget(m_project, this); + m_tree_dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + addDockWidget(Qt::LeftDockWidgetArea, m_tree_dock); +} + +/** + * @brief TerminalStripEditorWindow::currentStripChanged + * @param strip + */ +void TerminalStripEditorWindow::currentStripChanged(TerminalStrip *strip) +{ + Q_UNUSED(strip) + updateUi(); + +} + +void TerminalStripEditorWindow::updateUi() +{ + ui->m_remove_terminal->setEnabled(m_tree_dock->currentIsStrip()); + + ui->m_stacked_widget->setCurrentIndex(EMPTY_PAGE); + + if (auto real_terminal = m_tree_dock->currentRealTerminal()) + { + if (!real_terminal->parentStrip()) + { + ui->m_stacked_widget->setCurrentIndex(FREE_TERMINAL_PAGE); + m_free_terminal_editor->reload(); + } + } else if (auto strip_ = m_tree_dock->currentStrip()) { + ui->m_stacked_widget->setCurrentIndex(TERMINAL_STRIP_PAGE); + m_terminal_strip_editor->setCurrentStrip(strip_); + } +} + +/** + * @brief TerminalStripEditorWindow::on_m_add_terminal_strip_triggered + * Action when user click on add terminal strip button + */ +void TerminalStripEditorWindow::on_m_add_terminal_strip_triggered() +{ + QScopedPointer dialog(new TerminalStripCreatorDialog(m_project, this)); + + dialog->setLocation(m_tree_dock->currentLocation()); + dialog->setInstallation(m_tree_dock->currentInstallation()); + + if (dialog->exec() == QDialog::Accepted) + { + auto ts = dialog->generatedTerminalStrip(); + m_project->undoStack()->push(new AddTerminalStripCommand(ts, m_project)); + + m_tree_dock->reload(); + m_tree_dock->setSelectedStrip(ts); + } +} + +/** + * @brief TerminalStripEditorWindow::on_m_remove_terminal_triggered + */ +void TerminalStripEditorWindow::on_m_remove_terminal_triggered() +{ + if (m_tree_dock->currentIsStrip()) + { + if (auto strip_ = m_tree_dock->currentStrip()) + { + m_project->undoStack()->push(new RemoveTerminalStripCommand(strip_, m_project)); + m_tree_dock->reload(); + } + + } +} + +/** + * @brief TerminalStripEditorWindow::on_m_reload_triggered + */ +void TerminalStripEditorWindow::on_m_reload_triggered() { + m_tree_dock->reload(); + m_terminal_strip_editor->reload(); + m_free_terminal_editor->reload(); +} + +/** + * @brief TerminalStripEditorWindow::on_m_button_box_clicked + * Action when user click on the apply/reset button + * @param button + */ +void TerminalStripEditorWindow::on_m_button_box_clicked(QAbstractButton *button) +{ + auto role_{ui->m_button_box->buttonRole(button)}; + + if (role_ == QDialogButtonBox::ApplyRole) + { + switch (ui->m_stacked_widget->currentIndex()) { + case FREE_TERMINAL_PAGE: + m_free_terminal_editor->apply(); + break; + case TERMINAL_STRIP_PAGE: + m_terminal_strip_editor->apply(); + break; + default: + break; + } + } + else if (role_ == QDialogButtonBox::ResetRole) + { + m_terminal_strip_editor->reload(); + m_free_terminal_editor->reload(); + } +} + + +void TerminalStripEditorWindow::on_m_stacked_widget_currentChanged(int arg1) { + ui->m_button_box->setHidden(arg1 == EMPTY_PAGE); +} + diff --git a/sources/TerminalStrip/ui/terminalstripeditorwindow.h b/sources/TerminalStrip/ui/terminalstripeditorwindow.h new file mode 100644 index 000000000..a31b709c0 --- /dev/null +++ b/sources/TerminalStrip/ui/terminalstripeditorwindow.h @@ -0,0 +1,63 @@ +/* + Copyright 2006-2022 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 TERMINALSTRIPEDITORWINDOW_H +#define TERMINALSTRIPEDITORWINDOW_H + +#include + +class QETProject; +class TerminalStripTreeDockWidget; +class TerminalStrip; +class FreeTerminalEditor; +class TerminalStripEditor; +class QAbstractButton; + +namespace Ui { + class TerminalStripEditorWindow; +} + +class TerminalStripEditorWindow : public QMainWindow +{ + Q_OBJECT + + public: + explicit TerminalStripEditorWindow(QETProject *project, QWidget *parent = nullptr); + ~TerminalStripEditorWindow(); + + private slots: + void on_m_add_terminal_strip_triggered(); + void on_m_remove_terminal_triggered(); + void on_m_reload_triggered(); + void on_m_button_box_clicked(QAbstractButton *button); + + void on_m_stacked_widget_currentChanged(int arg1); + + private: + void addTreeDockWidget(); + void currentStripChanged(TerminalStrip *strip); + void updateUi(); + + private: + Ui::TerminalStripEditorWindow *ui{nullptr}; + QETProject *m_project {nullptr}; + TerminalStripTreeDockWidget *m_tree_dock{nullptr}; + FreeTerminalEditor *m_free_terminal_editor {nullptr}; + TerminalStripEditor *m_terminal_strip_editor {nullptr}; +}; + +#endif // TERMINALSTRIPEDITORWINDOW_H diff --git a/sources/TerminalStrip/ui/terminalstripeditorwindow.ui b/sources/TerminalStrip/ui/terminalstripeditorwindow.ui new file mode 100644 index 000000000..43cb3eaa7 --- /dev/null +++ b/sources/TerminalStrip/ui/terminalstripeditorwindow.ui @@ -0,0 +1,96 @@ + + + TerminalStripEditorWindow + + + + 0 + 0 + 1364 + 868 + + + + Gestionnaire de borniers + + + + + + + + + + QDialogButtonBox::Apply|QDialogButtonBox::Reset + + + + + + + + + 0 + 0 + 1364 + 21 + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + + :/ico/16x16/list-add.png:/ico/16x16/list-add.png + + + Ajouter un bornier + + + Ajouter un bornier au projet + + + + + + :/ico/16x16/list-remove.png:/ico/16x16/list-remove.png + + + Supprimer le bornier + + + Supprimer le bornier du projet + + + + + + :/ico/16x16/view-refresh.png:/ico/16x16/view-refresh.png + + + Recharger + + + Recharger les borniers + + + + + + + + diff --git a/sources/TerminalStrip/ui/terminalstripmodel.cpp b/sources/TerminalStrip/ui/terminalstripmodel.cpp index 16085fd83..e582dd6d9 100644 --- a/sources/TerminalStrip/ui/terminalstripmodel.cpp +++ b/sources/TerminalStrip/ui/terminalstripmodel.cpp @@ -116,6 +116,17 @@ TerminalStripModel::TerminalStripModel(TerminalStrip *terminal_strip, QObject *p }); } +/** + * @brief TerminalStripModel::setTerminalStrip + * set the current terminal strip of this model to @a terminal_strip. + * @param terminal_strip + */ +void TerminalStripModel::setTerminalStrip(TerminalStrip *terminal_strip) +{ + m_terminal_strip = terminal_strip; + reload(); +} + int TerminalStripModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) @@ -190,10 +201,6 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const index.column() == LEVEL_3_CELL)) { return bridgePixmapFor(index); - auto pixmap_ = bridgePixmapFor(index); - if (!pixmap_.isNull()) { - return pixmap_; - } } return QVariant(); @@ -310,8 +317,7 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const /** * @brief TerminalStripModel::modifiedRealTerminalData - * @return a vector of QPair of modified terminal. - * the first value of the QPair is the original data, the second value is the edited data + * @return a vector of modified terminal. */ QVector TerminalStripModel::modifiedmodelRealTerminalData() const { @@ -484,6 +490,19 @@ void TerminalStripModel::buildBridgePixmap(const QSize &pixmap_size) } } +/** + * @brief TerminalStripModel::reload + * Reload (reset) the model + */ +void TerminalStripModel::reload() +{ + beginResetModel(); + m_physical_data.clear(); + m_modified_cell.clear(); + fillPhysicalTerminalData(); + endResetModel(); +} + void TerminalStripModel::fillPhysicalTerminalData() { //Get all physical terminal @@ -499,7 +518,7 @@ void TerminalStripModel::fillPhysicalTerminalData() { if (!real_t.isNull()) { - mptd.real_data.append(modelRealData(real_t)); + mptd.real_data.append(modelRealTerminalData::data(real_t)); } } @@ -681,21 +700,21 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const //Check if we need to draw a none bridge pixmap //Check previous - auto phy_t = m_terminal_strip->physicalTerminal(mrtd.real_terminal); + auto phy_t = mrtd.real_terminal.toStrongRef()->physicalTerminal(); auto current_real_terminal = mrtd; auto current_phy_uuid = phy_t->uuid(); bool already_jumped_to_previous = false; modelRealTerminalData previous_data; do { - current_real_terminal = modelRealData(m_terminal_strip->previousRealTerminal(current_real_terminal.real_terminal)); + current_real_terminal = modelRealTerminalData::data(m_terminal_strip->previousRealTerminal(current_real_terminal.real_terminal)); if (current_real_terminal.level_ == -1) { break; } //We are in the same physical terminal as previous loop - if (current_phy_uuid == m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid()) + if (current_phy_uuid == current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid()) { if (current_real_terminal.bridged_ && current_real_terminal.level_ == level_column) { @@ -707,7 +726,7 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const break; } else { already_jumped_to_previous = true; - current_phy_uuid = m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid(); + current_phy_uuid = current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid(); if (current_real_terminal.bridged_ && current_real_terminal.level_ == level_column) { previous_data = current_real_terminal; @@ -723,14 +742,14 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const modelRealTerminalData next_data; do { - current_real_terminal = modelRealData(m_terminal_strip->nextRealTerminal(current_real_terminal.real_terminal)); + current_real_terminal = modelRealTerminalData::data(m_terminal_strip->nextRealTerminal(current_real_terminal.real_terminal)); if (current_real_terminal.level_ == -1) { break; } //We are in the same physical terminal as previous loop - if (current_phy_uuid == m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid()) + if (current_phy_uuid == current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid()) { if (current_real_terminal.bridged_ && current_real_terminal.level_ == level_column) { @@ -742,7 +761,7 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const break; } else { already_jumped_to_next = true; - current_phy_uuid = m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid(); + current_phy_uuid = current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid(); if (current_real_terminal.bridged_ && current_real_terminal.level_ == level_column) { next_data = current_real_terminal; @@ -762,29 +781,6 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const return QPixmap(); } -modelRealTerminalData TerminalStripModel::modelRealData(const QWeakPointer &real_terminal) -{ - modelRealTerminalData mrtd; - const auto real_t = real_terminal.toStrongRef(); - if (!real_terminal.isNull()) - { - mrtd.level_ = real_t->level(); - mrtd.label_ = real_t->label(); - mrtd.Xref_ = real_t->Xref(); - mrtd.cable_ = real_t->cable(); - mrtd.cable_wire = real_t->cableWire(); - mrtd.conductor_ = real_t->conductor(); - mrtd.led_ = real_t->isLed(); - mrtd.type_ = real_t->type(); - mrtd.function_ = real_t->function(); - mrtd.element_ = real_t->element(); - mrtd.real_terminal = real_terminal; - mrtd.bridged_ = real_t->isBridged(); - } - - return mrtd; -} - /*********************************************************** * A little delegate for add a combobox to edit type * and a spinbox to edit the level of a terminal diff --git a/sources/TerminalStrip/ui/terminalstripmodel.h b/sources/TerminalStrip/ui/terminalstripmodel.h index 5e0db6865..dbe3ae720 100644 --- a/sources/TerminalStrip/ui/terminalstripmodel.h +++ b/sources/TerminalStrip/ui/terminalstripmodel.h @@ -26,7 +26,7 @@ #include #include "../terminalstrip.h" -#include "../../qetgraphicsitem/element.h" +#include "modelTerminalData.h" //Code to use QColor as key for QHash inline uint qHash(const QColor &key, uint seed) { @@ -43,37 +43,6 @@ inline uint qHash(const QPointer &key, uint seed) { class TerminalStrip; - -struct modelRealTerminalData -{ - int level_ = -1; - QString label_; - QString Xref_; - QString cable_; - QString cable_wire; - QString conductor_; - bool led_ = false; - bool bridged_ = false; - - ElementData::TerminalType type_ = ElementData::TerminalType::TTGeneric; - ElementData::TerminalFunction function_ = ElementData::TerminalFunction::TFGeneric; - QPointer element_; - - QWeakPointer real_terminal; - -}; - -struct modelPhysicalTerminalData -{ - QVector real_data; - int pos_ = -1; - QUuid uuid_; -}; - -inline bool operator == (const modelPhysicalTerminalData &data_1, const modelPhysicalTerminalData &data_2) { - return data_1.uuid_ == data_2.uuid_; -} - class TerminalStripModel : public QAbstractTableModel { public: @@ -101,6 +70,7 @@ class TerminalStripModel : public QAbstractTableModel Q_OBJECT public: TerminalStripModel(TerminalStrip *terminal_strip, QObject *parent = nullptr); + void setTerminalStrip(TerminalStrip *terminal_strip); virtual int rowCount (const QModelIndex &parent = QModelIndex()) const override; virtual int columnCount (const QModelIndex &parent = QModelIndex()) const override; @@ -116,6 +86,8 @@ class TerminalStripModel : public QAbstractTableModel void buildBridgePixmap(const QSize &pixmap_size); + void reload(); + private: void fillPhysicalTerminalData(); modelRealTerminalData dataAtRow(int row) const; @@ -124,8 +96,6 @@ class TerminalStripModel : public QAbstractTableModel modelRealTerminalData realDataAtIndex(int index) const; QPixmap bridgePixmapFor(const QModelIndex &index) const; - static modelRealTerminalData modelRealData(const QWeakPointer &real_terminal); - private: QPointer m_terminal_strip; QHash, QVector> m_modified_cell; diff --git a/sources/TerminalStrip/ui/terminalstriptreedockwidget.cpp b/sources/TerminalStrip/ui/terminalstriptreedockwidget.cpp new file mode 100644 index 000000000..4469ef6ca --- /dev/null +++ b/sources/TerminalStrip/ui/terminalstriptreedockwidget.cpp @@ -0,0 +1,385 @@ +/* + Copyright 2006-2022 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 "terminalstriptreedockwidget.h" +#include "ui_terminalstriptreedockwidget.h" + +#include "../UndoCommand/addterminaltostripcommand.h" +#include "../../elementprovider.h" +#include "../physicalterminal.h" +#include "../../qeticons.h" +#include "../../qetproject.h" +#include "../realterminal.h" +#include "../../qetgraphicsitem/terminalelement.h" +#include "../terminalstrip.h" +#include "terminalstriptreewidget.h" + +TerminalStripTreeDockWidget::TerminalStripTreeDockWidget(QETProject *project, QWidget *parent) : + QDockWidget(parent), + ui(new Ui::TerminalStripTreeDockWidget), + m_project(project) +{ + ui->setupUi(this); + buildTree(); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) + ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex()); +#else + ui->m_tree_view->expandAll(); +#endif + + setupUndoConnections(); +} + +TerminalStripTreeDockWidget::~TerminalStripTreeDockWidget() +{ + delete ui; +} + +/** + * @brief TerminalStripTreeDockWidget::reload + */ +void TerminalStripTreeDockWidget::reload() +{ + auto current_ = m_current_strip; + + ui->m_tree_view->clear(); + m_item_strip_H.clear(); + m_uuid_terminal_H.clear(); + m_uuid_strip_H.clear(); + + for (const auto &connection_ : qAsConst(m_strip_changed_connection)) { + disconnect(connection_); + } + m_strip_changed_connection.clear(); + + + buildTree(); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) + ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex()); +#else + ui->m_terminal_strip_tw->expandAll(); +#endif + + //Reselect the tree widget item of the current edited strip + auto item = m_item_strip_H.key(current_); + if (item) { + ui->m_tree_view->setCurrentItem(item); + } +} + +/** + * @brief TerminalStripTreeDockWidget::currentIsStrip + * @return true if the current selected item is a terminal strip. + */ +bool TerminalStripTreeDockWidget::currentIsStrip() const { + return m_item_strip_H.contains(ui->m_tree_view->currentItem()); +} + +/** + * @brief TerminalStripTreeDockWidget::currentStrip + * @return The current selected strip or nullptr if there is + * no strip selected; + */ +TerminalStrip *TerminalStripTreeDockWidget::currentStrip() const { + return m_current_strip; +} + +/** + * @brief TerminalStripTreeDockWidget::currentInstallation + * @return the installation according to the current selection + */ +QString TerminalStripTreeDockWidget::currentInstallation() const +{ + if (m_current_strip) { + return m_current_strip->installation(); + } + + if (auto item = ui->m_tree_view->currentItem()) + { + if (item->type() == TerminalStripTreeWidget::Location) { + item = item->parent(); + } + if (item->type() == TerminalStripTreeWidget::Installation) { + return item->data(0, Qt::DisplayRole).toString(); + } + } + + return QString(); +} + +/** + * @brief TerminalStripTreeDockWidget::currentLocation + * @return the location according to the current selection + */ +QString TerminalStripTreeDockWidget::currentLocation() const +{ + if (m_current_strip) { + return m_current_strip->location(); + } + + if (auto item = ui->m_tree_view->currentItem()) { + if (item->type() == TerminalStripTreeWidget::Location) { + return item->data(0, Qt::DisplayRole).toString(); + } + } + + return QString(); +} + +/** + * @brief TerminalStripTreeDockWidget::setSelectedStrip + * @param strip + */ +void TerminalStripTreeDockWidget::setSelectedStrip(TerminalStrip *strip) { + ui->m_tree_view->setCurrentItem(m_item_strip_H.key(strip)); +} + +/** + * @brief TerminalStripTreeDockWidget::currentRealTerminal + * @return the current real terminal or a null QSharedPointer. + */ +QSharedPointer TerminalStripTreeDockWidget::currentRealTerminal() const +{ + if (auto item = ui->m_tree_view->currentItem()) { + if (item->type() == TerminalStripTreeWidget::Terminal) { + return m_uuid_terminal_H.value(item->data(0,TerminalStripTreeWidget::UUID_USER_ROLE).toUuid()); + } + } + return QSharedPointer(); +} + +/** + * @brief TerminalStripTreeDockWidget::on_m_tree_view_currentItemChanged + * @param current + * @param previous + */ +void TerminalStripTreeDockWidget::on_m_tree_view_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + Q_UNUSED(previous) + + if (!current) { + setCurrentStrip(nullptr); + return; + } + + TerminalStrip *strip_ = nullptr; + if (current->type() == TerminalStripTreeWidget::Strip) { + strip_ = m_item_strip_H.value(current); + } + else if (current->type() == TerminalStripTreeWidget::Terminal + && current->parent() + && current->parent()->type() == TerminalStripTreeWidget::Strip) { + strip_ = m_item_strip_H.value(current->parent()); + } + + if (strip_ != m_current_strip) { + setCurrentStrip(strip_); + } +} + +/** + * @brief TerminalStripTreeDockWidget::buildTree + */ +void TerminalStripTreeDockWidget::buildTree() +{ + + auto title_ = m_project->title(); + if (title_.isEmpty()) { + title_ = tr("Projet sans titre"); + } + + QStringList strl{title_}; + new QTreeWidgetItem(ui->m_tree_view, strl, TerminalStripTreeWidget::Root); + + QStringList ftstrl(tr("Bornes indépendante")); + new QTreeWidgetItem(ui->m_tree_view, ftstrl, TerminalStripTreeWidget::FreeTerminal); + + auto ts_vector = m_project->terminalStrip(); + std::sort(ts_vector.begin(), ts_vector.end(), [](TerminalStrip *a, TerminalStrip *b) { + return a->name() < b->name(); + }); + + for (const auto &ts : qAsConst(ts_vector)) { + addTerminalStrip(ts); + } + addFreeTerminal(); +} + +QTreeWidgetItem* TerminalStripTreeDockWidget::addTerminalStrip(TerminalStrip *terminal_strip) +{ + if (auto item = m_item_strip_H.key(terminal_strip)) { + return item; + } + + auto root_item = ui->m_tree_view->topLevelItem(0); + + //Check if installation already exist + //if not create a new one + auto installation_str = terminal_strip->installation(); + QTreeWidgetItem *inst_qtwi = nullptr; + for (int i = 0 ; ichildCount() ; ++i) { + auto child_inst = root_item->child(i); + if (child_inst->data(0, Qt::DisplayRole).toString() == installation_str) { + inst_qtwi = child_inst; + break; + } + } + if (!inst_qtwi) { + QStringList inst_strl{installation_str}; + inst_qtwi = new QTreeWidgetItem(root_item, inst_strl, TerminalStripTreeWidget::Installation); + } + + //Check if location already exist + //if not create a new one + auto location_str = terminal_strip->location(); + QTreeWidgetItem *loc_qtwi = nullptr; + for (int i = 0 ; ichildCount() ; ++i) { + auto child_loc = inst_qtwi->child(i); + if (child_loc->data(0, Qt::DisplayRole).toString() == location_str) { + loc_qtwi = child_loc; + break; + } + } + if (!loc_qtwi) { + QStringList loc_strl{location_str}; + loc_qtwi = new QTreeWidgetItem(inst_qtwi, loc_strl, TerminalStripTreeWidget::Location); + } + + //Add the terminal strip + QStringList name{terminal_strip->name()}; + auto strip_item = new QTreeWidgetItem(loc_qtwi, name, TerminalStripTreeWidget::Strip); + strip_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, terminal_strip->uuid()); + strip_item->setIcon(0, QET::Icons::TerminalStrip); + + //Add child terminal of the strip + for (auto i=0 ; iphysicalTerminalCount() ; ++i) + { + auto phy_t = terminal_strip->physicalTerminal(i); + if (phy_t->realTerminalCount()) + { + QString text_; + for (const auto &real_t : phy_t->realTerminals()) + { + if (text_.isEmpty()) + text_ = real_t->label(); + else + text_.append(QStringLiteral(", ")).append(real_t->label()); + } + const auto real_t = phy_t->realTerminals().at(0); + auto terminal_item = new QTreeWidgetItem(strip_item, QStringList(text_), TerminalStripTreeWidget::Terminal); + terminal_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, phy_t->uuid()); + terminal_item->setIcon(0, QET::Icons::ElementTerminal); + } + } + + m_item_strip_H.insert(strip_item, terminal_strip); + m_uuid_strip_H.insert(terminal_strip->uuid(), terminal_strip); + + m_strip_changed_connection.append(connect(terminal_strip, &TerminalStrip::orderChanged, this, &TerminalStripTreeDockWidget::reload)); + return strip_item; +} + +/** + * @brief TerminalStripTreeDockWidget::addFreeTerminal + */ +void TerminalStripTreeDockWidget::addFreeTerminal() +{ + ElementProvider ep(m_project); + auto vector_ = ep.freeTerminal(); + + if (vector_.isEmpty()) { + return; + } + + //Sort the terminal element by label + std::sort(vector_.begin(), vector_.end(), [](TerminalElement *a, TerminalElement *b) { + return a->actualLabel() < b->actualLabel(); + }); + + auto free_terminal_item = ui->m_tree_view->topLevelItem(1); + + for (const auto terminal : qAsConst(vector_)) + { + QUuid uuid_ = terminal->uuid(); + QStringList strl{terminal->actualLabel()}; + auto item = new QTreeWidgetItem(free_terminal_item, strl, TerminalStripTreeWidget::Terminal); + item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, uuid_.toString()); + item->setIcon(0, QET::Icons::ElementTerminal); + + m_uuid_terminal_H.insert(uuid_, terminal->realTerminal()); + } +} + +void TerminalStripTreeDockWidget::setupUndoConnections() +{ + connect(ui->m_tree_view, &TerminalStripTreeWidget::terminalAddedToStrip, this, + [=](QUuid terminal_uuid, QUuid strip_uuid) + { + auto terminal = m_uuid_terminal_H.value(terminal_uuid); + auto strip = m_uuid_strip_H.value(strip_uuid); + + if (!terminal || !strip) { + return; + } + + auto undo = new AddTerminalToStripCommand(terminal, strip); + m_project->undoStack()->push(undo); + }); + + connect(ui->m_tree_view, &TerminalStripTreeWidget::terminalMovedFromStripToStrip, this, + [=] (QUuid terminal_uuid, QUuid old_strip_uuid, QUuid new_strip_uuid) + { + auto old_strip = m_uuid_strip_H.value(old_strip_uuid); + auto new_strip = m_uuid_strip_H.value(new_strip_uuid); + + if (!old_strip || !new_strip) { + return; + } + auto terminal = old_strip->physicalTerminal(terminal_uuid); + if (!terminal) { + return; + } + + auto undo = new MoveTerminalCommand(terminal, old_strip, new_strip); + m_project->undoStack()->push(undo); + }); + + connect(ui->m_tree_view, &TerminalStripTreeWidget::terminalRemovedFromStrip, this, + [=] (QUuid terminal_uuid, QUuid old_strip_uuid) + { + auto strip_ = m_uuid_strip_H.value(old_strip_uuid); + if (!strip_) { + return; + } + + auto terminal_ = strip_->physicalTerminal(terminal_uuid); + if (!terminal_) { + return; + } + + auto undo = new RemoveTerminalFromStripCommand(terminal_, strip_); + m_project->undoStack()->push(undo); + }); +} + +void TerminalStripTreeDockWidget::setCurrentStrip(TerminalStrip *strip) +{ + m_current_strip = strip; + emit currentStripChanged(strip); +} diff --git a/sources/TerminalStrip/ui/terminalstriptreedockwidget.h b/sources/TerminalStrip/ui/terminalstriptreedockwidget.h new file mode 100644 index 000000000..e1dfd08f6 --- /dev/null +++ b/sources/TerminalStrip/ui/terminalstriptreedockwidget.h @@ -0,0 +1,73 @@ +/* + Copyright 2006-2022 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 TERMINALSTRIPTREEDOCKWIDGET_H +#define TERMINALSTRIPTREEDOCKWIDGET_H + +#include +#include + +class QETProject; +class QTreeWidgetItem; +class TerminalStrip; +class RealTerminal; + +namespace Ui { + class TerminalStripTreeDockWidget; +} + +class TerminalStripTreeDockWidget : public QDockWidget +{ + Q_OBJECT + + public: + explicit TerminalStripTreeDockWidget(QETProject *project, QWidget *parent = nullptr); + ~TerminalStripTreeDockWidget(); + + void reload(); + bool currentIsStrip() const; + TerminalStrip* currentStrip() const; + QString currentInstallation() const; + QString currentLocation() const; + void setSelectedStrip(TerminalStrip *strip); + QSharedPointer currentRealTerminal() const; + + signals: + void currentStripChanged(TerminalStrip *strip); + + private slots: + void on_m_tree_view_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + + private: + void buildTree(); + QTreeWidgetItem* addTerminalStrip(TerminalStrip *terminal_strip); + void addFreeTerminal(); + void setupUndoConnections(); + void setCurrentStrip(TerminalStrip *strip); + + private: + Ui::TerminalStripTreeDockWidget *ui; + QPointer m_project; + QPointer m_current_strip; + + QHash m_item_strip_H; + QHash> m_uuid_terminal_H; + QHash> m_uuid_strip_H; + QVector m_strip_changed_connection; +}; + +#endif // TERMINALSTRIPTREEDOCKWIDGET_H diff --git a/sources/TerminalStrip/ui/terminalstriptreedockwidget.ui b/sources/TerminalStrip/ui/terminalstriptreedockwidget.ui new file mode 100644 index 000000000..f04b5df29 --- /dev/null +++ b/sources/TerminalStrip/ui/terminalstriptreedockwidget.ui @@ -0,0 +1,48 @@ + + + TerminalStripTreeDockWidget + + + + 0 + 0 + 397 + 542 + + + + Explorateur de bornier + + + + + + + QAbstractItemView::InternalMove + + + true + + + false + + + + 1 + + + + + + + + + + TerminalStripTreeWidget + QTreeWidget +
terminalstriptreewidget.h
+
+
+ + +
diff --git a/sources/TerminalStrip/ui/terminalstriptreewidget.cpp b/sources/TerminalStrip/ui/terminalstriptreewidget.cpp index 1ca25917b..17a184549 100644 --- a/sources/TerminalStrip/ui/terminalstriptreewidget.cpp +++ b/sources/TerminalStrip/ui/terminalstriptreewidget.cpp @@ -23,8 +23,6 @@ #include #include -int TerminalStripTreeWidget::UUID_USER_ROLE = Qt::UserRole + 1; - TerminalStripTreeWidget::TerminalStripTreeWidget(QWidget *parent) : QTreeWidget(parent) {} diff --git a/sources/TerminalStrip/ui/terminalstriptreewidget.h b/sources/TerminalStrip/ui/terminalstriptreewidget.h index fc1218bc7..d5b7fac1e 100644 --- a/sources/TerminalStrip/ui/terminalstriptreewidget.h +++ b/sources/TerminalStrip/ui/terminalstriptreewidget.h @@ -39,7 +39,7 @@ class TerminalStripTreeWidget : public QTreeWidget }; //Role used for data in QTreeWidgetItem - static int UUID_USER_ROLE; + static constexpr int UUID_USER_ROLE{Qt::UserRole + 1}; signals: /** diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 64f8ebe4b..08ddcac02 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -42,7 +42,7 @@ #include "undocommand/rotateselectioncommand.h" #include "undocommand/rotatetextscommand.h" #include "diagram.h" -#include "TerminalStrip/ui/terminalstripeditor.h" +#include "TerminalStrip/ui/terminalstripeditorwindow.h" #include "ui/diagrameditorhandlersizewidget.h" #ifdef BUILD_WITHOUT_KF5 @@ -427,7 +427,7 @@ void QETDiagramEditor::setUpActions() //Add a nomenclature item m_add_nomenclature = new QAction(QET::Icons::TableOfContent, tr("Ajouter une nomenclature"), this); - connect(m_add_nomenclature, &QAction::triggered, [this]() { + connect(m_add_nomenclature, &QAction::triggered, this, [=]() { if(this->currentDiagramView()) { QetGraphicsTableFactory::createAndAddNomenclature(this->currentDiagramView()->diagram()); } @@ -435,19 +435,19 @@ void QETDiagramEditor::setUpActions() //Add a summary item m_add_summary = new QAction(QET::Icons::TableOfContent, tr("Ajouter un sommaire"), this); - connect(m_add_summary, &QAction::triggered, [this]() { + connect(m_add_summary, &QAction::triggered, this, [=]() { if(this->currentDiagramView()) { QetGraphicsTableFactory::createAndAddSummary(this->currentDiagramView()->diagram()); } }); m_terminal_strip_dialog = new QAction(QET::Icons::TerminalStrip, tr("Gestionnaire de borniers (DEV)"), this); - connect(m_terminal_strip_dialog, &QAction::triggered, [this]() + connect(m_terminal_strip_dialog, &QAction::triggered, this, [=]() { if (auto project = this->currentProject()) { - auto str = new TerminalStripEditor(project, this); - str->show(); + auto tsew {new TerminalStripEditorWindow{project, this}}; + tsew->show(); } }); diff --git a/sources/qetgraphicsitem/terminalelement.cpp b/sources/qetgraphicsitem/terminalelement.cpp index 8791382ab..21208ffdc 100644 --- a/sources/qetgraphicsitem/terminalelement.cpp +++ b/sources/qetgraphicsitem/terminalelement.cpp @@ -16,6 +16,7 @@ along with QElectroTech. If not, see . */ #include "terminalelement.h" +#include"../TerminalStrip/realterminal.h" /** @brief TerminalElement::TerminalElement @@ -27,7 +28,10 @@ TerminalElement::TerminalElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) : Element(location, qgi, state, Element::Terminale) -{} +{ + auto rt = new RealTerminal(this); + m_real_terminal = rt->sharedRef(); +} TerminalElement::~TerminalElement() {} @@ -41,17 +45,11 @@ void TerminalElement::initLink(QETProject *project) { } /** - * @brief TerminalElement::setParentTerminalStrip - * Set \p strip as parent terminal strip. - * Be carefull, this function only set internally the parent terminal strip. - * This function don't check if there is a previous - * parent terminal strip and don't check - * if the new terminal strip have this terminal element - * in her list of terminal element. - * @param strip + * @brief TerminalElement::realTerminal + * @return the real terminal of this terminal element. */ -void TerminalElement::setParentTerminalStrip(TerminalStrip *strip) { - m_parent_terminal_strip = strip; +QSharedPointer TerminalElement::realTerminal() const { + return m_real_terminal; } /** @@ -60,6 +58,9 @@ void TerminalElement::setParentTerminalStrip(TerminalStrip *strip) { * terminal element or nullptr if not. */ TerminalStrip *TerminalElement::parentTerminalStrip() const { - return m_parent_terminal_strip.data(); + if (m_real_terminal) { + return m_real_terminal->parentStrip(); + } + return nullptr; } diff --git a/sources/qetgraphicsitem/terminalelement.h b/sources/qetgraphicsitem/terminalelement.h index 3fa5163d3..c2319d8f5 100644 --- a/sources/qetgraphicsitem/terminalelement.h +++ b/sources/qetgraphicsitem/terminalelement.h @@ -23,6 +23,7 @@ #include "../TerminalStrip/terminalstrip.h" class QETProject; +class RealTerminal; /** @brief The TerminalElement class */ @@ -35,11 +36,12 @@ class TerminalElement : public Element ~TerminalElement() override; void initLink(QETProject *project) override; + QSharedPointer realTerminal() const; void setParentTerminalStrip(TerminalStrip *strip); TerminalStrip *parentTerminalStrip() const; private: - QPointer m_parent_terminal_strip; + QSharedPointer m_real_terminal; }; #endif // TERMINALELEMENT_H diff --git a/sources/utils/qetutils.cpp b/sources/utils/qetutils.cpp index 7bb3c92b6..769b0766e 100644 --- a/sources/utils/qetutils.cpp +++ b/sources/utils/qetutils.cpp @@ -87,3 +87,48 @@ qreal QETUtils::graphicsHandlerSize(QGraphicsItem *item) //Default value return 10; } + +/** + * @brief QETUtils::sortBeginIntString + * Sort the string @a str_a and @a str_b and take in + * count if string begin with an int to sort it + * as int and not as string in this case. + * For exemple if we have to sort the string : + * "3str", 10str", "100str", "2str", "20str". + * The default behavior when sorting QString with the comparaison operator will be: + * "10str" "100str" "2str", "20str", "3str" + * When sorting with this function, the result will be : + * "10str", "2str", "3str", "20str", "100str" + * @param str_a + * @param str_b + * @return + */ +bool QETUtils::sortBeginIntString(const QString &str_a, const QString &str_b) +{ + const QRegularExpression rx(QStringLiteral("^\\d+")); + int int_a =-1; + int int_b =-1; + + auto match_a = rx.match(str_a); + if (match_a.hasMatch()) { + int_a = match_a.captured(0).toInt(); + } + + auto match_b = rx.match(str_b); + if (match_b.hasMatch()) { + int_b = match_b.captured(0).toInt(); + } + + //Sort as numbers if both string + //start at least by a digit and + //the number of each string are different. + //Else sort as string + if (int_a >= 0 && + int_b >= 0 && + int_a != int_b) { + return int_a QVector> sharedVectorToWeak(const QVector> &vector) {