428 lines
11 KiB
C++
Raw Normal View History

2021-03-16 19:59:45 +01:00
/*
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 "terminalstrip.h"
#include "../qetproject.h"
#include "../qetgraphicsitem/element.h"
#include "../qetgraphicsitem/terminalelement.h"
2021-03-16 19:59:45 +01:00
using shared_real_terminal = QSharedPointer<RealTerminal>;
using shared_physical_terminal = QSharedPointer<PhysicalTerminal>;
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/**
* @brief The RealTerminal class
* Represent a real terminal.
* A real terminal can be a drawed terminal in a folio
* or a terminal set by user but not present
* on any folio (for example a reserved terminal).
*/
class RealTerminal
{
public :
/**
* @brief RealTerminal
* @param parent_strip : parent terminal strip
* @param terminal : terminal element (if any) in a folio
*/
RealTerminal(TerminalStrip *parent_strip, Element *terminal = nullptr) :
m_element(terminal),
m_parent_terminal_strip(parent_strip)
{}
/**
* @brief isElement
* @return true if this real terminal is linked to a terminal element
*/
bool isElement() const {
return m_element.isNull() ? false : true;
}
/**
* @brief element
* @return the element linked to this real terminal
* or nullptr if not linked to an Element.
*/
Element *element() const {
return m_element.data();
}
/**
* @brief label
* @return the label of this real terminal
*/
QString label() const {
if (!m_element.isNull()) {
return m_element->actualLabel();
} else {
return QStringLiteral("");
}
}
/**
* @brief elementUuid
* @return if this real terminal is an element
* in a folio, return the uuid of the element
* else return a null uuid.
*/
QUuid elementUuid() const {
if (!m_element.isNull()) {
return m_element->uuid();
} else {
return QUuid();
}
}
2021-03-16 19:59:45 +01:00
private :
QPointer<Element> m_element;
QPointer<TerminalStrip> m_parent_terminal_strip;
};
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/**
* @brief The PhysicalTerminal class
* Represent a physical terminal.
* A physical terminal is composed a least by one real terminal.
* When a physical terminal have more than one real terminal
* that mean the physical terminal have levels (one by real terminal).
* The index of terminals returned by the function terminals()
* is the same as the real level of the physical terminal, the index are from back to front.
*
* Example for a 3 levels terminal.
* index 0 = back (mounting plate)
* index 1 = middle
* index 2 = front (electrical cabinet door)
*
* m
* o _
* u | |
* n | | _
* t | || |
* i | || | _
* n | || || | d
* g |0||1||2| o
* | || ||_| o
* p | || | r
* l | ||_|
* a | |
* t |_|
* e
*
*/
class PhysicalTerminal
{
public:
/**
* @brief PhysicalTerminal
* @param parent_strip : Parent terminal strip
* @param terminals : A vector of real terminals
* who compose this physical terminal.
* \p terminals must have at least one terminal
*/
PhysicalTerminal(TerminalStrip *parent_strip,
QVector<shared_real_terminal> terminals) :
m_parent_terminal_strip(parent_strip),
m_real_terminal(terminals)
{}
/**
* @brief setTerminals
* Set the real terminal of this physical terminal
* the order of the terminal in \p terminals represent
* the level index.
* @param terminals
*/
void setTerminals(QVector<shared_real_terminal> terminals) {
m_real_terminal = terminals;
}
/**
* @brief levelCount
* @return the number of level of this terminal
*/
int levelCount() const {
return m_real_terminal.size();
}
/**
* @brief terminals
* @return A vector of real terminal who compose this physical terminal
*/
QVector<shared_real_terminal> terminals() const {
return m_real_terminal;
}
private:
QPointer<TerminalStrip> m_parent_terminal_strip;
QVector<shared_real_terminal> m_real_terminal;
};
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/**
* @brief TerminalStrip::TerminalStrip
* @param installation
* @param location
2021-03-16 19:59:45 +01:00
* @param name
* @param project
*/
TerminalStrip::TerminalStrip(const QString &installation, const QString &location, const QString &name, QETProject *project) :
QObject(project),
m_project(project)
2021-04-02 20:51:55 +02:00
{
m_data.m_installation = installation;
m_data.m_location = location;
m_data.m_name = name;
}
2021-03-16 19:59:45 +01:00
void TerminalStrip::setInstallation(const QString &installation) {
2021-04-02 20:51:55 +02:00
m_data.m_installation = installation;
2021-03-16 19:59:45 +01:00
}
void TerminalStrip::setLocation(const QString &location) {
2021-04-02 20:51:55 +02:00
m_data.m_location = location;
2021-03-16 19:59:45 +01:00
}
void TerminalStrip::setName(const QString &name) {
2021-04-02 20:51:55 +02:00
m_data.m_name = name;
2021-03-16 19:59:45 +01:00
}
2021-04-04 19:39:21 +02:00
void TerminalStrip::setComment(const QString &comment) {
m_data.m_comment = comment;
}
void TerminalStrip::setDescription(const QString &description) {
m_data.m_description = description;
}
2021-03-16 19:59:45 +01:00
/**
* @brief TerminalStrip::addTerminal
* Add terminal to this terminal strip
* @param terminal
* @return true if the terminal was successfully added.
* Return false, if terminal already exist.
* Return false, if terminal is not a terminal element.
*/
bool TerminalStrip::addTerminal(Element *terminal)
{
if (m_terminal_elements_vector.contains(terminal)) {
return false;
}
if (terminal->elementData().m_type != ElementData::Terminale) {
return false;
}
m_terminal_elements_vector.append(terminal);
2021-03-16 19:59:45 +01:00
//Create the real terminal
shared_real_terminal real_terminal(new RealTerminal(this, terminal));
m_real_terminals.append(real_terminal);
//Create a new single level physical terminal
shared_physical_terminal physical_terminal(
new PhysicalTerminal(this,
QVector<shared_real_terminal>{real_terminal}));
m_physical_terminals.append(physical_terminal);
static_cast<TerminalElement *>(terminal)->setParentTerminalStrip(this);
2021-03-16 19:59:45 +01:00
return true;
}
/**
* @brief TerminalStrip::removeTerminal
* Remove terminal from this terminal strip
* @param terminal
* @return true if terminal was successfully removed
*/
bool TerminalStrip::removeTerminal(Element *terminal)
{
if (m_terminal_elements_vector.contains(terminal))
2021-03-16 19:59:45 +01:00
{
m_terminal_elements_vector.removeOne(terminal);
//Get the real and physical terminal associated to @terminal
if (auto real_terminal = realTerminal(terminal))
2021-03-16 19:59:45 +01:00
{
if (auto physical_terminal = physicalTerminal(real_terminal))
{
if (physical_terminal->levelCount() == 1) {
m_physical_terminals.removeOne(physical_terminal);
} else {
auto v = physical_terminal->terminals();
v.removeOne(real_terminal);
physical_terminal->setTerminals(v);
}
2021-03-16 19:59:45 +01:00
}
m_real_terminals.removeOne(real_terminal);
2021-03-16 19:59:45 +01:00
static_cast<TerminalElement *>(terminal)->setParentTerminalStrip(nullptr);
return true;
}
2021-03-16 19:59:45 +01:00
//There is no reason to be here, but in case of....
return false;
}
2021-03-16 19:59:45 +01:00
return false;
}
/**
* @brief TerminalStrip::haveTerminal
* @param terminal
* @return true if \p terminal belong to this strip
*/
bool TerminalStrip::haveTerminal(Element *terminal) {
return m_terminal_elements_vector.contains(terminal);
}
/**
* @brief TerminalStrip::physicalTerminalCount
* @return the number of physical terminal.
* A physical terminal is the representation of a real electrical terminal.
* Notice that a physical terminal can have level (like in real life)
*/
int TerminalStrip::physicalTerminalCount() const {
return m_physical_terminals.size();
}
TerminalStripIndex TerminalStrip::index(int index)
{
TerminalStripIndex tsi_;
if (index < 0 ||
index >= m_physical_terminals.size()) {
return tsi_;
}
auto phy_term = m_physical_terminals.at(index);
for(auto &real_term : phy_term->terminals()) {
tsi_.m_label.append(real_term->label());
tsi_.m_uuid.append(real_term->elementUuid());
}
tsi_.m_valid = true;
return tsi_;
}
/**
* @brief TerminalStrip::terminalElement
* @return A vector of all terminal element owned by this strip
*/
QVector<QPointer<Element> > TerminalStrip::terminalElement() const {
return m_terminal_elements_vector;
}
2021-03-16 19:59:45 +01:00
/**
* @brief TerminalStrip::realTerminal
* @param terminal
* @return the real terminal linked to \p terminal
* the returned QSharedPointer can be null.
*/
QSharedPointer<RealTerminal> TerminalStrip::realTerminal(Element *terminal)
{
shared_real_terminal rt;
for (auto &real : qAsConst(m_real_terminals)) {
if (real->element() == terminal) {
return real;
2021-03-16 19:59:45 +01:00
}
}
return rt;
}
/**
* @brief TerminalStrip::physicalTerminal
* @param terminal
* @return the physical terminal linked to \p terminal.
* The returned QSharedPointer can be null.
*/
QSharedPointer<PhysicalTerminal> TerminalStrip::physicalTerminal(QSharedPointer<RealTerminal> terminal)
{
shared_physical_terminal pt;
for (auto &physical : qAsConst(m_physical_terminals))
{
if (physical->terminals().contains(terminal))
{
pt = physical;
break;
}
}
return pt;
}
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
bool TerminalStripIndex::isValid() const
{
return m_valid;
}
QString TerminalStripIndex::label(int level) const
{
if (level<0 ||
level >= m_label.size()) {
return QStringLiteral("");
}
return m_label.at(level);
}
QUuid TerminalStripIndex::uuid(int level) const
{
if (level<0 ||
level >= m_uuid.size()) {
return QUuid();
}
return m_uuid.at(level);
}