Merge branch 'terminal_strip'

* terminal_strip:
  TerminalStripBridge color can be edited.
  Use QSharedPointer instead of QWeakPointer + remove unused include
  Change struct TerminalStripBridge to class
  Revamp terminalStrip feature code
  Revamp PhysicalTerminal class
  Revamp RealTerminal class...... again
  Improve bridge edition
  Improve code readability
  Fix copy constructo warning
  Make code less spaghetti
  Draw bridge pixmap in the tableview (wip)
  REmove unused method : levelCellCount
  Remove isXrefCell method...
  Add terminal bridge feature
This commit is contained in:
joshua
2022-01-27 19:02:43 +01:00
26 changed files with 2511 additions and 854 deletions

View File

@@ -0,0 +1,71 @@
/*
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 "bridgeterminalscommand.h"
BridgeTerminalsCommand::BridgeTerminalsCommand(TerminalStrip *strip,
QVector<QSharedPointer<RealTerminal>> real_terminal,
QUndoCommand *parent):
QUndoCommand(parent),
m_strip(strip),
m_real_terminal_vector(real_terminal)
{
setText(QObject::tr("Ponter des bornes entre-elles"));
}
void BridgeTerminalsCommand::undo()
{
if (m_strip) {
m_strip->unBridge(m_real_terminal_vector);
}
}
void BridgeTerminalsCommand::redo()
{
if (m_strip) {
m_strip->setBridge(m_real_terminal_vector);
}
}
UnBridgeTerminalsCommand::UnBridgeTerminalsCommand(TerminalStrip *strip,
QVector<QSharedPointer<RealTerminal>> real_terminal,
QUndoCommand *parent):
QUndoCommand(parent),
m_strip(strip)
{
setText(QObject::tr("Supprimer des ponts de bornes"));
if (strip->canUnBridge(real_terminal))
{
m_terminals = real_terminal;
m_bridge = strip->isBridged(real_terminal.first());
}
}
void UnBridgeTerminalsCommand::undo()
{
if (m_strip && m_bridge) {
m_strip->setBridge(m_bridge, m_terminals);
}
}
void UnBridgeTerminalsCommand::redo()
{
if (m_strip) {
m_strip->unBridge(m_terminals);
}
}

View File

@@ -0,0 +1,68 @@
/*
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 BRIDGETERMINALSCOMMAND_H
#define BRIDGETERMINALSCOMMAND_H
#include <QUndoCommand>
#include <QVector>
#include <QPointer>
#include <QMultiMap>
#include "../terminalstrip.h"
/**
* @brief The BridgeTerminalsCommand class
* UndoCommand use to create bridge betwen terminals
* of a terminals strip
*/
class BridgeTerminalsCommand : public QUndoCommand
{
public:
BridgeTerminalsCommand(TerminalStrip *strip, QVector<QSharedPointer<RealTerminal>> real_terminal, QUndoCommand *parent = nullptr);
~BridgeTerminalsCommand() override {}
void undo() override;
void redo() override;
private:
QPointer<TerminalStrip> m_strip;
QVector<QSharedPointer<RealTerminal>> m_real_terminal_vector;
};
/**
* @brief The UnBridgeTerminalsCommand class
* UndoCommand use to remove bridge betwen terminals
* of a terminals strip
*/
class UnBridgeTerminalsCommand : public QUndoCommand
{
public:
UnBridgeTerminalsCommand(TerminalStrip *strip, QVector<QSharedPointer<RealTerminal>> real_terminal, QUndoCommand *parent = nullptr);
~UnBridgeTerminalsCommand() override{}
void undo() override;
void redo() override;
private:
QPointer<TerminalStrip> m_strip;
QSharedPointer<TerminalStripBridge> m_bridge;
QVector<QSharedPointer<RealTerminal>> m_terminals;
};
#endif // BRIDGETERMINALSCOMMAND_H

View File

@@ -16,16 +16,17 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "changeterminallevel.h"
#include "../realterminal.h"
ChangeTerminalLevel::ChangeTerminalLevel(TerminalStrip *strip,
const RealTerminalData &real_terminal,
const QWeakPointer<RealTerminal> &real_terminal,
int level,
QUndoCommand *parent) :
QUndoCommand(parent),
m_strip(strip),
m_real_terminal(real_terminal),
m_new_level(level),
m_old_level(real_terminal.level_)
m_old_level(real_terminal.toStrongRef()->level())
{}
void ChangeTerminalLevel::undo()

View File

@@ -26,7 +26,7 @@ class ChangeTerminalLevel : public QUndoCommand
{
public:
ChangeTerminalLevel(TerminalStrip *strip,
const RealTerminalData &real_terminal,
const QWeakPointer<RealTerminal> &real_terminal,
int level,
QUndoCommand *parent = nullptr);
@@ -35,7 +35,7 @@ class ChangeTerminalLevel : public QUndoCommand
private:
QPointer<TerminalStrip> m_strip;
RealTerminalData m_real_terminal;
QWeakPointer<RealTerminal> m_real_terminal;
int m_new_level, m_old_level;
};

View File

@@ -0,0 +1,51 @@
/*
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 "changeterminalstripcolor.h"
#include "../terminalstripbridge.h"
/**
* @brief ChangeTerminalStripColor::ChangeTerminalStripColor
* @param bridge
* @param color
* @param parent
*/
ChangeTerminalStripColor::ChangeTerminalStripColor(QSharedPointer<TerminalStripBridge> bridge,
const QColor &color,
QUndoCommand *parent):
QUndoCommand(parent),
m_bridge(bridge),
m_new_color(color)
{
if (m_bridge) {
m_old_color = m_bridge->color();
}
}
void ChangeTerminalStripColor::redo()
{
if (m_bridge) {
m_bridge->setColor(m_new_color);
}
}
void ChangeTerminalStripColor::undo()
{
if (m_bridge) {
m_bridge->setColor(m_old_color);
}
}

View File

@@ -0,0 +1,45 @@
/*
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 CHANGETERMINALSTRIPCOLOR_H
#define CHANGETERMINALSTRIPCOLOR_H
#include <QUndoCommand>
#include <QSharedPointer>
#include <QColor>
class TerminalStripBridge;
/**
* @brief The ChangeTerminalStripColor class
*/
class ChangeTerminalStripColor : public QUndoCommand
{
public:
ChangeTerminalStripColor(QSharedPointer<TerminalStripBridge> bridge,
const QColor &color,
QUndoCommand *parent = nullptr);
void redo() override;
void undo() override;
private:
QSharedPointer<TerminalStripBridge> m_bridge;
QColor m_old_color, m_new_color;
};
#endif // CHANGETERMINALSTRIPCOLOR_H

View File

@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "groupterminalscommand.h"
#include "../physicalterminal.h"
/**
* @brief GroupTerminalsCommand::GroupTerminalsCommand
@@ -24,8 +25,8 @@
* @param to_group : Terminals to group
*/
GroupTerminalsCommand::GroupTerminalsCommand(TerminalStrip *strip,
const PhysicalTerminalData &receiver_,
const QVector<RealTerminalData> &to_group,
const QSharedPointer<PhysicalTerminal> &receiver_,
const QVector<QSharedPointer<RealTerminal>> &to_group,
QUndoCommand *parent):
QUndoCommand(parent),
m_terminal_strip(strip),
@@ -43,12 +44,12 @@ void GroupTerminalsCommand::undo() {
void GroupTerminalsCommand::redo() {
if (m_terminal_strip) {
m_terminal_strip->groupTerminals(m_receiver, m_to_group);
m_terminal_strip->groupTerminals(m_receiver,m_to_group);
}
}
UnGroupTerminalsCommand::UnGroupTerminalsCommand(TerminalStrip *strip,
const QVector<RealTerminalData> &to_ungroup,
const QVector<QSharedPointer<RealTerminal>> &to_ungroup,
QUndoCommand *parent) :
QUndoCommand(parent),
m_terminal_strip(strip)
@@ -77,19 +78,21 @@ void UnGroupTerminalsCommand::redo()
}
}
void UnGroupTerminalsCommand::setUp(const QVector<RealTerminalData> &to_ungroup)
void UnGroupTerminalsCommand::setUp(const QVector<QSharedPointer<RealTerminal>> &to_ungroup)
{
for (auto rtd_ : to_ungroup)
for (const auto &rt_ : to_ungroup)
{
auto ptd_ = m_terminal_strip->physicalTerminalData(rtd_);
auto phy_t = m_terminal_strip->physicalTerminal(rt_.toWeakRef());
if (phy_t)
{
//Physical have only one real terminal, no need to ungroup it
if (phy_t->realTerminalCount() <= 1) {
continue;
}
//Physical have only one real terminal, no need to ungroup it
if (ptd_.real_terminals_vector.size() <= 1) {
continue;
auto vector_ = m_physical_real_H.value(phy_t);
vector_.append(rt_);
m_physical_real_H.insert(phy_t, vector_);
}
auto vector_ = m_physical_real_H.value(ptd_);
vector_.append(rtd_);
m_physical_real_H.insert(ptd_, vector_);
}
}

View File

@@ -31,8 +31,8 @@ class GroupTerminalsCommand : public QUndoCommand
{
public:
GroupTerminalsCommand(TerminalStrip *strip,
const PhysicalTerminalData &receiver_,
const QVector<RealTerminalData> &to_group,
const QSharedPointer<PhysicalTerminal> &receiver_,
const QVector<QSharedPointer<RealTerminal>> &to_group,
QUndoCommand *parent = nullptr);
void undo() override;
@@ -40,8 +40,8 @@ class GroupTerminalsCommand : public QUndoCommand
private:
QPointer<TerminalStrip> m_terminal_strip;
PhysicalTerminalData m_receiver;
QVector <RealTerminalData> m_to_group;
QSharedPointer<PhysicalTerminal> m_receiver;
QVector<QSharedPointer<RealTerminal>> m_to_group;
};
/**
@@ -52,18 +52,18 @@ class UnGroupTerminalsCommand : public QUndoCommand
{
public:
UnGroupTerminalsCommand(TerminalStrip *strip,
const QVector<RealTerminalData> &to_ungroup,
const QVector<QSharedPointer<RealTerminal>> &to_ungroup,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
private:
void setUp(const QVector<RealTerminalData> &to_ungroup);
void setUp(const QVector<QSharedPointer<RealTerminal>> &to_ungroup);
private:
QPointer<TerminalStrip> m_terminal_strip;
QHash <PhysicalTerminalData, QVector<RealTerminalData>> m_physical_real_H;
QHash <QSharedPointer<PhysicalTerminal>, QVector<QSharedPointer<RealTerminal>>> m_physical_real_H;
};
#endif // GROUPTERMINALSCOMMAND_H

View File

@@ -17,13 +17,16 @@
*/
#include "sortterminalstripcommand.h"
#include "../terminalstrip.h"
#include "../physicalterminal.h"
#include "../realterminal.h"
SortTerminalStripCommand::SortTerminalStripCommand(TerminalStrip *strip, QUndoCommand *parent) :
QUndoCommand(parent),
m_strip(strip)
{
setText(QObject::tr("Trier le bornier %1").arg(m_strip->name()));
m_old_order = m_new_order = m_strip->physicalTerminalData();
m_old_order = m_strip->physicalTerminal();
m_new_order = m_strip->physicalTerminal();
sort();
}
@@ -43,7 +46,7 @@ void SortTerminalStripCommand::redo()
void SortTerminalStripCommand::sort()
{
std::sort(m_new_order.begin(), m_new_order.end(), [](PhysicalTerminalData arg1, PhysicalTerminalData arg2)
std::sort(m_new_order.begin(), m_new_order.end(), [](QSharedPointer<PhysicalTerminal> arg1, QSharedPointer<PhysicalTerminal> arg2)
{
const QRegularExpression rx(QStringLiteral("^\\d+"));
@@ -52,9 +55,9 @@ void SortTerminalStripCommand::sort()
int int1 =-1;
int int2 =-1;
if (arg1.real_terminals_vector.count())
if (arg1->realTerminalCount())
{
str1 = arg1.real_terminals_vector.constLast().label_;
str1 = arg1->realTerminals().constLast()->label();
auto match = rx.match(str1);
if (match.hasMatch()) {
@@ -62,9 +65,9 @@ void SortTerminalStripCommand::sort()
}
}
if (arg2.real_terminals_vector.count())
if (arg2->realTerminalCount())
{
str2 = arg2.real_terminals_vector.constLast().label_;
str2 = arg2->realTerminals().constLast()->label();
auto match = rx.match(str2);
if (match.hasMatch()) {

View File

@@ -23,7 +23,7 @@
#include <QVector>
class TerminalStrip;
struct PhysicalTerminalData;
class PhysicalTerminal;
/**
* @brief The SortTerminalStripCommand class
@@ -43,8 +43,8 @@ class SortTerminalStripCommand : public QUndoCommand
private:
QPointer<TerminalStrip> m_strip;
QVector<PhysicalTerminalData> m_old_order,
m_new_order;
QVector<QSharedPointer<PhysicalTerminal>> m_old_order,
m_new_order;
};
#endif // SORTTERMINALSTRIPCOMMAND_H

View File

@@ -0,0 +1,176 @@
/*
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 "physicalterminal.h"
#include "realterminal.h"
#include "terminalstrip.h"
/**
* @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::PhysicalTerminal(TerminalStrip *parent_strip,
QVector<QSharedPointer<RealTerminal>> terminals) :
m_parent_terminal_strip(parent_strip),
m_real_terminal(terminals)
{}
/**
* @brief PhysicalTerminal::sharedRef
* @return a QSharedPointer of this
*/
QSharedPointer<PhysicalTerminal> PhysicalTerminal::sharedRef()
{
QSharedPointer<PhysicalTerminal> this_shared(this->weakRef());
if (this_shared.isNull())
{
this_shared = QSharedPointer<PhysicalTerminal>(this);
m_this_weak = this_shared.toWeakRef();
}
return this_shared;
}
/**
* @brief PhysicalTerminal::weakRef
* @return a QWeakPointer of this, weak pointer can be null
*/
QWeakPointer<PhysicalTerminal> PhysicalTerminal::weakRef() {
return m_this_weak;
}
/**
* @brief toXml
* @param parent_document
* @return this physical terminal to xml
*/
QDomElement PhysicalTerminal::toXml(QDomDocument &parent_document) const
{
auto root_elmt = parent_document.createElement(this->xmlTagName());
for (auto &real_t : m_real_terminal) {
root_elmt.appendChild(real_t->toXml(parent_document));
}
return root_elmt;
}
/**
* @brief setTerminals
* Set the RealTerminal who compose this physical terminal.
* The position of the RealTerminal in @a terminals
* represent the level of these in this physical terminal.
* @param terminals
*/
void PhysicalTerminal::setTerminals(const QVector<QSharedPointer<RealTerminal>> &terminals) {
m_real_terminal = terminals;
}
/**
* @brief addTerminals
* Append the real terminal @a terminal
* to this physical terminal.
* @param terminal
*/
void PhysicalTerminal::addTerminal(const QSharedPointer<RealTerminal> &terminal) {
m_real_terminal.append(terminal);
}
/**
* @brief removeTerminal
* Remove @a terminal from the list of real terminal
* @param terminal
* @return true if sucessfully removed
*/
bool PhysicalTerminal::removeTerminal(const QSharedPointer<RealTerminal> &terminal) {
return m_real_terminal.removeOne(terminal);
}
/**
* @brief setLevelOf
* Change the level of \p terminal
* @param terminal
* @param level
*/
bool PhysicalTerminal::setLevelOf(const QSharedPointer<RealTerminal> &terminal, int level)
{
const int i = m_real_terminal.indexOf(terminal);
if (i >= 0)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
m_real_terminal.swapItemsAt(i, std::min(level, m_real_terminal.size()-1));
#else
auto j = std::min(level, m_real_terminal.size()-1);
std::swap(m_real_terminal.begin()[i], m_real_terminal.begin()[j]);
#endif
return true;
}
return false;
}
/**
* @brief levelCount
* @return the number of level of this terminal
*/
int PhysicalTerminal::levelCount() const {
return m_real_terminal.size();
}
/**
* @brief levelOf
* @param terminal
* @return the level of real terminal \p terminal or
* -1 if \terminal is not a part of this physicalTerminal
*/
int PhysicalTerminal::levelOf(const QSharedPointer<RealTerminal> &terminal) const {
return m_real_terminal.indexOf(terminal);
}
/**
* @brief terminals
* @return A vector of RealTerminal who compose this PhysicalTerminal
*/
QVector<QSharedPointer<RealTerminal>> PhysicalTerminal::realTerminals() const {
return m_real_terminal;
}
/**
* @brief uuid
* @return the uuid of this physical terminal
*/
QUuid PhysicalTerminal::uuid() const {
return m_uuid;
}
int PhysicalTerminal::pos() const
{
if (m_parent_terminal_strip) {
return m_parent_terminal_strip->pos(m_this_weak);
} else {
return -1;
}
}
int PhysicalTerminal::realTerminalCount() const {
return m_real_terminal.size();
}
QString PhysicalTerminal::xmlTagName() {
return QStringLiteral("physical_terminal");
}

View File

@@ -0,0 +1,96 @@
/*
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 PHYSICALTERMINAL_H
#define PHYSICALTERMINAL_H
#include <QSharedPointer>
#include <QDomElement>
#include <QPointer>
#include <QUuid>
class RealTerminal;
class TerminalStrip;
/**
* @brief The PhysicalTerminal class
* Represent a physical terminal.
* A physical terminal is composed a least by one RealTerminal.
* When a physical terminal have more than one real terminal
* that mean the physical terminal have levels (one by real terminal).
* The index of real terminals returned by the function terminals()
* is the same as the real level of the real 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
{
friend class TerminalStrip;
private:
PhysicalTerminal(TerminalStrip *parent_strip, QVector<QSharedPointer<RealTerminal>> terminals);
QSharedPointer<PhysicalTerminal> sharedRef();
QWeakPointer<PhysicalTerminal> weakRef();
QDomElement toXml(QDomDocument &parent_document) const;
void setTerminals(const QVector<QSharedPointer<RealTerminal>> &terminals);
void addTerminal(const QSharedPointer<RealTerminal> &terminal);
bool removeTerminal(const QSharedPointer<RealTerminal> &terminal);
bool setLevelOf(const QSharedPointer<RealTerminal> &terminal, int level);
public:
PhysicalTerminal(){}
int levelCount() const;
int levelOf(const QSharedPointer<RealTerminal> &terminal) const;
QVector<QSharedPointer<RealTerminal>> realTerminals() const;
QUuid uuid() const;
int pos() const;
int realTerminalCount() const;
static QString xmlTagName();
private:
QPointer<TerminalStrip> m_parent_terminal_strip;
QVector<QSharedPointer<RealTerminal>> m_real_terminal;
QUuid m_uuid = QUuid::createUuid();
QWeakPointer<PhysicalTerminal> m_this_weak;
};
#endif // PHYSICALTERMINAL_H

View File

@@ -0,0 +1,286 @@
/*
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 "realterminal.h"
#include "terminalstrip.h"
#include "../qetgraphicsitem/terminalelement.h"
#include "physicalterminal.h"
/**
* @brief RealTerminal
* @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)
{}
/**
* @brief RealTerminal::sharedRef
* @return a QSharedPointer of this
*/
QSharedPointer<RealTerminal> RealTerminal::sharedRef()
{
QSharedPointer<RealTerminal> this_shared(this->weakRef());
if (this_shared.isNull())
{
this_shared = QSharedPointer<RealTerminal>(this);
m_this_weak = this_shared.toWeakRef();
}
return this_shared;
}
/**
* @brief RealTerminal::weakRef
* @return a QWeakPointer of this, weak pointer can be bull
*/
QWeakPointer<RealTerminal> RealTerminal::weakRef() {
return m_this_weak;
}
/**
* @brief fromXml
* @param xml_element
* @return
*/
bool RealTerminal::fromXml(QDomElement xml_element, const QVector<TerminalElement *> &terminal_vector)
{
if (xml_element.tagName() != xmlTagName()) {
return true;
}
auto is_draw = xml_element.attribute(QStringLiteral("is_draw")) == QLatin1String("true")
? true : false;
QUuid uuid_(xml_element.attribute(QStringLiteral("uuid")));
if (is_draw) {
for (auto terminal : terminal_vector) {
if (terminal->uuid() == uuid_)
{
m_element = terminal;
break;
}
}
} else {
m_uuid = uuid_;
}
return true;
}
/**
* @brief toXml
* @param parent_document
* @return this real terminal to xml
*/
QDomElement RealTerminal::toXml(QDomDocument &parent_document) const
{
auto root_elmt = parent_document.createElement(this->xmlTagName());
root_elmt.setAttribute("is_draw", m_element ? "true" : "false");
root_elmt.setAttribute("uuid", m_element ? m_element->uuid().toString() :
m_uuid.toString());
return root_elmt;
}
/**
* @brief parentStrip
* @return parent terminal strip
*/
TerminalStrip *RealTerminal::parentStrip() const {
return m_parent_terminal_strip.data();
}
/**
* @brief RealTerminal::level
* @return
*/
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);
}
}
return -1;
}
/**
* @brief label
* @return the label of this real terminal
*/
QString RealTerminal::label() const {
if (!m_element.isNull()) {
return m_element->actualLabel();
} else {
return QLatin1String();
}
}
/**
* @brief RealTerminal::Xref
* @return Conveniant method to get the XRef
* formated to string
*/
QString RealTerminal::Xref() const
{
if (!m_element.isNull()) {
return autonum::AssignVariables::genericXref(m_element.data());
} else {
return QString();
}
}
/**
* @brief RealTerminal::cable
* @return
*/
QString RealTerminal::cable() const {
return QString();
}
/**
* @brief RealTerminal::cableWire
* @return
*/
QString RealTerminal::cableWire() const {
return QString();
}
/**
* @brief RealTerminal::conductor
* @return
*/
QString RealTerminal::conductor() const {
return QString();
}
/**
* @brief RealTerminal::type
* @return
*/
ElementData::TerminalType RealTerminal::type() const {
if (m_element) {
return m_element->elementData().terminalType();
} else {
return ElementData::TTGeneric;
}
}
/**
* @brief RealTerminal::function
* @return
*/
ElementData::TerminalFunction RealTerminal::function() const {
if (m_element) {
return m_element->elementData().terminalFunction();
} else {
return ElementData::TFGeneric;
}
}
/**
* @brief RealTerminal::isLed
* @return
*/
bool RealTerminal::isLed() const {
if (m_element) {
return m_element->elementData().terminalLed();
} else {
return false;
}
}
/**
* @brief isElement
* @return true if this real terminal is linked to a terminal element
*/
bool RealTerminal::isElement() const {
return m_element.isNull() ? false : true;
}
/**
* @brief RealTerminal::isBridged
* @return true if is bridged.
* @sa TerminalStrip::isBridged
*/
bool RealTerminal::isBridged() const
{
if (m_parent_terminal_strip) {
return !m_parent_terminal_strip->isBridged(m_this_weak.toStrongRef()).isNull();
} else {
return false;
}
}
/**
* @brief RealTerminal::bridge
* @return
*/
QSharedPointer<TerminalStripBridge> RealTerminal::bridge() const
{
if (m_parent_terminal_strip) {
return m_parent_terminal_strip->isBridged(m_this_weak.toStrongRef());
} else {
return QSharedPointer<TerminalStripBridge>();
}
}
/**
* @brief element
* @return the element linked to this real terminal
* or nullptr if not linked to an Element.
*/
Element *RealTerminal::element() const {
return m_element.data();
}
/**
* @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 RealTerminal::elementUuid() const {
if (!m_element.isNull()) {
return m_element->uuid();
} else {
return QUuid();
}
}
/**
* @brief uuid
* @return the uuid of this real terminal
*/
QUuid RealTerminal::uuid() const {
return m_uuid;
}
/**
* @brief RealTerminal::RealTerminal::xmlTagName
* @return
*/
QString RealTerminal::RealTerminal::xmlTagName() {
return QStringLiteral("real_terminal");
}

View File

@@ -0,0 +1,86 @@
/*
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 REALTERMINAL_H
#define REALTERMINAL_H
#include <QSharedPointer>
#include <QDomElement>
#include "../properties/elementdata.h"
class TerminalStrip;
class Element;
class TerminalElement;
class PhysicalTerminal;
class TerminalStripBridge;
/**
* @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).
*
* When create a new instance of RealTerminal you must
* call sharedRef() and only use the returned QSharedPointer
* instead of the raw pointer
*/
class RealTerminal
{
friend class TerminalStrip;
friend class PhysicalTerminal;
private:
RealTerminal(TerminalStrip *strip, Element *element = nullptr);
QSharedPointer<RealTerminal> sharedRef();
QWeakPointer<RealTerminal> weakRef();
bool fromXml(QDomElement xml_element, const QVector<TerminalElement *> &terminal_vector);
QDomElement toXml(QDomDocument &parent_document) const;
public:
TerminalStrip *parentStrip() const;
int level() const;
QString label() const;
QString Xref() const;
QString cable() const;
QString cableWire() const;
QString conductor() const;
ElementData::TerminalType type() const;
ElementData::TerminalFunction function() const;
bool isLed() const;
bool isElement() const;
bool isBridged() const;
QSharedPointer<TerminalStripBridge> bridge() const;
Element* element() const;
QUuid elementUuid() const;
QUuid uuid() const;
static QString xmlTagName();
private :
QPointer<Element> m_element;
QPointer<TerminalStrip> m_parent_terminal_strip;
QUuid m_uuid = QUuid::createUuid();
QWeakPointer<RealTerminal> m_this_weak;
};
#endif // REALTERMINAL_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/*
/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
@@ -20,6 +20,8 @@
#include <QObject>
#include <QPointer>
#include <QColor>
#include "terminalstripdata.h"
#include "../properties/elementdata.h"
@@ -29,65 +31,30 @@ class QETProject;
class PhysicalTerminal;
class TerminalStripIndex;
class TerminalElement;
struct RealTerminalData
{
int level_ = -1;
QString label_,
Xref_,
cable_,
cable_wire_,
conductor_;
QUuid element_uuid,
real_terminal_uuid;
ElementData::TerminalType type_;
ElementData::TerminalFunction function_;
bool led_ = false,
is_element = false;
QPointer<Element> element_;
};
struct PhysicalTerminalData
{
QVector<RealTerminalData> real_terminals_vector;
int pos_ = -1;
QUuid uuid_;
};
//Code to use PhysicalTerminalData as key for QHash
inline bool operator == (const PhysicalTerminalData &phy_1, const PhysicalTerminalData &phy_2) {
return phy_1.uuid_ == phy_2.uuid_;
}
inline uint qHash(const PhysicalTerminalData &key, uint seed) {
return qHash(key.uuid_, seed);
}
class TerminalStrip;
class TerminalStripBridge;
/**
* @brief The TerminalStrip class
* This class hold all the datas and configurations
* of a terminal strip (but the not the visual aspect).
* A terminal strip have some informations (name comment etc...)
* and is composed by terminals (draw in a diagram or described in the terminal strip)
* and is composed by one or several PhysicalTerminal.
*/
class TerminalStrip : public QObject
{
friend class TerminalStripModel;
friend class RealTerminalData;
Q_OBJECT
public:
signals:
void orderChanged(); //Emitted when the order of the physical terminal is changed
void bridgeChanged();
void bridgeColorChanged(QSharedPointer<TerminalStripBridge> bridge);
public:
TerminalStrip(QETProject *project);
TerminalStrip(const QString &installation,
@@ -113,14 +80,30 @@ class TerminalStrip : public QObject
bool addTerminal (Element *terminal);
bool removeTerminal (Element *terminal);
int pos(const QSharedPointer<PhysicalTerminal> &terminal) const;
int physicalTerminalCount() const;
PhysicalTerminalData physicalTerminalData(int index) const;
PhysicalTerminalData physicalTerminalData (const RealTerminalData &real_data) const;
QVector<PhysicalTerminalData> physicalTerminalData() const;
bool setOrderTo(const QVector<PhysicalTerminalData> &sorted_vector);
bool groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector<RealTerminalData> &added_terminals);
void unGroupTerminals(const QVector<RealTerminalData> &terminals_to_ungroup);
bool setLevel(const RealTerminalData &real_terminal_data, int level);
QSharedPointer<PhysicalTerminal> physicalTerminal(int index) const;
QSharedPointer<PhysicalTerminal> physicalTerminal (const QSharedPointer<RealTerminal> &real_terminal) const;
QVector<QSharedPointer<PhysicalTerminal>> physicalTerminal() const;
QSharedPointer<RealTerminal> realTerminal(Element *terminal) const;
bool setOrderTo(const QVector<QSharedPointer<PhysicalTerminal>> &sorted_vector);
bool groupTerminals(const QSharedPointer<PhysicalTerminal> &receiver_terminal, const QVector<QSharedPointer<RealTerminal>> &added_terminals);
void unGroupTerminals(const QVector<QSharedPointer<RealTerminal>> &terminals_to_ungroup);
bool setLevel(const QSharedPointer<RealTerminal> &real_terminal, int level);
bool isBridgeable(const QVector<QSharedPointer<RealTerminal>> &real_terminals) const;
bool setBridge(const QVector<QSharedPointer<RealTerminal>> &real_terminals);
bool setBridge(const QSharedPointer<TerminalStripBridge> &bridge, const QVector<QSharedPointer<RealTerminal>> &real_terminals);
void unBridge(const QVector<QSharedPointer<RealTerminal>> &real_terminals);
bool canUnBridge(const QVector <QSharedPointer<RealTerminal>> &real_terminals) const;
QSharedPointer<TerminalStripBridge> isBridged(const QSharedPointer<RealTerminal> real_terminal) const;
QSharedPointer<TerminalStripBridge> bridgeFor (const QVector<QSharedPointer<RealTerminal>> &terminal_vector) const;
QSharedPointer<RealTerminal> previousTerminalInLevel(const QSharedPointer<RealTerminal> &real_terminal) const;
QSharedPointer<RealTerminal> nextTerminalInLevel(const QSharedPointer<RealTerminal> &real_terminal) const;
QSharedPointer<RealTerminal> previousRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const;
QSharedPointer<RealTerminal> nextRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const;
QVector<QPointer<Element>> terminalElement() const;
@@ -129,11 +112,7 @@ class TerminalStrip : public QObject
bool fromXml(QDomElement &xml_element);
private:
QSharedPointer<RealTerminal> realTerminal(Element *terminal);
QSharedPointer<PhysicalTerminal> physicalTerminal(QSharedPointer<RealTerminal> terminal) const;
RealTerminalData realTerminalData(QSharedPointer<RealTerminal> real_terminal) const;
QSharedPointer<PhysicalTerminal> physicalTerminalForUuid (const QUuid &uuid) const;
QSharedPointer<RealTerminal> realTerminalForUuid(const QUuid &uuid) const;
void rebuildRealVector();
private:
TerminalStripData m_data;
@@ -141,6 +120,7 @@ class TerminalStrip : public QObject
QVector<QPointer<Element>> m_terminal_elements_vector;
QVector<QSharedPointer<RealTerminal>> m_real_terminals;
QVector<QSharedPointer<PhysicalTerminal>> m_physical_terminals;
QVector<QSharedPointer<TerminalStripBridge>> m_bridge;
};
#endif // TERMINALSTRIP_H

View File

@@ -0,0 +1,115 @@
/*
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 "terminalstripbridge.h"
#include "realterminal.h"
#include "terminalstrip.h"
TerminalStripBridge::TerminalStripBridge(TerminalStrip *parent_strip) :
m_strip(parent_strip)
{}
/**
* @brief TerminalStripBridge::sharedRef
* @return a QSharedPointer of this
*/
QSharedPointer<TerminalStripBridge> TerminalStripBridge::sharedRef()
{
QSharedPointer<TerminalStripBridge> this_shared(this->weakRef());
if (this_shared.isNull())
{
this_shared = QSharedPointer<TerminalStripBridge>(this);
m_this_weak = this_shared.toWeakRef();
}
return this_shared;
}
/**
* @brief TerminalStripBridge::weakRef
* @return a QWeakPointer of this, weak pointer can be null
*/
QWeakPointer<TerminalStripBridge> TerminalStripBridge::weakRef() {
return m_this_weak;
}
/**
* @brief TerminalStripBridge::color
* @return The color of this bridge
*/
QColor TerminalStripBridge::color() const {
return m_color;
}
void TerminalStripBridge::setColor(const QColor &color) {
m_color = color;
if (m_strip) {
m_strip->bridgeColorChanged(sharedRef());
}
}
/**
* @brief TerminalStripBridge::realTerminals
* @return the real terminals who are bridged by this bridge
*/
QVector<QSharedPointer<RealTerminal> > TerminalStripBridge::realTerminals() const {
return m_real_terminals;
}
/**
* @brief TerminalStripBridge::addTerminals
* @param real_terminals
* @return Add terminals of @a real_terminals to this bridge.
* If a terminal is already bridged by this bridge, the terminal is ignored.
* If at least one terminal doesn't belong to the same strip of this bridge
* this function do nothing and return false.
*/
bool TerminalStripBridge::addTerminals(const QVector<QSharedPointer<RealTerminal> > &real_terminals)
{
QVector<QSharedPointer<RealTerminal>> to_append;
for (const auto &real_t : real_terminals)
{
if (!real_t.isNull())
{
if (real_t->parentStrip() != m_strip) {
return false;
}
if (!m_real_terminals.contains(real_t)) {
to_append.append(real_t);
}
} else {
return false;
}
}
m_real_terminals.append(to_append);
return true;
}
/**
* @brief TerminalStripBridge::removeTerminals
* @param real_terminal
* Remove all real terminal of @real_terminals from this bridge.
* This function doesn't make any check, they just remove if exist.
* @sa TerminalStrip::canUnBridge
*/
void TerminalStripBridge::removeTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals)
{
for (const auto &real_t : real_terminals) {
m_real_terminals.removeOne(real_t);
}
}

View File

@@ -0,0 +1,59 @@
/*
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 TERMINALSTRIPBRIDGE_H
#define TERMINALSTRIPBRIDGE_H
#include <QSharedPointer>
#include <QUuid>
#include <QPointer>
#include <QColor>
class RealTerminal;
class TerminalStrip;
class TerminalStripBridge
{
friend class TerminalStrip;
public:
static QVector<QColor> bridgeColor() {return QVector<QColor>{Qt::red, Qt::blue, Qt::white, Qt::darkGray, Qt::black};}
TerminalStripBridge(TerminalStrip *parent_strip = nullptr);
QSharedPointer<TerminalStripBridge> sharedRef();
QWeakPointer<TerminalStripBridge> weakRef();
QColor color() const;
void setColor(const QColor &color);
QVector<QSharedPointer<RealTerminal>> realTerminals() const;
private:
bool addTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals);
void removeTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals);
private:
QPointer<TerminalStrip> m_strip;
QVector<QSharedPointer<RealTerminal>> m_real_terminals;
QColor m_color = Qt::darkGray;
QUuid m_uuid = QUuid::createUuid();
QWeakPointer<TerminalStripBridge> m_this_weak;
};
#endif // TERMINALSTRIPBRIDGE_H

View File

@@ -24,6 +24,10 @@ TerminalStripData::TerminalStripData()
}
TerminalStripData::TerminalStripData(const TerminalStripData &other) {
*this = other;
}
QDomElement TerminalStripData::toXml(QDomDocument &xml_document) const
{
auto root_elmt = xml_document.createElement(this->xmlTagName());

View File

@@ -29,6 +29,7 @@ class TerminalStripData : public PropertiesInterface
public:
TerminalStripData();
TerminalStripData(const TerminalStripData &other);
void toSettings(QSettings &/*settings*/, const QString = QString()) const override {}
void fromSettings (const QSettings &/*settings*/, const QString = QString()) override {}

View File

@@ -1,4 +1,4 @@
/*
/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
@@ -33,6 +33,11 @@
#include "../UndoCommand/sortterminalstripcommand.h"
#include "../UndoCommand/groupterminalscommand.h"
#include "../UndoCommand/changeterminallevel.h"
#include "../UndoCommand/bridgeterminalscommand.h"
#include "../UndoCommand/changeterminalstripcolor.h"
#include "../physicalterminal.h"
#include "../realterminal.h"
#include "../terminalstripbridge.h"
#include <QTreeWidgetItem>
@@ -49,6 +54,7 @@ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
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)
@@ -56,26 +62,34 @@ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
#else
ui->m_terminal_strip_tw->expandAll();
#endif
//Setup the bridge color
ui->m_bridge_color_cb->setColors(TerminalStripBridge::bridgeColor().toList());
setUpUndoConnections();
//Call for update the state of child widgets
selectionChanged();
//Go the diagram of double clicked terminal
connect(ui->m_table_widget, &QAbstractItemView::doubleClicked, [this](const QModelIndex &index)
connect(ui->m_table_widget, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
{
Element *elmt = nullptr;
if (this->m_model->isXrefCell(index, &elmt))
if (m_model->columnTypeForIndex(index) == TerminalStripModel::XRef)
{
auto diagram = elmt->diagram();
if (diagram)
auto mrtd = m_model->modelRealTerminalDataForIndex(index);
if (mrtd.element_)
{
diagram->showMe();
if (diagram->views().size())
auto elmt = mrtd.element_;
auto diagram = elmt->diagram();
if (diagram)
{
auto fit_view = elmt->sceneBoundingRect();
fit_view.adjust(-200,-200,200,200);
diagram->views().first()->fitInView(fit_view, Qt::KeepAspectRatioByExpanding);
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);
}
}
}
}
@@ -91,8 +105,8 @@ TerminalStripEditor::~TerminalStripEditor() {
void TerminalStripEditor::setUpUndoConnections()
{
connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalAddedToStrip,
[this](QUuid terminal_uuid, QUuid strip_uuid)
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);
@@ -105,8 +119,8 @@ void TerminalStripEditor::setUpUndoConnections()
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)
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);
@@ -120,8 +134,8 @@ void TerminalStripEditor::setUpUndoConnections()
m_project->undoStack()->push(undo);
});
connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalRemovedFromStrip,
[this] (QUuid terminal_uuid, QUuid old_strip_uuid)
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);
@@ -221,16 +235,16 @@ QTreeWidgetItem* TerminalStripEditor::addTerminalStrip(TerminalStrip *terminal_s
//Add child terminal of the strip
for (auto i=0 ; i<terminal_strip->physicalTerminalCount() ; ++i)
{
auto ptd = terminal_strip->physicalTerminalData(i);
if (ptd.real_terminals_vector.size())
auto phy_t = terminal_strip->physicalTerminal(i);
if (phy_t->realTerminalCount())
{
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.element_uuid.toString());
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.element_uuid, qgraphicsitem_cast<TerminalElement *>(real_t.element_));
if (real_t->element()) {
m_uuid_terminal_H.insert(real_t->elementUuid(), qgraphicsitem_cast<TerminalElement *>(real_t->element()));
}
}
}
@@ -286,6 +300,7 @@ 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);
}
if (!strip_)
@@ -317,10 +332,12 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
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);
}
}
@@ -339,7 +356,7 @@ void TerminalStripEditor::spanMultiLevelTerminals()
auto current_row = 0;
for (auto i = 0 ; i < m_current_strip->physicalTerminalCount() ; ++i)
{
const auto level_count = m_current_strip->physicalTerminalData(i).real_terminals_vector.size();
const auto level_count = m_current_strip->physicalTerminal(i)->realTerminalCount();
if (level_count > 1) {
ui->m_table_widget->setSpan(current_row, 0, level_count, 1);
}
@@ -361,6 +378,10 @@ void TerminalStripEditor::selectionChanged()
ui->m_type_cb ->setDisabled(true);
ui->m_function_cb ->setDisabled(true);
ui->m_led_cb ->setDisabled(true);
ui->m_bridge_terminals_pb ->setDisabled(true);
ui->m_unbridge_terminals_pb->setDisabled(true);
ui->m_bridge_color_cb ->setDisabled(true);
return;
}
@@ -378,32 +399,132 @@ void TerminalStripEditor::selectionChanged()
ui->m_led_cb ->setEnabled(true);
}
const auto terminal_vector = m_model->physicalTerminalDataForIndex(index_list);
const auto model_physical_terminal_vector = m_model->modelPhysicalTerminalDataForIndex(index_list);
const auto model_real_terminal_vector = m_model->modelRealTerminalDataForIndex(index_list);
//Enable/disable group button
ui->m_group_terminals_pb->setEnabled(terminal_vector.size() > 1 ? true : false);
ui->m_group_terminals_pb->setEnabled(model_physical_terminal_vector.size() > 1 ? true : false);
//Enable/disable ungroup button
auto it_= std::find_if(terminal_vector.constBegin(), terminal_vector.constEnd(), [](const PhysicalTerminalData &data)
auto it_= std::find_if(model_physical_terminal_vector.constBegin(), model_physical_terminal_vector.constEnd(), [](const modelPhysicalTerminalData &data)
{
if (data.real_terminals_vector.size() >= 2) {
if (data.real_data.size() >= 2) {
return true;
} else {
return false;
}
});
ui->m_ungroup_pb->setDisabled(it_ == terminal_vector.constEnd());
ui->m_ungroup_pb->setDisabled(it_ == model_physical_terminal_vector.constEnd());
//Enable/disable level spinbox
bool enable_ = false;
for (const auto &physical : terminal_vector)
for (const auto &physical : model_physical_terminal_vector)
{
if (physical.real_terminals_vector.size() > 1) {
if (physical.real_data.size() > 1) {
enable_ = true;
break;
}
}
ui->m_level_sb->setEnabled(enable_);
//Enable/disable bridge and unbridge
bool enable_bridge = false;
bool enable_unbridge = false;
bool enable_bridge_color = false;
//One column must be selected and the column must be a level column
int level_ = TerminalStripModel::levelForColumn(isSingleColumnSelected());
if (level_ >= 0 && m_current_strip)
{
//Select only terminals of corresponding level cell selection
QVector<QSharedPointer<RealTerminal>> real_terminal_in_level_vector;
for (const auto &mrtd : model_real_terminal_vector)
{
if (mrtd.level_ == level_) {
real_terminal_in_level_vector.append(mrtd.real_terminal.toStrongRef());
if (!enable_bridge_color && mrtd.bridged_) {
enable_bridge_color = true;
}
}
}
enable_bridge = m_current_strip->isBridgeable(real_terminal_in_level_vector);
enable_unbridge = m_current_strip->canUnBridge(real_terminal_in_level_vector);
}
ui->m_bridge_terminals_pb->setEnabled(enable_bridge);
ui->m_unbridge_terminals_pb->setEnabled(enable_unbridge);
ui->m_bridge_color_cb->setEnabled(enable_bridge_color);
}
QSize TerminalStripEditor::setUpBridgeCellWidth()
{
if (ui->m_table_widget->verticalHeader() &&
m_model)
{
auto section_size = ui->m_table_widget->verticalHeader()->defaultSectionSize();
auto h_header = ui->m_table_widget->horizontalHeader();
for (int i = TerminalStripModel::Level0 ; i<(TerminalStripModel::Level3+1) ; ++i) {
ui->m_table_widget->setColumnWidth(i, section_size);
h_header->setSectionResizeMode(i, QHeaderView::Fixed);
}
return QSize(section_size, section_size);
}
return QSize(0,0);
}
/**
* @brief TerminalStripEditor::isSingleColumnSelected
* If all current QModelIndex are in the same column
* return the column type
* @sa TerminalStripModel::Column
* @return the column or TerminalStripModel::Invalid if several column are selected
*/
TerminalStripModel::Column TerminalStripEditor::isSingleColumnSelected() const
{
if (m_current_strip &&
ui->m_table_widget->selectionModel())
{
const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
if (index_list.isEmpty()) {
return TerminalStripModel::Invalid;
}
auto column_ = index_list.first().column();
for (const auto &index : index_list) {
if (index.column() != column_) {
return TerminalStripModel::Invalid;
}
}
return TerminalStripModel::columnTypeForIndex(index_list.first());
}
return TerminalStripModel::Invalid;
}
/**
* @brief TerminalStripEditor::singleColumnData
* @return a QPair with for first value the column and for second value the data
* of selected cell of the table widget, only if the selected cells are
* in the same column. If selected cells are not in the same column the first value
* of the QPair is TerminalStripModel::Invalid.
*/
QPair<TerminalStripModel::Column, QVector<modelRealTerminalData> > TerminalStripEditor::singleColumnData() const
{
if (m_current_strip)
{
auto level_ = isSingleColumnSelected();
if (level_ != TerminalStripModel::Invalid)
{
const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
const auto mrtd_vector = m_model->modelRealTerminalDataForIndex(index_list);
return qMakePair(level_, mrtd_vector);
}
}
return qMakePair(TerminalStripModel::Invalid, QVector<modelRealTerminalData>());
}
/**
@@ -540,22 +661,20 @@ void TerminalStripEditor::on_m_dialog_button_box_clicked(QAbstractButton *button
if (m_model)
{
for (const auto &data_ : m_model->modifiedRealTerminalData())
for (const auto &data_ : m_model->modifiedmodelRealTerminalData())
{
auto original_ = data_.first;
auto edited_ = data_.second;
auto element = original_.element_;
if (element) {
if (auto element = data_.element_)
{
auto current_data = element->elementData();
current_data.setTerminalType(edited_.type_);
current_data.setTerminalFunction(edited_.function_);
current_data.setTerminalLED(edited_.led_);
current_data.m_informations.addValue(QStringLiteral("label"), edited_.label_);
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 (edited_.level_)
m_project->undoStack()->push(new ChangeTerminalLevel(m_current_strip, original_, edited_.level_));
if (data_.level_ != data_.real_terminal.toStrongRef()->level())
m_project->undoStack()->push(new ChangeTerminalLevel(m_current_strip, data_.real_terminal, data_.level_));
}
}
}
@@ -584,11 +703,18 @@ void TerminalStripEditor::on_m_group_terminals_pb_clicked()
{
if (m_model && m_current_strip && m_project)
{
auto rtd_vector = m_model->realTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes());
if (rtd_vector.size() >= 2)
auto mrtd_vector = m_model->modelRealTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes());
if (mrtd_vector.size() >= 2)
{
auto receiver_ = m_current_strip->physicalTerminalData(rtd_vector.takeFirst());
m_project->undoStack()->push(new GroupTerminalsCommand(m_current_strip, receiver_, rtd_vector));
auto receiver_ = m_current_strip->physicalTerminal(mrtd_vector.takeFirst().real_terminal);
QVector<QSharedPointer<RealTerminal>> vector_;
for (const auto & mrtd : mrtd_vector) {
vector_.append(mrtd.real_terminal.toStrongRef());
}
m_project->undoStack()->push(new GroupTerminalsCommand(m_current_strip,
receiver_,
vector_));
}
}
}
@@ -600,8 +726,13 @@ void TerminalStripEditor::on_m_ungroup_pb_clicked()
{
if (m_model && m_current_strip)
{
const auto rtd_vector = m_model->realTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes());
m_project->undoStack()->push(new UnGroupTerminalsCommand(m_current_strip, rtd_vector));
const auto mrtd_vector = m_model->modelRealTerminalDataForIndex(ui->m_table_widget->selectionModel()->selectedIndexes());
QVector<QSharedPointer<RealTerminal>> vector_;
for (const auto &mrtd : mrtd_vector) {
vector_.append(mrtd.real_terminal.toStrongRef());
}
m_project->undoStack()->push(new UnGroupTerminalsCommand(m_current_strip,vector_));
}
}
@@ -617,7 +748,7 @@ void TerminalStripEditor::on_m_level_sb_valueChanged(int arg1)
for (auto index : index_list)
{
auto level_index = m_model->index(index.row(), 1, index.parent());
auto level_index = m_model->index(index.row(), TerminalStripModel::Level, index.parent());
if (level_index.isValid())
{
m_model->setData(level_index, arg1);
@@ -634,7 +765,7 @@ void TerminalStripEditor::on_m_type_cb_activated(int index)
for (auto model_index : index_list)
{
auto type_index = m_model->index(model_index.row(), 6, model_index.parent());
auto type_index = m_model->index(model_index.row(), TerminalStripModel::Type, model_index.parent());
if (type_index.isValid())
{
ElementData::TerminalType override_type;
@@ -667,7 +798,7 @@ void TerminalStripEditor::on_m_function_cb_activated(int index)
for (auto model_index : index_list)
{
auto function_index = m_model->index(model_index.row(), 7, model_index.parent());
auto function_index = m_model->index(model_index.row(), TerminalStripModel::Function, model_index.parent());
if (function_index.isValid())
{
ElementData::TerminalFunction override_function;
@@ -696,7 +827,7 @@ void TerminalStripEditor::on_m_led_cb_activated(int index)
for (auto model_index : index_list)
{
auto led_index = m_model->index(model_index.row(), 8, model_index.parent());
auto led_index = m_model->index(model_index.row(), TerminalStripModel::Led, model_index.parent());
if (led_index.isValid()) {
m_model->setData(led_index,
@@ -706,3 +837,89 @@ void TerminalStripEditor::on_m_led_cb_activated(int index)
}
}
/**
* @brief TerminalStripEditor::on_m_bridge_terminals_pb_clicked
*/
void TerminalStripEditor::on_m_bridge_terminals_pb_clicked()
{
if (m_current_strip)
{
int level_ = isSingleColumnSelected();
if (level_ >= TerminalStripModel::Level0 &&
level_ <= TerminalStripModel::Level3)
{
if(level_ == TerminalStripModel::Level0){level_ = 0;}
else if(level_ == TerminalStripModel::Level1){level_ = 1;}
else if(level_ == TerminalStripModel::Level2){level_ = 2;}
else if(level_ == TerminalStripModel::Level3){level_ = 3;}
const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
const auto mrtd_vector = m_model->modelRealTerminalDataForIndex(index_list);
QVector <QSharedPointer<RealTerminal>> match_vector;
for (const auto &mrtd : mrtd_vector)
{
if (mrtd.level_ == level_) {
match_vector.append(mrtd.real_terminal.toStrongRef());
}
}
if (m_current_strip->isBridgeable(match_vector)) {
m_project->undoStack()->push(new BridgeTerminalsCommand(m_current_strip, match_vector));
}
}
}
}
/**
* @brief TerminalStripEditor::on_m_unbridge_terminals_pb_clicked
*/
void TerminalStripEditor::on_m_unbridge_terminals_pb_clicked()
{
if (m_current_strip)
{
int level_ = isSingleColumnSelected();
if (level_ >= TerminalStripModel::Level0 &&
level_ <= TerminalStripModel::Level3)
{
if(level_ == TerminalStripModel::Level0){level_ = 0;}
else if(level_ == TerminalStripModel::Level1){level_ = 1;}
else if(level_ == TerminalStripModel::Level2){level_ = 2;}
else if(level_ == TerminalStripModel::Level3){level_ = 3;}
const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
const auto mrtd_vector = m_model->modelRealTerminalDataForIndex(index_list);
QVector<QSharedPointer<RealTerminal>> match_vector;
for (const auto &mrtd : mrtd_vector)
{
if (mrtd.level_ == level_
&& mrtd.bridged_) {
match_vector.append(mrtd.real_terminal.toStrongRef());
}
}
m_project->undoStack()->push(new UnBridgeTerminalsCommand(m_current_strip, match_vector));
}
}
}
void TerminalStripEditor::on_m_bridge_color_cb_activated(const QColor &col)
{
const auto data_vector = singleColumnData();
const auto column_ = data_vector.first;
if (column_ == TerminalStripModel::Level0 ||
column_ == TerminalStripModel::Level1 ||
column_ == TerminalStripModel::Level2 ||
column_ == TerminalStripModel::Level3)
{
const auto level_ = TerminalStripModel::levelForColumn(column_);
for (const auto &mrtd : data_vector.second)
{
if (mrtd.level_ == level_ && mrtd.bridged_) {
auto bridge_ = mrtd.real_terminal.toStrongRef()->bridge();
m_project->undoStack()->push(new ChangeTerminalStripColor(bridge_, col));
break;
}
}
}
}

View File

@@ -20,6 +20,8 @@
#include <QDialog>
#include "terminalstripmodel.h"
namespace Ui {
class TerminalStripEditor;
}
@@ -29,7 +31,6 @@ class TerminalStrip;
class QTreeWidgetItem;
class TerminalElement;
class QAbstractButton;
class TerminalStripModel;
/**
* @brief The TerminalStripEditor class
@@ -52,6 +53,9 @@ class TerminalStripEditor : public QDialog
void setCurrentStrip(TerminalStrip *strip_);
void spanMultiLevelTerminals();
void selectionChanged();
QSize setUpBridgeCellWidth();
TerminalStripModel::Column isSingleColumnSelected() const;
QPair<TerminalStripModel::Column, QVector<modelRealTerminalData>> singleColumnData() const;
private slots:
void on_m_add_terminal_strip_pb_clicked();
@@ -66,6 +70,9 @@ class TerminalStripEditor : public QDialog
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_bridge_terminals_pb_clicked();
void on_m_unbridge_terminals_pb_clicked();
void on_m_bridge_color_cb_activated(const QColor &col);
private:
Ui::TerminalStripEditor *ui;

View File

@@ -178,34 +178,14 @@
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_3">
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Type :</string>
<string>Étage :</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="m_ungroup_pb">
<property name="text">
<string>Degrouper les bornes</string>
</property>
</widget>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<item row="6" column="1">
<widget class="QComboBox" name="m_type_cb">
<item>
<property name="text">
@@ -234,10 +214,96 @@
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="m_level_sb"/>
<item row="8" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>LED :</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="m_level_sb"/>
</item>
<item row="9" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="13" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="m_auto_ordering_pb">
<property name="text">
<string>Position automatique</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Couleur pont :</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QPushButton" name="m_group_terminals_pb">
<property name="text">
<string>Grouper les bornes</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="m_ungroup_pb">
<property name="text">
<string>Degrouper les bornes</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Type :</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="m_led_cb">
<item>
<property name="text">
<string>Sans</string>
</property>
</item>
<item>
<property name="text">
<string>Avec</string>
</property>
</item>
</widget>
</item>
<item row="12" column="1">
<widget class="KColorCombo" name="m_bridge_color_cb"/>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="m_function_cb">
<item>
<property name="text">
@@ -256,52 +322,17 @@
</item>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="m_auto_ordering_pb">
<item row="10" column="0" colspan="2">
<widget class="QPushButton" name="m_bridge_terminals_pb">
<property name="text">
<string>Position automatique</string>
<string>Ponter les bornes</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<item row="11" column="0" colspan="2">
<widget class="QPushButton" name="m_unbridge_terminals_pb">
<property name="text">
<string>Étage :</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QPushButton" name="m_group_terminals_pb">
<property name="text">
<string>Grouper les bornes</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="m_led_cb">
<item>
<property name="text">
<string>Sans</string>
</property>
</item>
<item>
<property name="text">
<string>Avec</string>
</property>
</item>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>LED :</string>
<string>Déponter les bornes</string>
</property>
</widget>
</item>
@@ -375,6 +406,11 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KColorCombo</class>
<extends>QComboBox</extends>
<header>kcolorcombo.h</header>
</customwidget>
<customwidget>
<class>TerminalStripTreeWidget</class>
<extends>QTreeWidget</extends>

View File

@@ -18,30 +18,86 @@
#include "terminalstripmodel.h"
#include "../terminalstrip.h"
#include "../../qetgraphicsitem/element.h"
#include "../physicalterminal.h"
#include "../realterminal.h"
#include "../terminalstripbridge.h"
#include <QDebug>
#include <QBrush>
#include <QVector>
#include <QComboBox>
#include <QSpinBox>
#include <QPainter>
#include <QApplication>
/**
* Some const int who describe what a column contain
*/
const int POS_CELL = 0;
const int LEVEL_CELL = 1;
const int LABEL_CELL = 2;
const int XREF_CELL = 3;
const int CABLE_CELL = 4;
const int CABLE_WIRE_CELL = 5;
const int TYPE_CELL = 6;
const int FUNCTION_CELL = 7;
const int LED_CELL = 8;
const int CONDUCTOR_CELL = 9;
const int LEVEL_0_CELL = 2;
const int LEVEL_1_CELL = 3;
const int LEVEL_2_CELL = 4;
const int LEVEL_3_CELL = 5;
const int LABEL_CELL = 6;
const int XREF_CELL = 7;
const int CABLE_CELL = 8;
const int CABLE_WIRE_CELL = 9;
const int TYPE_CELL = 10;
const int FUNCTION_CELL = 11;
const int LED_CELL = 12;
const int CONDUCTOR_CELL = 13;
const int ROW_COUNT = 9;
const int ROW_COUNT = 13;
static QVector<bool> UNMODIFIED_CELL_VECTOR{false, false, false, false, false, false, false, false, false, false};
static QVector<bool> UNMODIFIED_CELL_VECTOR{false, false, false, false, false, false, false, false, false, false, false, false, false, false};
/**
* @brief TerminalStripModel::levelForColumn
* Return the terminal level for column @a column
* or -1 if column is not a level column
* @param column
* @return
*/
int TerminalStripModel::levelForColumn(Column column)
{
switch (column) {
case Level0: return 0;
case Level1: return 1;
case Level2: return 2;
case Level3: return 3;
default: return -1;
}
}
/**
* @brief TerminalStripModel::columnTypeForIndex
* @param index
* @return the thing (pos, level, type, function etc...) for @a index
*/
TerminalStripModel::Column TerminalStripModel::columnTypeForIndex(const QModelIndex &index)
{
if (index.isValid())
{
switch (index.column()) {
case 0: return Pos;
case 1: return Level;
case 2 : return Level0;
case 3 : return Level1;
case 4 : return Level2;
case 5 : return Level3;
case 6 : return Label;
case 7 : return XRef;
case 8 : return Cable;
case 9 : return CableWire;
case 10 : return Type;
case 11 : return Function;
case 12 : return Led;
case 13 : return Conductor;
default : return Invalid;
}
}
return Invalid;
}
/**
* @brief TerminalStripModel::TerminalStripModel
@@ -53,6 +109,11 @@ TerminalStripModel::TerminalStripModel(TerminalStrip *terminal_strip, QObject *p
m_terminal_strip(terminal_strip)
{
fillPhysicalTerminalData();
connect(terminal_strip, &TerminalStrip::bridgeColorChanged, this, [=] {
emit dataChanged(index(0, LEVEL_0_CELL),
index(rowCount(), LEVEL_3_CELL));
});
}
int TerminalStripModel::rowCount(const QModelIndex &parent) const
@@ -64,8 +125,8 @@ int TerminalStripModel::rowCount(const QModelIndex &parent) const
}
auto count = 0;
for (const auto &ptd : m_edited_terminal_data) {
count += ptd.real_terminals_vector.size();
for (const auto &mptd : m_physical_data) {
count += mptd.real_data.size();
}
return count;
@@ -83,28 +144,28 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
return QVariant();
}
const auto rtd = dataAtRow(index.row());
const auto mrtd = dataAtRow(index.row());
if (role == Qt::DisplayRole)
{
switch (index.column()) {
case POS_CELL : return physicalDataAtIndex(index.row()).pos_;
case LEVEL_CELL : return rtd.level_;
case LABEL_CELL : return rtd.label_;
case XREF_CELL : return rtd.Xref_;
case CABLE_CELL : return rtd.cable_;
case CABLE_WIRE_CELL : return rtd.cable_wire_;
case TYPE_CELL : return ElementData::translatedTerminalType(rtd.type_);
case FUNCTION_CELL : return ElementData::translatedTerminalFunction(rtd.function_);
case CONDUCTOR_CELL : return rtd.conductor_;
case LEVEL_CELL : return mrtd.level_;
case LABEL_CELL : return mrtd.label_;
case XREF_CELL : return mrtd.Xref_;
case CABLE_CELL : return mrtd.cable_;
case CABLE_WIRE_CELL : return mrtd.cable_wire;
case TYPE_CELL : return ElementData::translatedTerminalType(mrtd.type_);
case FUNCTION_CELL : return ElementData::translatedTerminalFunction(mrtd.function_);
case CONDUCTOR_CELL : return mrtd.conductor_;
default : return QVariant();
}
}
else if (role == Qt::EditRole)
{
switch (index.column()) {
case LABEL_CELL : return rtd.label_;
case LABEL_CELL : return mrtd.label_;
default: return QVariant();
}
@@ -112,23 +173,35 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
else if (role == Qt::CheckStateRole &&
index.column() == LED_CELL)
{
return rtd.led_ ? Qt::Checked : Qt::Unchecked;
return mrtd.led_ ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::BackgroundRole && index.column() <= CONDUCTOR_CELL )
{
if (m_modified_cell.contains(rtd.element_) &&
m_modified_cell.value(rtd.element_).at(index.column()))
if (m_modified_cell.contains(mrtd.element_) &&
m_modified_cell.value(mrtd.element_).at(index.column()))
{
return QBrush(Qt::yellow);
}
}
else if (role == Qt::DecorationRole &&
(index.column() == LEVEL_0_CELL ||
index.column() == LEVEL_1_CELL ||
index.column() == LEVEL_2_CELL ||
index.column() == LEVEL_3_CELL))
{
return bridgePixmapFor(index);
auto pixmap_ = bridgePixmapFor(index);
if (!pixmap_.isNull()) {
return pixmap_;
}
}
return QVariant();
}
bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
auto rtd = dataAtRow(index.row());
auto mrtd = dataAtRow(index.row());
bool modified_ = false;
int modified_cell = -1;
auto column_ = index.column();
@@ -136,35 +209,35 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value
if (column_ == LEVEL_CELL &&
role == Qt::EditRole)
{
rtd.level_ = value.toInt();
mrtd.level_ = value.toInt();
modified_ = true;
modified_cell = LEVEL_CELL;
}
else if (column_ == LED_CELL)
{
rtd.led_ = value.toBool();
mrtd.led_ = value.toBool();
modified_ = true;
modified_cell = LED_CELL;
}
else if (column_ == TYPE_CELL &&
role == Qt::EditRole)
{
rtd.type_ = value.value<ElementData::TerminalType>();
mrtd.type_ = value.value<ElementData::TerminalType>();
modified_ = true;
modified_cell = TYPE_CELL;
}
else if (column_ == FUNCTION_CELL &&
role == Qt::EditRole)
{
rtd.function_ = value.value<ElementData::TerminalFunction>();
mrtd.function_ = value.value<ElementData::TerminalFunction>();
modified_ = true;
modified_cell = FUNCTION_CELL;
}
else if (column_ == LABEL_CELL &&
role == Qt::EditRole &&
rtd.label_ != value.toString())
mrtd.label_ != value.toString())
{
rtd.label_ = value.toString();
mrtd.label_ = value.toString();
modified_ = true;
modified_cell = LABEL_CELL;
}
@@ -172,19 +245,19 @@ bool TerminalStripModel::setData(const QModelIndex &index, const QVariant &value
//Set the modification to the terminal data
if (modified_)
{
replaceDataAtRow(rtd, index.row());
replaceDataAtRow(mrtd, index.row());
if (rtd.element_)
if (mrtd.element_)
{
QVector<bool> vector_;
if (m_modified_cell.contains(rtd.element_)) {
vector_ = m_modified_cell.value(rtd.element_);
if (m_modified_cell.contains(mrtd.element_)) {
vector_ = m_modified_cell.value(mrtd.element_);
} else {
vector_ = UNMODIFIED_CELL_VECTOR;
}
vector_.replace(modified_cell, true);
m_modified_cell.insert(rtd.element_, vector_);
m_modified_cell.insert(mrtd.element_, vector_);
}
emit dataChanged(index, index);
return true;
@@ -202,6 +275,10 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation
switch (section) {
case POS_CELL: return tr("Position");
case LEVEL_CELL: return tr("Étage");
case LEVEL_0_CELL: return QStringLiteral("0");
case LEVEL_1_CELL: return QStringLiteral("1");
case LEVEL_2_CELL: return QStringLiteral("2");
case LEVEL_3_CELL: return QStringLiteral("3");
case LABEL_CELL: return tr("Label");
case XREF_CELL: return tr("Référence croisé");
case CABLE_CELL: return tr("Câble");
@@ -236,22 +313,21 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const
* @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
*/
QVector<QPair<RealTerminalData, RealTerminalData>> TerminalStripModel::modifiedRealTerminalData() const
QVector<modelRealTerminalData> TerminalStripModel::modifiedmodelRealTerminalData() const
{
QVector<QPair<RealTerminalData, RealTerminalData>> returned_vector;
QVector<modelRealTerminalData> returned_vector;
const auto modified_real_terminal = m_modified_cell.keys();
for (auto i = 0 ; i<m_edited_terminal_data.size() ; ++i)
for (auto i = 0 ; i<m_physical_data.size() ; ++i)
{
auto ptd_ = m_edited_terminal_data.at(i);
for (auto j = 0 ; j < ptd_.real_terminals_vector.size() ; ++j)
auto ptd_ = m_physical_data.at(i);
for (auto j = 0 ; j < ptd_.real_data.size() ; ++j)
{
auto rtd_ = ptd_.real_terminals_vector.at(j);
if (modified_real_terminal.contains(rtd_.element_))
auto mrtd_ = ptd_.real_data.at(j);
if (modified_real_terminal.contains(mrtd_.element_))
{
returned_vector.append(qMakePair(m_original_terminal_data.at(i).real_terminals_vector.at(j),
m_edited_terminal_data.at(i).real_terminals_vector.at(j)));
returned_vector.append(m_physical_data.at(i).real_data.at(j));
}
}
}
@@ -259,40 +335,15 @@ QVector<QPair<RealTerminalData, RealTerminalData>> TerminalStripModel::modifiedR
return returned_vector;
}
/**
* @brief TerminalStripModel::isXrefCell
* @param index
* @param elmt : Pointer of a pointer element
* @return true if the index is the Xref cell, if true the pointer \p element
* will be set to the element associated to the cell.
*/
bool TerminalStripModel::isXrefCell(const QModelIndex &index, Element **element)
{
if (index.model() == this
&& index.isValid()
&& index.column() == XREF_CELL)
{
if (index.row() < rowCount())
{
if (auto data = dataAtRow(index.row()) ; data.element_) {
*element = data.element_.data();
}
}
return true;
}
return false;
}
/**
* @brief TerminalStripModel::terminalsForIndex
* @param index_list
* @return A vector of PhysicalTerminalData represented by index_list.
* If sereval index point to the same terminal the vector have only one PhysicalTerminalData
*/
QVector<PhysicalTerminalData> TerminalStripModel::physicalTerminalDataForIndex(QModelIndexList index_list) const
QVector<modelPhysicalTerminalData> TerminalStripModel::modelPhysicalTerminalDataForIndex(QModelIndexList index_list) const
{
QVector<PhysicalTerminalData> vector_;
QVector<modelPhysicalTerminalData> vector_;
if (index_list.isEmpty()) {
return vector_;
}
@@ -306,7 +357,8 @@ QVector<PhysicalTerminalData> TerminalStripModel::physicalTerminalDataForIndex(Q
}
}
for (auto i : set_) {
for (const auto i : set_)
{
const auto phy = physicalDataAtIndex(i);
if (!vector_.contains(phy)) {
vector_.append(phy);
@@ -321,9 +373,9 @@ QVector<PhysicalTerminalData> TerminalStripModel::physicalTerminalDataForIndex(Q
* @param index_list
* @return
*/
QVector<RealTerminalData> TerminalStripModel::realTerminalDataForIndex(QModelIndexList index_list) const
QVector<modelRealTerminalData> TerminalStripModel::modelRealTerminalDataForIndex(QModelIndexList index_list) const
{
QVector<RealTerminalData> vector_;
QVector<modelRealTerminalData> vector_;
if (index_list.isEmpty()) {
return vector_;
}
@@ -346,28 +398,127 @@ QVector<RealTerminalData> TerminalStripModel::realTerminalDataForIndex(QModelInd
return vector_;
}
void TerminalStripModel::fillPhysicalTerminalData()
/**
* @brief TerminalStripModel::realTerminalDataForIndex
* @param index
* @return modelRealTerminalData at index @a index or null modelRealTerminalData if invalid
*/
modelRealTerminalData TerminalStripModel::modelRealTerminalDataForIndex(const QModelIndex &index) const
{
//Get all physical terminal
if (m_terminal_strip) {
for (auto i=0 ; i < m_terminal_strip->physicalTerminalCount() ; ++i) {
m_original_terminal_data.append(m_terminal_strip->physicalTerminalData(i));
}
m_edited_terminal_data = m_original_terminal_data;
if (index.isValid()) {
return realDataAtIndex(index.row());
} else {
return modelRealTerminalData();
}
}
RealTerminalData TerminalStripModel::dataAtRow(int row) const
/**
* @brief TerminalStripModel::buildBridgePixmap
* Build the pixmap of bridge.
* You should call this method when you know the
* size to use in the bridge cell of a QTableView.
* @param pixmap_size
*/
void TerminalStripModel::buildBridgePixmap(const QSize &pixmap_size)
{
m_bridges_pixmaps.clear();
for (auto color_ : TerminalStripBridge::bridgeColor())
{
QPen pen;
pen.setColor(color_);
pen.setWidth(1);
QBrush brush;
brush.setColor(color_);
brush.setStyle(Qt::SolidPattern);
QPixmap top_(pixmap_size);
top_.fill(Qt::lightGray);
QPainter top_p(&top_);
top_p.setPen(pen);
top_p.setBrush(brush);
QPixmap middle_(pixmap_size);
middle_.fill(Qt::lightGray);
QPainter middle_p(&middle_);
middle_p.setPen(pen);
middle_p.setBrush(brush);
QPixmap bottom_(pixmap_size);
bottom_.fill(Qt::lightGray);
QPainter bottom_p(&bottom_);
bottom_p.setPen(pen);
bottom_p.setBrush(brush);
QPixmap none_(pixmap_size);
none_.fill(Qt::lightGray);
QPainter none_p(&none_);
none_p.setPen(pen);
none_p.setBrush(brush);
auto w_ = pixmap_size.width();
auto h_ = pixmap_size.height();
//Draw circle
top_p.drawEllipse(QPoint(w_/2, h_/2), w_/4, h_/4);
middle_p.drawEllipse(QPoint(w_/2, h_/2), w_/4, h_/4);
bottom_p.drawEllipse(QPoint(w_/2, h_/2), w_/4, h_/4);
//Draw top line
middle_p.drawRect((w_/2)-(w_/8), 0, w_/4, h_/2);
bottom_p.drawRect((w_/2)-(w_/8), 0, w_/4, h_/2);
none_p.drawRect((w_/2)-(w_/8), 0, w_/4, h_/2);
//Draw bottom line
top_p.drawRect((w_/2)-(w_/8), h_/2, w_/4, h_/2);
middle_p.drawRect((w_/2)-(w_/8), h_/2, w_/4, h_/2);
none_p.drawRect((w_/2)-(w_/8), h_/2, w_/4, h_/2);
BridgePixmap bpxm;
bpxm.top_ = top_;
bpxm.middle_ = middle_;
bpxm.bottom_ = bottom_;
bpxm.none_ = none_;
m_bridges_pixmaps.insert(color_, bpxm);
}
}
void TerminalStripModel::fillPhysicalTerminalData()
{
//Get all physical terminal
if (m_terminal_strip)
{
for (const auto &phy_t : m_terminal_strip->physicalTerminal())
{
modelPhysicalTerminalData mptd;
mptd.pos_ = phy_t->pos();
mptd.uuid_ = phy_t->uuid();
for (const auto &real_t : phy_t->realTerminals())
{
if (!real_t.isNull())
{
mptd.real_data.append(modelRealData(real_t));
}
}
m_physical_data.append(mptd);
}
}
}
modelRealTerminalData TerminalStripModel::dataAtRow(int row) const
{
if (row > rowCount(QModelIndex())) {
return RealTerminalData();
return modelRealTerminalData();
}
else
{
auto current_row = 0;
for (const auto &physical_data : m_edited_terminal_data)
for (const auto &physical_data : qAsConst(m_physical_data))
{
for (const auto &real_data : physical_data.real_terminals_vector)
for (const auto &real_data : physical_data.real_data)
{
if (current_row == row) {
return real_data;
@@ -378,7 +529,7 @@ RealTerminalData TerminalStripModel::dataAtRow(int row) const
}
}
return RealTerminalData();
return modelRealTerminalData();
}
/**
@@ -387,7 +538,7 @@ RealTerminalData TerminalStripModel::dataAtRow(int row) const
* @param data
* @param row
*/
void TerminalStripModel::replaceDataAtRow(RealTerminalData data, int row)
void TerminalStripModel::replaceDataAtRow(modelRealTerminalData data, int row)
{
if (row > rowCount(QModelIndex())) {
return;
@@ -397,15 +548,15 @@ void TerminalStripModel::replaceDataAtRow(RealTerminalData data, int row)
auto current_row = 0;
auto current_physical = 0;
for (const auto &physical_data : qAsConst(m_edited_terminal_data))
for (const auto &physical_data : qAsConst(m_physical_data))
{
auto current_real = 0;
for (int i=0 ; i<physical_data.real_terminals_vector.count() ; ++i)
for (int i=0 ; i<physical_data.real_data.count() ; ++i)
{
if (current_row == row) {
auto physical_data = m_edited_terminal_data.at(current_physical);
physical_data.real_terminals_vector.replace(current_real, data);
m_edited_terminal_data.replace(current_physical, physical_data);
auto physical_data = m_physical_data.at(current_physical);
physical_data.real_data.replace(current_real, data);
m_physical_data.replace(current_physical, physical_data);
return;
} else {
++current_real;
@@ -426,19 +577,19 @@ void TerminalStripModel::replaceDataAtRow(RealTerminalData data, int row)
* have is own row.
* If \p index is out of range, return a default PhysicalTerminalData (pos_ is set to -1 by default)
*/
PhysicalTerminalData TerminalStripModel::physicalDataAtIndex(int index) const
modelPhysicalTerminalData TerminalStripModel::physicalDataAtIndex(int index) const
{
if (m_edited_terminal_data.isEmpty()) {
return PhysicalTerminalData();
if (m_physical_data.isEmpty()) {
return modelPhysicalTerminalData();
}
int current_checked_index = -1;
int current_phy = -1;
bool match_ = false;
for (const auto &ptd_ : qAsConst(m_edited_terminal_data))
for (const auto &ptd_ : qAsConst(m_physical_data))
{
current_checked_index += ptd_.real_terminals_vector.size();
current_checked_index += ptd_.real_data.size();
++current_phy;
if (current_checked_index >= index) {
@@ -448,9 +599,9 @@ PhysicalTerminalData TerminalStripModel::physicalDataAtIndex(int index) const
}
if (match_) {
return m_edited_terminal_data.at(current_phy);
return m_physical_data.at(current_phy);
} else {
return PhysicalTerminalData();
return modelPhysicalTerminalData();
}
}
@@ -459,17 +610,17 @@ PhysicalTerminalData TerminalStripModel::physicalDataAtIndex(int index) const
* @param index
* @return the realTerminalData at index \p index.
*/
RealTerminalData TerminalStripModel::realDataAtIndex(int index) const
modelRealTerminalData TerminalStripModel::realDataAtIndex(int index) const
{
if (m_edited_terminal_data.isEmpty()) {
return RealTerminalData();
if (m_physical_data.isEmpty()) {
return modelRealTerminalData();
}
int current_checked_index = -1;
for (const auto & ptd_ : qAsConst(m_edited_terminal_data))
for (const auto & ptd_ : qAsConst(m_physical_data))
{
for (const auto & rtd_ : qAsConst(ptd_.real_terminals_vector)) {
for (const auto & rtd_ : qAsConst(ptd_.real_data)) {
++current_checked_index;
if (current_checked_index == index) {
return rtd_;
@@ -477,11 +628,165 @@ RealTerminalData TerminalStripModel::realDataAtIndex(int index) const
}
}
return RealTerminalData();
return modelRealTerminalData();
}
QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
{
if (!index.isValid() || m_terminal_strip.isNull()) {
return QPixmap();
}
auto level_column = levelForColumn(columnTypeForIndex(index));
if (level_column == -1) {
return QPixmap();
}
auto mrtd = modelRealTerminalDataForIndex(index);
//Terminal level correspond to the column level of index
if (level_column == mrtd.level_)
{
if (mrtd.bridged_)
{
auto bridge_ = m_terminal_strip->isBridged(mrtd.real_terminal);
if (bridge_)
{
const auto previous_t = m_terminal_strip->previousTerminalInLevel(mrtd.real_terminal);
QSharedPointer<TerminalStripBridge> previous_bridge;
if (previous_t)
previous_bridge = previous_t->bridge();
const auto next_t = m_terminal_strip->nextTerminalInLevel(mrtd.real_terminal);
QSharedPointer<TerminalStripBridge> next_bridge;
if (next_t)
next_bridge = next_t->bridge();
auto color_ = bridge_->color();
auto pixmap_ = m_bridges_pixmaps.value(color_);
//Current real terminal between two bridged terminal
if ((bridge_ == previous_bridge) &&
(bridge_ == next_bridge)) {
return pixmap_.middle_;
} else if (bridge_ == previous_bridge) {
return pixmap_.bottom_;
} else if (bridge_ == next_bridge) {
return pixmap_.top_;
}
}
}
}
//Terminal level ins't in the same column level of index
//Check if we need to draw a none bridge pixmap
//Check previous
auto phy_t = m_terminal_strip->physicalTerminal(mrtd.real_terminal);
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));
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_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) {
previous_data = current_real_terminal;
break;
}
}
else if (already_jumped_to_previous) { //We are not in same physical terminal as previous loop
break;
} else {
already_jumped_to_previous = true;
current_phy_uuid = m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid();
if (current_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) {
previous_data = current_real_terminal;
break;
}
}
} while(true);
//Check next
current_real_terminal = mrtd;
current_phy_uuid = phy_t->uuid();
bool already_jumped_to_next = false;
modelRealTerminalData next_data;
do {
current_real_terminal = modelRealData(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_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) {
next_data = current_real_terminal;
break;
}
}
else if (already_jumped_to_next) { //We are not in same physical terminal as previous loop
break;
} else {
already_jumped_to_next = true;
current_phy_uuid = m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid();
if (current_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) {
next_data = current_real_terminal;
break;
}
}
} while(true);
auto previous_bridge = m_terminal_strip->isBridged(previous_data.real_terminal);
if (previous_bridge == m_terminal_strip->isBridged(next_data.real_terminal))
{
if (previous_bridge) {
return m_bridges_pixmaps.value(previous_bridge->color()).none_;
}
}
return QPixmap();
}
modelRealTerminalData TerminalStripModel::modelRealData(const QWeakPointer<RealTerminal> &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;
}
/***********************************************************
* Alittle delegate for add a combobox to edit type
* A little delegate for add a combobox to edit type
* and a spinbox to edit the level of a terminal
**********************************************************/
@@ -536,3 +841,43 @@ void TerminalStripModelDelegate::setModelData(QWidget *editor, QAbstractItemMode
}
}
}
/**
* @brief TerminalStripModelDelegate::paint
* By default on a QTableView, Qt draw pixmap in cell with a little margin at left.
* Override the function to draw the pixmap of bridge without the margin at left.
* @param painter
* @param option
* @param index
*/
void TerminalStripModelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
auto column = index.column();
if (column == LEVEL_0_CELL ||
column == LEVEL_1_CELL ||
column == LEVEL_2_CELL ||
column == LEVEL_3_CELL)
{
auto variant = index.data(Qt::DecorationRole);
if (variant.isNull()) {
QStyledItemDelegate::paint(painter, option, index);
}
else
{
if (option.state & QStyle::State_Selected)
{
QStyleOptionViewItem opt_ = option;
initStyleOption(&opt_, index);
QStyle *style = QApplication::style();
auto px = style->generatedIconPixmap(QIcon::Selected, variant.value<QPixmap>(), &opt_);
style->drawItemPixmap(painter, option.rect, Qt::AlignLeft, px);
}
else {
painter->drawPixmap(option.rect, variant.value<QPixmap>());
}
}
}
else {
QStyledItemDelegate::paint(painter, option, index);
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
@@ -22,14 +22,82 @@
#include <QObject>
#include <QPointer>
#include <QStyledItemDelegate>
#include <QPair>
#include <QHash>
#include <QColor>
#include "../terminalstrip.h"
#include "../../qetgraphicsitem/element.h"
//Code to use QColor as key for QHash
inline uint qHash(const QColor &key, uint seed) {
return qHash(key.name(), seed);
}
//needed to use QPointer<Element> as key of QHash
inline uint qHash(const QPointer<Element> &key, uint seed) {
if (key)
return qHash(key->uuid(), seed);
else
return qHash(nullptr, 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> element_;
QWeakPointer<RealTerminal> real_terminal;
};
struct modelPhysicalTerminalData
{
QVector<modelRealTerminalData> 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:
enum Column {
Pos = 0,
Level = 1,
Level0 = 2,
Level1 = 3,
Level2 = 4,
Level3 = 5,
Label = 6,
XRef = 7,
Cable = 8,
CableWire = 9,
Type = 10,
Function = 11,
Led = 12,
Conductor = 13,
Invalid = 99
};
static int levelForColumn(TerminalStripModel::Column column);
static TerminalStripModel::Column columnTypeForIndex(const QModelIndex &index);
Q_OBJECT
public:
TerminalStripModel(TerminalStrip *terminal_strip, QObject *parent = nullptr);
@@ -40,24 +108,38 @@ class TerminalStripModel : public QAbstractTableModel
virtual bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
virtual Qt::ItemFlags flags (const QModelIndex &index) const override;
QVector<modelRealTerminalData> modifiedmodelRealTerminalData() const;
QVector<QPair<RealTerminalData, RealTerminalData>> modifiedRealTerminalData() const;
QVector<modelPhysicalTerminalData> modelPhysicalTerminalDataForIndex(QModelIndexList index_list) const;
QVector<modelRealTerminalData> modelRealTerminalDataForIndex(QModelIndexList index_list) const;
modelRealTerminalData modelRealTerminalDataForIndex(const QModelIndex &index) const;
bool isXrefCell(const QModelIndex &index, Element **element = nullptr);
QVector<PhysicalTerminalData> physicalTerminalDataForIndex(QModelIndexList index_list) const;
QVector<RealTerminalData> realTerminalDataForIndex(QModelIndexList index_list) const;
void buildBridgePixmap(const QSize &pixmap_size);
private:
void fillPhysicalTerminalData();
RealTerminalData dataAtRow(int row) const;
void replaceDataAtRow(RealTerminalData data, int row);
PhysicalTerminalData physicalDataAtIndex(int index) const;
RealTerminalData realDataAtIndex(int index) const;
modelRealTerminalData dataAtRow(int row) const;
void replaceDataAtRow(modelRealTerminalData data, int row);
modelPhysicalTerminalData physicalDataAtIndex(int index) const;
modelRealTerminalData realDataAtIndex(int index) const;
QPixmap bridgePixmapFor(const QModelIndex &index) const;
static modelRealTerminalData modelRealData(const QWeakPointer<RealTerminal> &real_terminal);
private:
QPointer<TerminalStrip> m_terminal_strip;
QVector<PhysicalTerminalData> m_edited_terminal_data, m_original_terminal_data;
QHash<Element *, QVector<bool>> m_modified_cell;
QHash<QPointer<Element>, QVector<bool>> m_modified_cell;
QVector<modelPhysicalTerminalData> m_physical_data;
struct BridgePixmap
{
QPixmap top_,
middle_,
bottom_,
none_;
};
QHash<QColor, BridgePixmap> m_bridges_pixmaps;
};
class TerminalStripModelDelegate : public QStyledItemDelegate
@@ -75,6 +157,8 @@ class TerminalStripModelDelegate : public QStyledItemDelegate
QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif // TERMINALSTRIPMODEL_H

View File

@@ -1,4 +1,4 @@
/*
/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
@@ -19,6 +19,7 @@
#define QETUTILS_H
#include <QMargins>
#include <QWeakPointer>
class QGraphicsItem;
@@ -30,6 +31,27 @@ namespace QETUtils
QString marginsToString(const QMargins &margins);
QMargins marginsFromString(const QString &string);
qreal graphicsHandlerSize(QGraphicsItem *item);
template <typename T>
QVector<QWeakPointer<T>> sharedVectorToWeak(const QVector<QSharedPointer<T>> &vector)
{
QVector<QWeakPointer<T>> return_vector;
for (const auto shared : vector) {
return_vector.append(shared.toWeakRef());
}
return return_vector;
}
template <typename T>
QVector<QSharedPointer<T>> weakVectorToShared(const QVector<QWeakPointer<T>> &vector)
{
QVector<QSharedPointer<T>> return_vector;
for (const auto weak : vector) {
return_vector.append(weak.toStrongRef());
}
return return_vector;
}
}
#endif // QETUTILS_H