Group terminals together is now managed by undo stack

This commit is contained in:
joshua
2021-10-09 11:58:10 +02:00
parent 828424cae8
commit 089f260d9b
6 changed files with 222 additions and 30 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<RealTerminalData> &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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef GROUPTERMINALSCOMMAND_H
#define GROUPTERMINALSCOMMAND_H
#include <QUndoCommand>
#include <QPointer>
#include <QVector>
#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<RealTerminalData> &to_group,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
private:
QPointer<TerminalStrip> m_terminal_strip;
PhysicalTerminalData m_receiver;
QVector <RealTerminalData> m_to_group;
QVector <RealTerminalData> m_to_ungroup;
};
#endif // GROUPTERMINALSCOMMAND_H

View File

@@ -297,6 +297,14 @@ class PhysicalTerminal
return m_real_terminal; return m_real_terminal;
} }
/**
* @brief uuid
* @return the uuid of this physical terminal
*/
QUuid uuid() const {
return m_uuid;
}
static QString xmlTagName() { static QString xmlTagName() {
return QStringLiteral("physical_terminal"); return QStringLiteral("physical_terminal");
} }
@@ -319,6 +327,7 @@ class PhysicalTerminal
private: private:
QPointer<TerminalStrip> m_parent_terminal_strip; QPointer<TerminalStrip> m_parent_terminal_strip;
QVector<shared_real_terminal> m_real_terminal; QVector<shared_real_terminal> m_real_terminal;
const QUuid m_uuid = QUuid::createUuid();
}; };
@@ -506,11 +515,43 @@ PhysicalTerminalData TerminalStrip::physicalTerminalData(int index) const
auto rtd = realTerminalData(real_terminal); auto rtd = realTerminalData(real_terminal);
ptd.real_terminals_vector.append(rtd); ptd.real_terminals_vector.append(rtd);
} }
ptd.uuid_ = physical_terminal->uuid();
} }
return ptd; 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 * @brief TerminalStrip::physicalTerminalData
* @return A vector of all physical terminal data owned by this terminal strip. * @return A vector of all physical terminal data owned by this terminal strip.
@@ -564,48 +605,55 @@ bool TerminalStrip::setOrderTo(QVector<PhysicalTerminalData> sorted_vector)
/** /**
* @brief TerminalStrip::groupTerminal * @brief TerminalStrip::groupTerminal
* Add \p added_terminal to \p receiver_terminal. * 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. * and \p receiver_terminal become a multi-level terminal.
* Emit the signal orderChanged(); * Emit the signal orderChanged();
* @param added_terminal * @param added_terminal
* @param receiver_terminal * @param receiver_terminal
* @return true if success * @return true if success
*/ */
bool TerminalStrip::groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector<PhysicalTerminalData> &added_terminals) bool TerminalStrip::groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector<RealTerminalData> &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."; qDebug() << "TerminalStrip::groupTerminal : Arguments terminals don't belong to this strip. Operation aborted.";
return false; return false;
} }
auto physical_receiver_terminal = receiver_terminal.physical_terminal; bool have_grouped = false;
for (const auto &added : added_terminals)
for (const auto &ptd : qAsConst(added_terminals))
{ {
if (!m_physical_terminals.contains(ptd.physical_terminal)) { const auto added_terminal = realTerminalForUuid(added.real_terminal_uuid);
if (added_terminal.isNull()) {
continue; continue;
} }
//Add every real terminal of ptd to receiver terminal auto physical_ = physicalTerminal(added_terminal);
for (auto const &rtd_ : qAsConst(ptd.real_terminals_vector)) physical_->removeTerminal(added_terminal);
{
if (auto rt = realTerminal(rtd_.element_)) { receiver_->addTerminal(added_terminal);
physical_receiver_terminal->addTerminal(rt); 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 emit orderChanged();
m_physical_terminals.removeOne(ptd.physical_terminal);
} }
emit orderChanged();
return true; return true;
} }
/** /**
* @brief TerminalStrip::unGroupTerminals * @brief TerminalStrip::unGroupTerminals
* Ungroup all real terminals of \p terminals_to_ungroup * Ungroup all real terminals of \p terminals_to_ungroup
* from this terminal strip
* @param terminals_to_ungroup * @param terminals_to_ungroup
*/ */
void TerminalStrip::unGroupTerminals(const QVector<RealTerminalData> &terminals_to_ungroup) void TerminalStrip::unGroupTerminals(const QVector<RealTerminalData> &terminals_to_ungroup)
@@ -613,7 +661,7 @@ void TerminalStrip::unGroupTerminals(const QVector<RealTerminalData> &terminals_
bool ungrouped = false; bool ungrouped = false;
for (const auto &rtd_ : terminals_to_ungroup) 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 if (auto physical_terminal = physicalTerminal(real_terminal)) //Get the physical terminal
{ {
@@ -773,12 +821,13 @@ RealTerminalData TerminalStrip::realTerminalData(QSharedPointer<RealTerminal> re
auto physical_terminal = physicalTerminal(real_terminal); auto physical_terminal = physicalTerminal(real_terminal);
rtd.real_terminal_uuid = real_terminal->uuid();
rtd.level_ = physical_terminal->levelOf(real_terminal); rtd.level_ = physical_terminal->levelOf(real_terminal);
rtd.label_ = real_terminal->label(); rtd.label_ = real_terminal->label();
if (real_terminal->isElement()) { if (real_terminal->isElement()) {
rtd.Xref_ = autonum::AssignVariables::genericXref(real_terminal->element()); 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.element_ = real_terminal->element();
} }
rtd.type_ = real_terminal->type(); rtd.type_ = real_terminal->type();
@@ -788,3 +837,44 @@ RealTerminalData TerminalStrip::realTerminalData(QSharedPointer<RealTerminal> re
return rtd; 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<PhysicalTerminal> 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<RealTerminal> 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;
}

View File

@@ -42,7 +42,8 @@ struct RealTerminalData
cable_wire_, cable_wire_,
conductor_; conductor_;
QUuid uuid_; QUuid element_uuid,
real_terminal_uuid;
ElementData::TerminalType type_; ElementData::TerminalType type_;
ElementData::TerminalFunction function_; ElementData::TerminalFunction function_;
@@ -58,6 +59,7 @@ struct PhysicalTerminalData
QVector<RealTerminalData> real_terminals_vector; QVector<RealTerminalData> real_terminals_vector;
int pos_ = -1; int pos_ = -1;
QSharedPointer<PhysicalTerminal> physical_terminal; QSharedPointer<PhysicalTerminal> physical_terminal;
QUuid uuid_;
}; };
/** /**
@@ -71,7 +73,8 @@ class TerminalStrip : public QObject
{ {
friend class TerminalStripModel; friend class TerminalStripModel;
Q_OBJECT Q_OBJECT
public: public:
signals: signals:
void orderChanged(); //Emitted when the order of the physical terminal is changed void orderChanged(); //Emitted when the order of the physical terminal is changed
@@ -105,9 +108,10 @@ class TerminalStrip : public QObject
int physicalTerminalCount() const; int physicalTerminalCount() const;
PhysicalTerminalData physicalTerminalData(int index) const; PhysicalTerminalData physicalTerminalData(int index) const;
PhysicalTerminalData physicalTerminalData (const RealTerminalData &real_data) const;
QVector<PhysicalTerminalData> physicalTerminalData() const; QVector<PhysicalTerminalData> physicalTerminalData() const;
bool setOrderTo(QVector<PhysicalTerminalData> sorted_vector); bool setOrderTo(QVector<PhysicalTerminalData> sorted_vector);
bool groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector<PhysicalTerminalData> &added_terminals); bool groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector<RealTerminalData> &added_terminals);
void unGroupTerminals(const QVector<RealTerminalData> &terminals_to_ungroup); void unGroupTerminals(const QVector<RealTerminalData> &terminals_to_ungroup);
QVector<QPointer<Element>> terminalElement() const; QVector<QPointer<Element>> terminalElement() const;
@@ -122,6 +126,8 @@ class TerminalStrip : public QObject
QSharedPointer<RealTerminal> realTerminal(Element *terminal); QSharedPointer<RealTerminal> realTerminal(Element *terminal);
QSharedPointer<PhysicalTerminal> physicalTerminal(QSharedPointer<RealTerminal> terminal) const; QSharedPointer<PhysicalTerminal> physicalTerminal(QSharedPointer<RealTerminal> terminal) const;
RealTerminalData realTerminalData(QSharedPointer<RealTerminal> real_terminal) const; RealTerminalData realTerminalData(QSharedPointer<RealTerminal> real_terminal) const;
QSharedPointer<PhysicalTerminal> physicalTerminalForUuid (const QUuid &uuid) const;
QSharedPointer<RealTerminal> realTerminalForUuid(const QUuid &uuid) const;
private: private:
TerminalStripData m_data; TerminalStripData m_data;

View File

@@ -31,6 +31,7 @@
#include "terminalstripmodel.h" #include "terminalstripmodel.h"
#include "../diagram.h" #include "../diagram.h"
#include "../UndoCommand/sortterminalstripcommand.h" #include "../UndoCommand/sortterminalstripcommand.h"
#include "../UndoCommand/groupterminalscommand.h"
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
@@ -219,11 +220,11 @@ QTreeWidgetItem* TerminalStripEditor::addTerminalStrip(TerminalStrip *terminal_s
{ {
auto real_t = ptd.real_terminals_vector.first(); auto real_t = ptd.real_terminals_vector.first();
auto terminal_item = new QTreeWidgetItem(strip_item, QStringList(real_t.label_), TerminalStripTreeWidget::Terminal); 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); terminal_item->setIcon(0, QET::Icons::ElementTerminal);
if (real_t.element_) { if (real_t.element_) {
m_uuid_terminal_H.insert(real_t.uuid_, qgraphicsitem_cast<TerminalElement *>(real_t.element_)); m_uuid_terminal_H.insert(real_t.element_uuid, qgraphicsitem_cast<TerminalElement *>(real_t.element_));
} }
} }
} }
@@ -536,13 +537,13 @@ void TerminalStripEditor::on_m_auto_ordering_pb_clicked()
*/ */
void TerminalStripEditor::on_m_group_terminals_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()); auto rtd_vector = m_model->realTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes());
if (ptd_vector.size() >= 2) if (rtd_vector.size() >= 2)
{ {
auto receiver_ = ptd_vector.takeFirst(); auto receiver_ = m_current_strip->physicalTerminalData(rtd_vector.takeFirst());
m_current_strip->groupTerminals(receiver_, ptd_vector); m_project->undoStack()->push(new GroupTerminalsCommand(m_current_strip, receiver_, rtd_vector));
} }
} }
} }

View File

@@ -61,7 +61,6 @@ class TerminalStripEditor : public QDialog
void on_m_dialog_button_box_clicked(QAbstractButton *button); void on_m_dialog_button_box_clicked(QAbstractButton *button);
void on_m_auto_ordering_pb_clicked(); void on_m_auto_ordering_pb_clicked();
void on_m_group_terminals_pb_clicked(); void on_m_group_terminals_pb_clicked();
void on_m_ungroup_pb_clicked(); void on_m_ungroup_pb_clicked();
private: private: