From 089f260d9bb66537045264b24d5fd794d411accc Mon Sep 17 00:00:00 2001 From: joshua Date: Sat, 9 Oct 2021 11:58:10 +0200 Subject: [PATCH] Group terminals together is now managed by undo stack --- .../UndoCommand/groupterminalscommand.cpp | 48 +++++++ .../UndoCommand/groupterminalscommand.h | 48 +++++++ sources/TerminalStrip/terminalstrip.cpp | 128 +++++++++++++++--- sources/TerminalStrip/terminalstrip.h | 12 +- .../TerminalStrip/ui/terminalstripeditor.cpp | 15 +- .../TerminalStrip/ui/terminalstripeditor.h | 1 - 6 files changed, 222 insertions(+), 30 deletions(-) create mode 100644 sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp create mode 100644 sources/TerminalStrip/UndoCommand/groupterminalscommand.h diff --git a/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp b/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp new file mode 100644 index 000000000..1794af02a --- /dev/null +++ b/sources/TerminalStrip/UndoCommand/groupterminalscommand.cpp @@ -0,0 +1,48 @@ +/* + Copyright 2006-2021 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "groupterminalscommand.h" + +/** + * @brief GroupTerminalsCommand::GroupTerminalsCommand + * @param strip : The parent strip of terminal to group + * @param receiver : The terminal where other terminals will be grouped + * @param to_group : Terminals to group + */ +GroupTerminalsCommand::GroupTerminalsCommand(TerminalStrip *strip, + const PhysicalTerminalData &receiver_, + const QVector &to_group, + QUndoCommand *parent): + QUndoCommand(parent), + m_terminal_strip(strip), + m_receiver(receiver_), + m_to_group(to_group) +{ + setText("Grouper un ensemble de bornes"); +} + +void GroupTerminalsCommand::undo() { + if (m_terminal_strip) { + m_terminal_strip->unGroupTerminals(m_to_group); + } +} + +void GroupTerminalsCommand::redo() { + if (m_terminal_strip) { + m_terminal_strip->groupTerminals(m_receiver, m_to_group); + } +} diff --git a/sources/TerminalStrip/UndoCommand/groupterminalscommand.h b/sources/TerminalStrip/UndoCommand/groupterminalscommand.h new file mode 100644 index 000000000..d6a14e9ac --- /dev/null +++ b/sources/TerminalStrip/UndoCommand/groupterminalscommand.h @@ -0,0 +1,48 @@ +/* + 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 GROUPTERMINALSCOMMAND_H +#define GROUPTERMINALSCOMMAND_H + +#include +#include +#include +#include "../terminalstrip.h" + +/** + * @brief The GroupTerminalsCommand class + * Class used to group (make level terminal) together + */ +class GroupTerminalsCommand : public QUndoCommand +{ + public: + GroupTerminalsCommand(TerminalStrip *strip, + const PhysicalTerminalData &receiver_, + const QVector &to_group, + QUndoCommand *parent = nullptr); + + void undo() override; + void redo() override; + + private: + QPointer m_terminal_strip; + PhysicalTerminalData m_receiver; + QVector m_to_group; + QVector m_to_ungroup; +}; + +#endif // GROUPTERMINALSCOMMAND_H diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp index 28d6a14c9..64a9af193 100644 --- a/sources/TerminalStrip/terminalstrip.cpp +++ b/sources/TerminalStrip/terminalstrip.cpp @@ -297,6 +297,14 @@ class PhysicalTerminal return m_real_terminal; } + /** + * @brief uuid + * @return the uuid of this physical terminal + */ + QUuid uuid() const { + return m_uuid; + } + static QString xmlTagName() { return QStringLiteral("physical_terminal"); } @@ -319,6 +327,7 @@ class PhysicalTerminal private: QPointer m_parent_terminal_strip; QVector m_real_terminal; + const QUuid m_uuid = QUuid::createUuid(); }; @@ -506,11 +515,43 @@ PhysicalTerminalData TerminalStrip::physicalTerminalData(int index) const auto rtd = realTerminalData(real_terminal); ptd.real_terminals_vector.append(rtd); } + ptd.uuid_ = physical_terminal->uuid(); } return ptd; } +/** + * @brief TerminalStrip::physicalTerminalData + * @param real_data + * @return the parent PhysicalTerminalData of \p real_data. + * the PhysicalTerminalData can be invalid if \p real_data don't belong to this strip + */ +PhysicalTerminalData TerminalStrip::physicalTerminalData(const RealTerminalData &real_data) const +{ + PhysicalTerminalData ptd_; + + const auto real_t = realTerminalForUuid(real_data.real_terminal_uuid); + if (real_t.isNull()) { + return ptd_; + } + + const auto phy_t = physicalTerminal(real_t); + if (phy_t.isNull()) { + return ptd_; + } + + ptd_.physical_terminal = phy_t; + ptd_.pos_ = m_physical_terminals.indexOf(phy_t); + for (auto real_terminal : phy_t->terminals()) { + auto rtd = realTerminalData(real_terminal); + ptd_.real_terminals_vector.append(rtd); + } + ptd_.uuid_ = phy_t->uuid(); + + return ptd_; +} + /** * @brief TerminalStrip::physicalTerminalData * @return A vector of all physical terminal data owned by this terminal strip. @@ -564,48 +605,55 @@ bool TerminalStrip::setOrderTo(QVector sorted_vector) /** * @brief TerminalStrip::groupTerminal * Add \p added_terminal to \p receiver_terminal. - * At the end of this method, the physical terminal represented by \p added_terminal is removed + * At the end of this method, if there is physical terminal + * without any real terminal, they will be removed * and \p receiver_terminal become a multi-level terminal. * Emit the signal orderChanged(); * @param added_terminal * @param receiver_terminal * @return true if success */ -bool TerminalStrip::groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector &added_terminals) +bool TerminalStrip::groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector &added_terminals) { - if (!m_physical_terminals.contains(receiver_terminal.physical_terminal)) { + const auto receiver_ = physicalTerminalForUuid(receiver_terminal.uuid_); + if (receiver_.isNull()) { qDebug() << "TerminalStrip::groupTerminal : Arguments terminals don't belong to this strip. Operation aborted."; return false; } - auto physical_receiver_terminal = receiver_terminal.physical_terminal; - - for (const auto &ptd : qAsConst(added_terminals)) + bool have_grouped = false; + for (const auto &added : added_terminals) { - if (!m_physical_terminals.contains(ptd.physical_terminal)) { + const auto added_terminal = realTerminalForUuid(added.real_terminal_uuid); + + if (added_terminal.isNull()) { continue; } - //Add every real terminal of ptd to receiver terminal - for (auto const &rtd_ : qAsConst(ptd.real_terminals_vector)) - { - if (auto rt = realTerminal(rtd_.element_)) { - physical_receiver_terminal->addTerminal(rt); + auto physical_ = physicalTerminal(added_terminal); + physical_->removeTerminal(added_terminal); + + receiver_->addTerminal(added_terminal); + have_grouped = true; + } + + if (have_grouped) + { + const auto vector_ = m_physical_terminals; + for (const auto &phys : vector_) { + if (phys->terminals().isEmpty()) { + m_physical_terminals.removeOne(phys); } } - //Remove ptd - m_physical_terminals.removeOne(ptd.physical_terminal); + emit orderChanged(); } - - emit orderChanged(); return true; } /** * @brief TerminalStrip::unGroupTerminals * Ungroup all real terminals of \p terminals_to_ungroup - * from this terminal strip * @param terminals_to_ungroup */ void TerminalStrip::unGroupTerminals(const QVector &terminals_to_ungroup) @@ -613,7 +661,7 @@ void TerminalStrip::unGroupTerminals(const QVector &terminals_ bool ungrouped = false; for (const auto &rtd_ : terminals_to_ungroup) { - if (auto real_terminal = realTerminal(rtd_.element_)) //Get the shared real terminal + if (auto real_terminal = realTerminalForUuid(rtd_.real_terminal_uuid)) //Get the shared real terminal { if (auto physical_terminal = physicalTerminal(real_terminal)) //Get the physical terminal { @@ -773,12 +821,13 @@ RealTerminalData TerminalStrip::realTerminalData(QSharedPointer re auto physical_terminal = physicalTerminal(real_terminal); + rtd.real_terminal_uuid = real_terminal->uuid(); rtd.level_ = physical_terminal->levelOf(real_terminal); rtd.label_ = real_terminal->label(); if (real_terminal->isElement()) { rtd.Xref_ = autonum::AssignVariables::genericXref(real_terminal->element()); - rtd.uuid_ = real_terminal->elementUuid(); + rtd.element_uuid = real_terminal->elementUuid(); rtd.element_ = real_terminal->element(); } rtd.type_ = real_terminal->type(); @@ -788,3 +837,44 @@ RealTerminalData TerminalStrip::realTerminalData(QSharedPointer re return rtd; } + +/** + * @brief TerminalStrip::physicalTerminalForUuid + * Return the PhysicalTerminal with uuid \p uuid or a null + * PhysicalTerminal if uuid don't match + * @param uuid + * @return + */ +QSharedPointer TerminalStrip::physicalTerminalForUuid(const QUuid &uuid) const +{ + shared_physical_terminal return_pt; + + for (const auto &pt_ : qAsConst(m_physical_terminals)) { + if (pt_->uuid() == uuid) { + return_pt = pt_; + break; + } + } + + return return_pt; +} + +/** + * @brief TerminalStrip::realTerminalForUuid + * @param uuid + * @return the RealTerminal with uuid \p uuid or a null + * RealTerminal if uuid don't match + */ +QSharedPointer TerminalStrip::realTerminalForUuid(const QUuid &uuid) const +{ + shared_real_terminal return_rt; + + for (const auto &rt_ : qAsConst(m_real_terminals)) { + if (rt_->uuid() == uuid) { + return_rt = rt_; + break; + } + } + + return return_rt; +} diff --git a/sources/TerminalStrip/terminalstrip.h b/sources/TerminalStrip/terminalstrip.h index f72c95295..3373a9c4f 100644 --- a/sources/TerminalStrip/terminalstrip.h +++ b/sources/TerminalStrip/terminalstrip.h @@ -42,7 +42,8 @@ struct RealTerminalData cable_wire_, conductor_; - QUuid uuid_; + QUuid element_uuid, + real_terminal_uuid; ElementData::TerminalType type_; ElementData::TerminalFunction function_; @@ -58,6 +59,7 @@ struct PhysicalTerminalData QVector real_terminals_vector; int pos_ = -1; QSharedPointer physical_terminal; + QUuid uuid_; }; /** @@ -71,7 +73,8 @@ class TerminalStrip : public QObject { friend class TerminalStripModel; - Q_OBJECT + Q_OBJECT + public: signals: void orderChanged(); //Emitted when the order of the physical terminal is changed @@ -105,9 +108,10 @@ class TerminalStrip : public QObject int physicalTerminalCount() const; PhysicalTerminalData physicalTerminalData(int index) const; + PhysicalTerminalData physicalTerminalData (const RealTerminalData &real_data) const; QVector physicalTerminalData() const; bool setOrderTo(QVector sorted_vector); - bool groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector &added_terminals); + bool groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector &added_terminals); void unGroupTerminals(const QVector &terminals_to_ungroup); QVector> terminalElement() const; @@ -122,6 +126,8 @@ class TerminalStrip : public QObject QSharedPointer realTerminal(Element *terminal); QSharedPointer physicalTerminal(QSharedPointer terminal) const; RealTerminalData realTerminalData(QSharedPointer real_terminal) const; + QSharedPointer physicalTerminalForUuid (const QUuid &uuid) const; + QSharedPointer realTerminalForUuid(const QUuid &uuid) const; private: TerminalStripData m_data; diff --git a/sources/TerminalStrip/ui/terminalstripeditor.cpp b/sources/TerminalStrip/ui/terminalstripeditor.cpp index 2383a3f1e..e674befb7 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.cpp +++ b/sources/TerminalStrip/ui/terminalstripeditor.cpp @@ -31,6 +31,7 @@ #include "terminalstripmodel.h" #include "../diagram.h" #include "../UndoCommand/sortterminalstripcommand.h" +#include "../UndoCommand/groupterminalscommand.h" #include @@ -219,11 +220,11 @@ QTreeWidgetItem* TerminalStripEditor::addTerminalStrip(TerminalStrip *terminal_s { auto real_t = ptd.real_terminals_vector.first(); auto terminal_item = new QTreeWidgetItem(strip_item, QStringList(real_t.label_), TerminalStripTreeWidget::Terminal); - terminal_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, real_t.uuid_.toString()); + terminal_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, real_t.element_uuid.toString()); terminal_item->setIcon(0, QET::Icons::ElementTerminal); if (real_t.element_) { - m_uuid_terminal_H.insert(real_t.uuid_, qgraphicsitem_cast(real_t.element_)); + m_uuid_terminal_H.insert(real_t.element_uuid, qgraphicsitem_cast(real_t.element_)); } } } @@ -536,13 +537,13 @@ void TerminalStripEditor::on_m_auto_ordering_pb_clicked() */ void TerminalStripEditor::on_m_group_terminals_pb_clicked() { - if (m_model && m_current_strip) + if (m_model && m_current_strip && m_project) { - auto ptd_vector = m_model->physicalTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes()); - if (ptd_vector.size() >= 2) + auto rtd_vector = m_model->realTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes()); + if (rtd_vector.size() >= 2) { - auto receiver_ = ptd_vector.takeFirst(); - m_current_strip->groupTerminals(receiver_, ptd_vector); + auto receiver_ = m_current_strip->physicalTerminalData(rtd_vector.takeFirst()); + m_project->undoStack()->push(new GroupTerminalsCommand(m_current_strip, receiver_, rtd_vector)); } } } diff --git a/sources/TerminalStrip/ui/terminalstripeditor.h b/sources/TerminalStrip/ui/terminalstripeditor.h index d7f9cd91f..cde20120b 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.h +++ b/sources/TerminalStrip/ui/terminalstripeditor.h @@ -61,7 +61,6 @@ class TerminalStripEditor : public QDialog 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(); private: