Merge branch 'terminal_strip'

* terminal_strip:
  Several real terminal can be added to terminal strip in one shot
  Minor : avoid unnecessary multiple function call
  The free terminal properties can be edited by batch.
  Change made inside the free terminal table can be applied
  Hide/show apply/reset buttons according to current displayed widget
  Edited data of terminal strip can be applied
  Change terminal strip editor class
  Add free terminal editor widget
  Add toolbar and buttons
  Start to move terminal strip editor from QDialog to QMainWindow
  Add table widget and item model for free terminal
  Revamp code
  Improve undo command when add/move/remove terminal in/from/to terminal strip
  Revamp code.
  Revamp code, make it more simple
  Remove the real terminal uuid, and use instead the uuid of the terminal element itself
  RealTerminal is created by the TerminalElement itself
  Change relationship betwen classes RealTerminal PhysicalTerminald and TerminalElement
  QTreeWidget "terminal explorer" : improve item text
  minor : remove unused code
This commit is contained in:
joshua
2022-04-09 11:54:58 +02:00
36 changed files with 2650 additions and 1097 deletions

View File

@@ -19,6 +19,7 @@
#include "../../qetproject.h" #include "../../qetproject.h"
#include "../terminalstrip.h" #include "../terminalstrip.h"
#include "../qetgraphicsitem/element.h" #include "../qetgraphicsitem/element.h"
#include "../realterminal.h"
#include <QObject> #include <QObject>
@@ -57,9 +58,13 @@ RemoveTerminalStripCommand::RemoveTerminalStripCommand(TerminalStrip *strip,
QUndoCommand *parent) : QUndoCommand *parent) :
QUndoCommand(parent), QUndoCommand(parent),
m_strip(strip), m_strip(strip),
m_project(project), m_project(project)
m_elements(strip->terminalElement())
{ {
for (const auto &real_t : strip->realTerminals())
{
if (real_t->element())
m_elements.append(real_t->element());
}
setText(QObject::tr("Supprimer un groupe de bornes")); setText(QObject::tr("Supprimer un groupe de bornes"));
} }

View File

@@ -17,6 +17,8 @@
*/ */
#include "addterminaltostripcommand.h" #include "addterminaltostripcommand.h"
#include "../../qetgraphicsitem/terminalelement.h" #include "../../qetgraphicsitem/terminalelement.h"
#include "../realterminal.h"
#include "../physicalterminal.h"
/** /**
* @brief AddTerminalToStripCommand::AddTerminalToStripCommand * @brief AddTerminalToStripCommand::AddTerminalToStripCommand
@@ -25,13 +27,12 @@
* @param strip : terminal strip where terminal must be added * @param strip : terminal strip where terminal must be added
* @param parent : parent undo command * @param parent : parent undo command
*/ */
AddTerminalToStripCommand::AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *strip, QUndoCommand *parent) : AddTerminalToStripCommand::AddTerminalToStripCommand(QSharedPointer<RealTerminal> terminal, TerminalStrip *strip, QUndoCommand *parent) :
QUndoCommand(parent), QUndoCommand(parent),
m_terminal(terminal), m_terminal(terminal),
m_new_strip(strip), m_new_strip(strip)
m_operation(Operation::add)
{ {
auto t_label = terminal->actualLabel(); auto t_label = terminal->label();
auto ts_name = strip->name(); auto ts_name = strip->name();
auto str_1 = t_label.isEmpty() ? QObject::tr("Ajouter une borne") : auto str_1 = t_label.isEmpty() ? QObject::tr("Ajouter une borne") :
@@ -43,37 +44,6 @@ AddTerminalToStripCommand::AddTerminalToStripCommand(TerminalElement *terminal,
setText(str_1 + " " + str_2); setText(str_1 + " " + str_2);
} }
/**
* @brief AddTerminalToStripCommand::AddTerminalToStripCommand
* Move \p terminal from \p old_strip to \p new_strip
* @param terminal : terminal to move
* @param old_strip : terminal where start the move
* @param new_strip : terminal where finish the move
* @param parent : parent undo command
*/
AddTerminalToStripCommand::AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *old_strip,
TerminalStrip *new_strip, QUndoCommand *parent) :
QUndoCommand(parent),
m_terminal(terminal),
m_old_strip(old_strip),
m_new_strip(new_strip),
m_operation(Operation::move)
{
auto t_label = terminal->actualLabel();
auto old_ts_name = old_strip->name();
auto new_ts_name = new_strip->name();
auto str_1 = t_label.isEmpty() ? QObject::tr("Déplacer une borne") :
QObject::tr("Déplacer la borne %1").arg(t_label);
auto str_2 = old_ts_name.isEmpty() ? QObject::tr("d'un groupe de bornes") :
QObject::tr("du groupe de bornes %1").arg(old_ts_name);
auto str_3 = new_ts_name.isEmpty() ? QObject::tr("à un autre groupe de bornes") :
QObject::tr("au groupe de bornes %1").arg(new_ts_name);
setText(str_1 + " " + str_2 + " " + str_3);
}
AddTerminalToStripCommand::~AddTerminalToStripCommand() AddTerminalToStripCommand::~AddTerminalToStripCommand()
{} {}
@@ -88,13 +58,7 @@ void AddTerminalToStripCommand::undo()
!m_new_strip) { !m_new_strip) {
return; return;
} }
m_new_strip->removeTerminal(m_terminal); m_new_strip->removeTerminal(m_terminal);
if ( m_operation == Operation::move &&
m_old_strip) {
m_old_strip->addTerminal(m_terminal);
}
} }
/** /**
@@ -107,12 +71,6 @@ void AddTerminalToStripCommand::redo()
!m_new_strip) { !m_new_strip) {
return; return;
} }
if (m_operation == Operation::move &&
m_old_strip) {
m_old_strip->removeTerminal(m_terminal);
}
m_new_strip->addTerminal(m_terminal); m_new_strip->addTerminal(m_terminal);
} }
@@ -122,14 +80,20 @@ void AddTerminalToStripCommand::redo()
* @param strip * @param strip
* @param parent * @param parent
*/ */
RemoveTerminalFromStripCommand::RemoveTerminalFromStripCommand(TerminalElement *terminal, RemoveTerminalFromStripCommand::RemoveTerminalFromStripCommand(QSharedPointer<PhysicalTerminal> terminal,
TerminalStrip *strip, TerminalStrip *strip,
QUndoCommand *parent) : QUndoCommand *parent) :
QUndoCommand(parent), QUndoCommand(parent),
m_terminal(terminal), m_terminals(terminal->realTerminals()),
m_strip(strip) m_strip(strip)
{ {
auto t_label = terminal->actualLabel(); QString t_label;
for (const auto &real_t : m_terminals) {
if (!t_label.isEmpty())
t_label.append(", ");
t_label.append(real_t->label());
}
auto strip_name = strip->name(); auto strip_name = strip->name();
auto str_1 = t_label.isEmpty() ? QObject::tr("Enlever une borne") : auto str_1 = t_label.isEmpty() ? QObject::tr("Enlever une borne") :
@@ -142,15 +106,85 @@ RemoveTerminalFromStripCommand::RemoveTerminalFromStripCommand(TerminalElement *
void RemoveTerminalFromStripCommand::undo() void RemoveTerminalFromStripCommand::undo()
{ {
if (m_terminal && m_strip) { if (m_strip)
m_strip->addTerminal(m_terminal); {
for (const auto &real_t : m_terminals) {
m_strip->addTerminal(real_t);
}
auto phy_t = m_terminals.first()->physicalTerminal();
if (phy_t) {
m_strip->groupTerminals(phy_t, m_terminals);
}
} }
} }
void RemoveTerminalFromStripCommand::redo() void RemoveTerminalFromStripCommand::redo()
{ {
if (m_terminal && m_strip) { if (m_strip)
m_strip->removeTerminal(m_terminal); {
for (const auto & real_t : m_terminals) {
m_strip->removeTerminal(real_t);
}
} }
} }
/**
* @brief MoveTerminalCommand::MoveTerminalCommand
* @param terminal
* @param old_strip
* @param new_strip
* @param parent
*/
MoveTerminalCommand::MoveTerminalCommand(QSharedPointer<PhysicalTerminal> terminal, TerminalStrip *old_strip,
TerminalStrip *new_strip, QUndoCommand *parent) :
QUndoCommand (parent),
m_terminal(terminal),
m_old_strip(old_strip),
m_new_strip(new_strip)
{
QString t_label;
for (auto real_t : terminal->realTerminals()) {
if (!t_label.isEmpty())
t_label.append(", ");
t_label.append(real_t->label());
}
auto strip_name = old_strip->name();
auto new_strip_name = new_strip->name();
auto str_1 = t_label.isEmpty() ? QObject::tr("Déplacer une borne") :
QObject::tr("Déplacer la borne %1").arg(t_label);
auto str_2 = strip_name.isEmpty() ? QObject::tr(" d'un groupe de bornes") :
QObject::tr(" du groupe de bornes %1").arg(strip_name);
auto str_3 = new_strip_name.isEmpty() ? QObject::tr("vers un groupe de bornes") :
QObject::tr("vers le groupe de bornes %1").arg(new_strip_name);
setText(str_1 + " " + str_2 + " " + str_3);
}
void MoveTerminalCommand::undo()
{
if (m_terminal)
{
if (m_new_strip) {
m_new_strip->removeTerminal(m_terminal);
}
if (m_old_strip) {
m_old_strip->addTerminal(m_terminal);
}
}
}
void MoveTerminalCommand::redo()
{
if (m_terminal)
{
if (m_old_strip) {
m_old_strip->removeTerminal(m_terminal);
}
if (m_new_strip) {
m_new_strip->addTerminal(m_terminal);
}
}
}

View File

@@ -23,6 +23,8 @@
class TerminalElement; class TerminalElement;
class TerminalStrip; class TerminalStrip;
class RealTerminal;
class PhysicalTerminal;
/** /**
* @brief The AddTerminalToStripCommand class * @brief The AddTerminalToStripCommand class
@@ -34,27 +36,15 @@ class TerminalStrip;
class AddTerminalToStripCommand : public QUndoCommand class AddTerminalToStripCommand : public QUndoCommand
{ {
public: public:
AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr); AddTerminalToStripCommand(QSharedPointer<RealTerminal> terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr);
AddTerminalToStripCommand(TerminalElement *terminal, TerminalStrip *old_strip,
TerminalStrip *new_strip, QUndoCommand *parent = nullptr);
~AddTerminalToStripCommand() override; ~AddTerminalToStripCommand() override;
void undo() override; void undo() override;
void redo() override; void redo() override;
private: private:
enum Operation{ QSharedPointer<RealTerminal> m_terminal;
none,
add,
move,
};
QPointer<TerminalElement> m_terminal;
QPointer<TerminalStrip> m_old_strip;
QPointer<TerminalStrip> m_new_strip; QPointer<TerminalStrip> m_new_strip;
Operation m_operation = Operation::none;
}; };
/** /**
@@ -65,15 +55,30 @@ class AddTerminalToStripCommand : public QUndoCommand
class RemoveTerminalFromStripCommand : public QUndoCommand class RemoveTerminalFromStripCommand : public QUndoCommand
{ {
public: public:
RemoveTerminalFromStripCommand (TerminalElement *terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr); RemoveTerminalFromStripCommand (QSharedPointer<PhysicalTerminal> terminal, TerminalStrip *strip, QUndoCommand *parent = nullptr);
~RemoveTerminalFromStripCommand() override {} ~RemoveTerminalFromStripCommand() override {}
void undo() override; void undo() override;
void redo() override; void redo() override;
private: private:
QPointer<TerminalElement> m_terminal; QVector<QSharedPointer<RealTerminal>> m_terminals;
QPointer<TerminalStrip> m_strip; QPointer<TerminalStrip> m_strip;
}; };
class MoveTerminalCommand : public QUndoCommand
{
public:
MoveTerminalCommand (QSharedPointer<PhysicalTerminal> terminal, TerminalStrip *old_strip,
TerminalStrip *new_strip, QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
private:
const QSharedPointer<PhysicalTerminal> m_terminal;
QPointer<TerminalStrip> m_old_strip, m_new_strip;
};
#endif // ADDTERMINALTOSTRIPCOMMAND_H #endif // ADDTERMINALTOSTRIPCOMMAND_H

View File

@@ -17,6 +17,7 @@
*/ */
#include "groupterminalscommand.h" #include "groupterminalscommand.h"
#include "../physicalterminal.h" #include "../physicalterminal.h"
#include "../realterminal.h"
/** /**
* @brief GroupTerminalsCommand::GroupTerminalsCommand * @brief GroupTerminalsCommand::GroupTerminalsCommand
@@ -87,8 +88,7 @@ void UnGroupTerminalsCommand::setUp(const QVector<QSharedPointer<RealTerminal>>
{ {
for (const auto &rt_ : to_ungroup) for (const auto &rt_ : to_ungroup)
{ {
auto phy_t = m_terminal_strip->physicalTerminal(rt_); if (auto phy_t = rt_->physicalTerminal())
if (phy_t)
{ {
//Physical have only one real terminal, no need to ungroup it //Physical have only one real terminal, no need to ungroup it
if (phy_t->realTerminalCount() <= 1) { if (phy_t->realTerminalCount() <= 1) {

View File

@@ -30,7 +30,13 @@ PhysicalTerminal::PhysicalTerminal(TerminalStrip *parent_strip,
QVector<QSharedPointer<RealTerminal>> terminals) : QVector<QSharedPointer<RealTerminal>> terminals) :
m_parent_terminal_strip(parent_strip), m_parent_terminal_strip(parent_strip),
m_real_terminal(terminals) m_real_terminal(terminals)
{} {
for (const auto &real_t : m_real_terminal) {
if (real_t) {
real_t->setPhysicalTerminal(sharedRef());
}
}
}
/** /**
* @brief PhysicalTerminal::sharedRef * @brief PhysicalTerminal::sharedRef
@@ -80,6 +86,11 @@ QDomElement PhysicalTerminal::toXml(QDomDocument &parent_document) const
*/ */
void PhysicalTerminal::setTerminals(const QVector<QSharedPointer<RealTerminal>> &terminals) { void PhysicalTerminal::setTerminals(const QVector<QSharedPointer<RealTerminal>> &terminals) {
m_real_terminal = terminals; m_real_terminal = terminals;
for (const auto &real_t : m_real_terminal) {
if (real_t) {
real_t->setPhysicalTerminal(sharedRef());
}
}
} }
/** /**
@@ -90,6 +101,7 @@ void PhysicalTerminal::setTerminals(const QVector<QSharedPointer<RealTerminal>>
*/ */
void PhysicalTerminal::addTerminal(const QSharedPointer<RealTerminal> &terminal) { void PhysicalTerminal::addTerminal(const QSharedPointer<RealTerminal> &terminal) {
m_real_terminal.append(terminal); m_real_terminal.append(terminal);
terminal->setPhysicalTerminal(sharedRef());
} }
/** /**
@@ -98,8 +110,13 @@ void PhysicalTerminal::addTerminal(const QSharedPointer<RealTerminal> &terminal)
* @param terminal * @param terminal
* @return true if sucessfully removed * @return true if sucessfully removed
*/ */
bool PhysicalTerminal::removeTerminal(const QSharedPointer<RealTerminal> &terminal) { bool PhysicalTerminal::removeTerminal(const QSharedPointer<RealTerminal> &terminal)
return m_real_terminal.removeOne(terminal); {
if (m_real_terminal.removeOne(terminal)) {
terminal->setPhysicalTerminal(QSharedPointer<PhysicalTerminal>());
return true;
}
return false;
} }
/** /**
@@ -124,6 +141,28 @@ bool PhysicalTerminal::setLevelOf(const QSharedPointer<RealTerminal> &terminal,
return false; return false;
} }
void PhysicalTerminal::setParentStrip(TerminalStrip *strip)
{
m_parent_terminal_strip = strip;
}
PhysicalTerminal::~PhysicalTerminal()
{
for (const auto &real_t : m_real_terminal) {
if (real_t) {
real_t->setPhysicalTerminal(QSharedPointer<PhysicalTerminal>());
}
}
}
/**
* @brief PhysicalTerminal::terminalStrip
* @return The parent terminal strip ornullptr
*/
TerminalStrip *PhysicalTerminal::terminalStrip() const {
return m_parent_terminal_strip.data();
}
/** /**
* @brief levelCount * @brief levelCount
* @return the number of level of this terminal * @return the number of level of this terminal

View File

@@ -61,6 +61,7 @@ class TerminalStrip;
class PhysicalTerminal class PhysicalTerminal
{ {
friend class TerminalStrip; friend class TerminalStrip;
friend class RealTerminal;
private: private:
PhysicalTerminal(TerminalStrip *parent_strip, QVector<QSharedPointer<RealTerminal>> terminals); PhysicalTerminal(TerminalStrip *parent_strip, QVector<QSharedPointer<RealTerminal>> terminals);
@@ -75,9 +76,13 @@ class PhysicalTerminal
bool setLevelOf(const QSharedPointer<RealTerminal> &terminal, int level); bool setLevelOf(const QSharedPointer<RealTerminal> &terminal, int level);
void setParentStrip(TerminalStrip *strip);
public: public:
PhysicalTerminal(){} PhysicalTerminal(){}
~PhysicalTerminal();
TerminalStrip* terminalStrip() const;
int levelCount() const; int levelCount() const;
int levelOf(const QSharedPointer<RealTerminal> &terminal) const; int levelOf(const QSharedPointer<RealTerminal> &terminal) const;
QVector<QSharedPointer<RealTerminal>> realTerminals() const; QVector<QSharedPointer<RealTerminal>> realTerminals() const;

View File

@@ -25,12 +25,17 @@
* @param parent_strip : parent terminal strip * @param parent_strip : parent terminal strip
* @param terminal : terminal element (if any) in a folio * @param terminal : terminal element (if any) in a folio
*/ */
RealTerminal::RealTerminal(TerminalStrip *parent_strip, RealTerminal::RealTerminal(Element *terminal) :
Element *terminal) : m_element(terminal)
m_element(terminal),
m_parent_terminal_strip(parent_strip)
{} {}
RealTerminal::~RealTerminal()
{
if (m_physical_terminal) {
m_physical_terminal->removeTerminal(sharedRef());
}
}
/** /**
* @brief RealTerminal::sharedRef * @brief RealTerminal::sharedRef
* @return a QSharedPointer of this * @return a QSharedPointer of this
@@ -47,6 +52,16 @@ QSharedPointer<RealTerminal> RealTerminal::sharedRef()
return this_shared; return this_shared;
} }
/**
* @brief RealTerminal::sharedRef
* @return a shared reference of this, not that because
* this method is const, the shared reference can be null if not already
* used in another part of the code.
*/
QSharedPointer<RealTerminal> RealTerminal::sharedRef() const {
return QSharedPointer<RealTerminal>(m_this_weak);
}
/** /**
* @brief RealTerminal::weakRef * @brief RealTerminal::weakRef
* @return a QWeakPointer of this, weak pointer can be bull * @return a QWeakPointer of this, weak pointer can be bull
@@ -55,35 +70,6 @@ QWeakPointer<RealTerminal> RealTerminal::weakRef() {
return m_this_weak; 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;
}
m_uuid = QUuid(xml_element.attribute(QStringLiteral("uuid")));
if (xml_element.hasAttribute(QStringLiteral("element_uuid")))
{
QUuid uuid_(xml_element.attribute(QStringLiteral("element_uuid")));
for (auto terminal : terminal_vector) {
if (terminal->uuid() == uuid_)
{
m_element = terminal;
break;
}
}
}
return true;
}
/** /**
* @brief toXml * @brief toXml
* @param parent_document * @param parent_document
@@ -92,7 +78,6 @@ bool RealTerminal::fromXml(QDomElement xml_element, const QVector<TerminalElemen
QDomElement RealTerminal::toXml(QDomDocument &parent_document) const QDomElement RealTerminal::toXml(QDomDocument &parent_document) const
{ {
auto root_elmt = parent_document.createElement(this->xmlTagName()); auto root_elmt = parent_document.createElement(this->xmlTagName());
root_elmt.setAttribute(QStringLiteral("uuid"), m_uuid.toString());
if (m_element) if (m_element)
root_elmt.setAttribute(QStringLiteral("element_uuid"), m_element->uuid().toString()); root_elmt.setAttribute(QStringLiteral("element_uuid"), m_element->uuid().toString());
@@ -100,11 +85,33 @@ QDomElement RealTerminal::toXml(QDomDocument &parent_document) const
} }
/** /**
* @brief parentStrip * @brief RealTerminal::setPhysicalTerminal
* @return parent terminal strip * Set the parent physical terminal of this real terminal
*/ * @param phy_t
TerminalStrip *RealTerminal::parentStrip() const { */
return m_parent_terminal_strip.data(); void RealTerminal::setPhysicalTerminal(const QSharedPointer<PhysicalTerminal> &phy_t) {
m_physical_terminal = phy_t;
}
/**
* @brief parentStrip
* @return parent terminal strip or nullptr
*/
TerminalStrip *RealTerminal::parentStrip() const noexcept {
if (m_physical_terminal) {
return m_physical_terminal->terminalStrip();
} else {
return nullptr;
}
}
/**
* @brief RealTerminal::physicalTerminal
* @return The parent physical terminal of this terminal.
* The returned QSharedPointer can be null
*/
QSharedPointer<PhysicalTerminal> RealTerminal::physicalTerminal() const noexcept{
return m_physical_terminal;
} }
/** /**
@@ -113,11 +120,9 @@ TerminalStrip *RealTerminal::parentStrip() const {
*/ */
int RealTerminal::level() const int RealTerminal::level() const
{ {
if (m_parent_terminal_strip) { if (m_physical_terminal &&
const auto phy_t = m_parent_terminal_strip->physicalTerminal(m_this_weak); sharedRef()) {
if (phy_t) { return m_physical_terminal->levelOf(sharedRef());
return phy_t->levelOf(m_this_weak);
}
} }
return -1; return -1;
@@ -224,8 +229,8 @@ bool RealTerminal::isElement() const {
*/ */
bool RealTerminal::isBridged() const bool RealTerminal::isBridged() const
{ {
if (m_parent_terminal_strip) { if (parentStrip()) {
return !m_parent_terminal_strip->isBridged(m_this_weak.toStrongRef()).isNull(); return !parentStrip()->isBridged(m_this_weak.toStrongRef()).isNull();
} else { } else {
return false; return false;
} }
@@ -237,8 +242,8 @@ bool RealTerminal::isBridged() const
*/ */
QSharedPointer<TerminalStripBridge> RealTerminal::bridge() const QSharedPointer<TerminalStripBridge> RealTerminal::bridge() const
{ {
if (m_parent_terminal_strip) { if (parentStrip()) {
return m_parent_terminal_strip->isBridged(m_this_weak.toStrongRef()); return parentStrip()->isBridged(m_this_weak.toStrongRef());
} else { } else {
return QSharedPointer<TerminalStripBridge>(); return QSharedPointer<TerminalStripBridge>();
} }
@@ -267,14 +272,6 @@ QUuid RealTerminal::elementUuid() const {
} }
} }
/**
* @brief uuid
* @return the uuid of this real terminal
*/
QUuid RealTerminal::uuid() const {
return m_uuid;
}
/** /**
* @brief RealTerminal::RealTerminal::xmlTagName * @brief RealTerminal::RealTerminal::xmlTagName
* @return * @return

View File

@@ -41,19 +41,25 @@ class TerminalStripBridge;
*/ */
class RealTerminal class RealTerminal
{ {
friend class TerminalStrip; friend class TerminalElement;
friend class PhysicalTerminal; friend class PhysicalTerminal;
private: private:
RealTerminal(TerminalStrip *strip, Element *element = nullptr); RealTerminal(Element *element);
QSharedPointer<RealTerminal> sharedRef(); QSharedPointer<RealTerminal> sharedRef();
QSharedPointer<RealTerminal> sharedRef() const;
QWeakPointer<RealTerminal> weakRef(); QWeakPointer<RealTerminal> weakRef();
bool fromXml(QDomElement xml_element, const QVector<TerminalElement *> &terminal_vector); void setPhysicalTerminal(const QSharedPointer<PhysicalTerminal> &phy_t);
QDomElement toXml(QDomDocument &parent_document) const;
public: public:
TerminalStrip *parentStrip() const; ~RealTerminal();
TerminalStrip *parentStrip() const noexcept;
QSharedPointer<PhysicalTerminal> physicalTerminal() const noexcept;
QDomElement toXml(QDomDocument &parent_document) const;
int level() const; int level() const;
QString label() const; QString label() const;
QString Xref() const; QString Xref() const;
@@ -72,15 +78,13 @@ class RealTerminal
Element* element() const; Element* element() const;
QUuid elementUuid() const; QUuid elementUuid() const;
QUuid uuid() const;
static QString xmlTagName(); static QString xmlTagName();
private : private :
QPointer<Element> m_element; QPointer<Element> m_element;
QPointer<TerminalStrip> m_parent_terminal_strip;
QUuid m_uuid = QUuid::createUuid();
QWeakPointer<RealTerminal> m_this_weak; QWeakPointer<RealTerminal> m_this_weak;
QSharedPointer<PhysicalTerminal> m_physical_terminal;
}; };
#endif // REALTERMINAL_H #endif // REALTERMINAL_H

View File

@@ -94,6 +94,49 @@ void TerminalStrip::setData(const TerminalStripData &data) {
m_data = data; m_data = data;
} }
bool TerminalStrip::addTerminal(QSharedPointer<RealTerminal> real_t)
{
//Check if terminal is already owned by a strip
//return if this strip or false if another strip
if (real_t->parentStrip()) {
if (real_t->parentStrip() != this)
return false;
else
return true;
}
//Create a new single level physical terminal
auto raw_phy_ptr = new PhysicalTerminal(this, QVector<QSharedPointer<RealTerminal>>{real_t});
m_physical_terminals.append(raw_phy_ptr->sharedRef());
emit orderChanged();
return true;
}
bool TerminalStrip::removeTerminal(QSharedPointer<RealTerminal> real_t)
{
if (real_t->parentStrip() != this) {
return false;
}
if (auto bridge_ = real_t->bridge()) {
bridge_->removeTerminal(real_t);
}
if (auto phy_t = real_t->physicalTerminal())
{
phy_t->removeTerminal(real_t);
if (phy_t->realTerminalCount() == 0) {
m_physical_terminals.removeOne(phy_t);
}
emit orderChanged();
return true;
}
return false;
}
/** /**
* @brief TerminalStrip::addTerminal * @brief TerminalStrip::addTerminal
* Add terminal to this terminal strip * Add terminal to this terminal strip
@@ -104,26 +147,22 @@ void TerminalStrip::setData(const TerminalStripData &data) {
*/ */
bool TerminalStrip::addTerminal(Element *terminal) bool TerminalStrip::addTerminal(Element *terminal)
{ {
if (m_terminal_elements_vector.contains(terminal)) { for (const auto &real_t : realTerminals()) {
return false; if (real_t->element() == terminal) {
return false;
}
} }
if (terminal->elementData().m_type != ElementData::Terminale) { if (terminal->elementData().m_type != ElementData::Terminale) {
return false; return false;
} }
m_terminal_elements_vector.append(terminal); auto casted_ = static_cast<TerminalElement *>(terminal);
//Create the real terminal
auto raw_real_ptr = new RealTerminal(this, terminal);
auto real_terminal = raw_real_ptr->sharedRef();
m_real_terminals.append(real_terminal);
//Create a new single level physical terminal //Create a new single level physical terminal
auto raw_phy_ptr = new PhysicalTerminal(this, QVector<QSharedPointer<RealTerminal>>{real_terminal}); auto raw_phy_ptr = new PhysicalTerminal(this, QVector<QSharedPointer<RealTerminal>>{casted_->realTerminal()});
m_physical_terminals.append(raw_phy_ptr->sharedRef()); m_physical_terminals.append(raw_phy_ptr->sharedRef());
static_cast<TerminalElement *>(terminal)->setParentTerminalStrip(this);
return true; return true;
} }
@@ -135,33 +174,71 @@ bool TerminalStrip::addTerminal(Element *terminal)
*/ */
bool TerminalStrip::removeTerminal(Element *terminal) bool TerminalStrip::removeTerminal(Element *terminal)
{ {
if (m_terminal_elements_vector.contains(terminal)) for (const auto &real_t : realTerminals())
{ {
m_terminal_elements_vector.removeOne(terminal); if (real_t->element() == terminal)
//Get the real and physical terminal associated to @terminal
if (auto real_terminal = realTerminal(terminal))
{ {
if (auto physical_terminal = physicalTerminal(real_terminal)) if (auto physical_t = real_t->physicalTerminal())
{ {
if (physical_terminal->levelCount() == 1) { physical_t->removeTerminal(real_t);
m_physical_terminals.removeOne(physical_terminal); if (physical_t->realTerminalCount() == 0) {
} else { m_physical_terminals.removeOne(physical_t);
auto v = physical_terminal->realTerminals();
v.removeOne(real_terminal);
physical_terminal->setTerminals(v);
} }
} }
m_real_terminals.removeOne(real_terminal);
static_cast<TerminalElement *>(terminal)->setParentTerminalStrip(nullptr);
rebuildRealVector();
return true; return true;
} }
//There is no reason to be here, but in case of....
return false;
} }
return false;
}
/**
* @brief TerminalStrip::addTerminal
* Add @a phy_t in this terminal strip.
* @param phy_t
* @return true if successfully added. A terminal can't be added is already
* belong to another terminal strip.
*/
bool TerminalStrip::addTerminal(QSharedPointer<PhysicalTerminal> phy_t)
{
if (phy_t->terminalStrip()) {
if (phy_t->terminalStrip() == this)
return true;
else
return false;
}
m_physical_terminals.append(phy_t);
phy_t->setParentStrip(this);
emit orderChanged();
return true;
}
/**
* @brief TerminalStrip::removeTerminal
* Remove @a phy_t from this terminal strip.
* @param phy_t
* @return true if successfully removed. Return false if can't be removed
* because not owned by this strip
*/
bool TerminalStrip::removeTerminal(QSharedPointer<PhysicalTerminal> phy_t)
{
if (m_physical_terminals.removeOne(phy_t))
{
for (const auto &real_t : phy_t->realTerminals()) {
if (auto bridge_ = real_t->bridge()) {
bridge_->removeTerminal(real_t);
}
}
phy_t->setParentStrip(nullptr);
emit orderChanged();
return true;
}
return false; return false;
} }
@@ -201,20 +278,17 @@ QSharedPointer<PhysicalTerminal> TerminalStrip::physicalTerminal(int index) cons
} }
/** /**
* @brief TerminalStrip::physicalTerminalData * @brief TerminalStrip::physicalTerminal
* @param real_terminal * @param uuid
* @return the parent PhysicalTerminal of \p real_terminal. * @return the the physicalTerminal with the uuid @a uuid or a empty
* the PhysicalTerminal can be null if \p real_terminal don't belong to this strip * QSharedPointer if empty.
*/ */
QSharedPointer<PhysicalTerminal> TerminalStrip::physicalTerminal (const QSharedPointer<RealTerminal> &real_terminal) const QSharedPointer<PhysicalTerminal> TerminalStrip::physicalTerminal(const QUuid &uuid) const
{ {
if (real_terminal.isNull()) { for (const auto &phy_t : m_physical_terminals)
return QSharedPointer<PhysicalTerminal>(); {
} if (phy_t->uuid() == uuid) {
return phy_t;
for (auto &physical : qAsConst(m_physical_terminals)) {
if (physical->realTerminals().contains(real_terminal)) {
return physical;
} }
} }
@@ -230,23 +304,6 @@ QVector<QSharedPointer<PhysicalTerminal>> TerminalStrip::physicalTerminal() cons
return m_physical_terminals; return m_physical_terminals;
} }
/**
* @brief TerminalStrip::realTerminal
* @param terminal
* @return the real terminal linked to \p terminal
* the returned QSharedPointer can be null.
*/
QSharedPointer<RealTerminal> TerminalStrip::realTerminal(Element *terminal) const
{
for (const auto &real : qAsConst(m_real_terminals)) {
if (real->element() == terminal) {
return real;
}
}
return shared_real_terminal();
}
/** /**
* @brief TerminalStrip::realTerminalForUuid * @brief TerminalStrip::realTerminalForUuid
* @param uuid * @param uuid
@@ -254,8 +311,8 @@ QSharedPointer<RealTerminal> TerminalStrip::realTerminal(Element *terminal) cons
*/ */
QSharedPointer<RealTerminal> TerminalStrip::realTerminalForUuid(const QUuid &uuid) const QSharedPointer<RealTerminal> TerminalStrip::realTerminalForUuid(const QUuid &uuid) const
{ {
for (const auto &t : qAsConst(m_real_terminals)) { for (const auto &t : realTerminals()) {
if (t->uuid() == uuid) { if (t->elementUuid() == uuid) {
return t; return t;
} }
} }
@@ -263,6 +320,19 @@ QSharedPointer<RealTerminal> TerminalStrip::realTerminalForUuid(const QUuid &uui
return QSharedPointer<RealTerminal>(); return QSharedPointer<RealTerminal>();
} }
/**
* @brief TerminalStrip::realTerminals
* @return All real terminal owned by this strip
*/
QVector<QSharedPointer<RealTerminal>> TerminalStrip::realTerminals() const
{
QVector<QSharedPointer<RealTerminal>> vector_;
for (const auto &phy : qAsConst(m_physical_terminals)) {
vector_.append(phy->realTerminals());
}
return vector_;
}
/** /**
* @brief TerminalStrip::setSortedTo * @brief TerminalStrip::setSortedTo
@@ -299,7 +369,6 @@ bool TerminalStrip::setOrderTo(const QVector<QSharedPointer<PhysicalTerminal>> &
} }
m_physical_terminals = new_order; m_physical_terminals = new_order;
rebuildRealVector();
emit orderChanged(); emit orderChanged();
return true; return true;
} }
@@ -329,9 +398,9 @@ bool TerminalStrip::groupTerminals(const QSharedPointer<PhysicalTerminal> &recei
continue; continue;
} }
auto physical_ = physicalTerminal(added_terminal); if (auto phy_t = added_terminal->physicalTerminal()) {
physical_->removeTerminal(added_terminal); phy_t->removeTerminal(added_terminal);
}
receiver_terminal->addTerminal(added_terminal); receiver_terminal->addTerminal(added_terminal);
have_grouped = true; have_grouped = true;
} }
@@ -345,7 +414,6 @@ bool TerminalStrip::groupTerminals(const QSharedPointer<PhysicalTerminal> &recei
} }
} }
rebuildRealVector();
emit orderChanged(); emit orderChanged();
} }
return true; return true;
@@ -363,7 +431,7 @@ void TerminalStrip::unGroupTerminals(const QVector<QSharedPointer<RealTerminal>>
{ {
if (real_terminal) if (real_terminal)
{ {
if (auto physical_terminal = physicalTerminal(real_terminal)) //Get the physical terminal if (auto physical_terminal = real_terminal->physicalTerminal()) //Get the physical terminal
{ {
if (physical_terminal->realTerminals().size() > 1) //Check if physical have more than one real terminal if (physical_terminal->realTerminals().size() > 1) //Check if physical have more than one real terminal
{ {
@@ -377,7 +445,6 @@ void TerminalStrip::unGroupTerminals(const QVector<QSharedPointer<RealTerminal>>
} }
if (ungrouped) { if (ungrouped) {
rebuildRealVector();
emit orderChanged(); emit orderChanged();
} }
} }
@@ -392,13 +459,11 @@ bool TerminalStrip::setLevel(const QSharedPointer<RealTerminal> &real_terminal,
{ {
if (real_terminal) if (real_terminal)
{ {
auto physical_terminal = physicalTerminal(real_terminal); if (auto physical_terminal = real_terminal->physicalTerminal())
if (physical_terminal)
{ {
if (physical_terminal->realTerminals().size() > 1 && if (physical_terminal->realTerminals().size() > 1 &&
physical_terminal->setLevelOf(real_terminal, level)) physical_terminal->setLevelOf(real_terminal, level))
{ {
rebuildRealVector();
emit orderChanged(); emit orderChanged();
return true; return true;
} }
@@ -433,7 +498,7 @@ bool TerminalStrip::isBridgeable(const QVector<QSharedPointer<RealTerminal>> &re
const int level_ = first_real_terminal->level(); const int level_ = first_real_terminal->level();
// Get the physical terminal and pos // Get the physical terminal and pos
auto first_physical_terminal = physicalTerminal(first_real_terminal); auto first_physical_terminal = first_real_terminal->physicalTerminal();
QVector<shared_physical_terminal> physical_vector{first_physical_terminal}; QVector<shared_physical_terminal> physical_vector{first_physical_terminal};
QVector<int> pos_vector{m_physical_terminals.indexOf(first_physical_terminal)}; QVector<int> pos_vector{m_physical_terminals.indexOf(first_physical_terminal)};
@@ -456,7 +521,7 @@ bool TerminalStrip::isBridgeable(const QVector<QSharedPointer<RealTerminal>> &re
} }
// Not to the same physical terminal of a previous checked real terminal // Not to the same physical terminal of a previous checked real terminal
const auto physical_terminal = physicalTerminal(real_terminal); const auto physical_terminal = real_terminal->physicalTerminal();
if (physical_vector.contains(physical_terminal)) { if (physical_vector.contains(physical_terminal)) {
return false; return false;
} else { } else {
@@ -604,7 +669,7 @@ bool TerminalStrip::canUnBridge(const QVector<QSharedPointer<RealTerminal> > &re
if (compar_bridge != isBridged(real_t)) { if (compar_bridge != isBridged(real_t)) {
return false; return false;
} else { } else {
sorted_terminal.insert(m_physical_terminals.indexOf(physicalTerminal(real_t)), sorted_terminal.insert(m_physical_terminals.indexOf(real_t->physicalTerminal()),
real_t); real_t);
} }
} }
@@ -698,7 +763,7 @@ QSharedPointer<TerminalStripBridge> TerminalStrip::bridgeFor(const QVector<QShar
*/ */
QSharedPointer<RealTerminal> TerminalStrip::previousTerminalInLevel(const QSharedPointer<RealTerminal> &real_terminal) const QSharedPointer<RealTerminal> TerminalStrip::previousTerminalInLevel(const QSharedPointer<RealTerminal> &real_terminal) const
{ {
const auto phy_t = physicalTerminal(real_terminal); const auto phy_t = real_terminal->physicalTerminal();
if (real_terminal && phy_t) if (real_terminal && phy_t)
{ {
const auto level_ = phy_t->levelOf(real_terminal); const auto level_ = phy_t->levelOf(real_terminal);
@@ -723,7 +788,7 @@ QSharedPointer<RealTerminal> TerminalStrip::previousTerminalInLevel(const QShare
*/ */
QSharedPointer<RealTerminal> TerminalStrip::nextTerminalInLevel(const QSharedPointer<RealTerminal> &real_terminal) const QSharedPointer<RealTerminal> TerminalStrip::nextTerminalInLevel(const QSharedPointer<RealTerminal> &real_terminal) const
{ {
const auto phy_t = physicalTerminal(real_terminal); const auto phy_t = real_terminal->physicalTerminal();
if (real_terminal && phy_t) if (real_terminal && phy_t)
{ {
const auto level_ = phy_t->levelOf(real_terminal); const auto level_ = phy_t->levelOf(real_terminal);
@@ -742,30 +807,24 @@ QSharedPointer<RealTerminal> TerminalStrip::nextTerminalInLevel(const QSharedPoi
QSharedPointer<RealTerminal> TerminalStrip::previousRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const QSharedPointer<RealTerminal> TerminalStrip::previousRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const
{ {
const auto index = m_real_terminals.indexOf(real_terminal); const auto real_t_vector = realTerminals();
const auto index = real_t_vector.indexOf(real_terminal);
if (index) { if (index) {
return m_real_terminals.at(index-1); return real_t_vector.at(index-1);
} }
return QSharedPointer<RealTerminal>(); return QSharedPointer<RealTerminal>();
} }
QSharedPointer<RealTerminal> TerminalStrip::nextRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const QSharedPointer<RealTerminal> TerminalStrip::nextRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const
{ {
const auto index = m_real_terminals.indexOf(real_terminal); const auto real_t_vector = realTerminals();
if (index != m_real_terminals.size()-1) { const auto index = real_t_vector.indexOf(real_terminal);
return m_real_terminals.at(index+1); if (index != real_t_vector.size()-1) {
return real_t_vector.at(index+1);
} }
return QSharedPointer<RealTerminal>(); return QSharedPointer<RealTerminal>();
} }
/**
* @brief TerminalStrip::terminalElement
* @return A vector of all terminal element owned by this strip
*/
QVector<QPointer<Element> > TerminalStrip::terminalElement() const {
return m_terminal_elements_vector;
}
/** /**
* @brief TerminalStrip::toXml * @brief TerminalStrip::toXml
* @param parent_document * @param parent_document
@@ -814,7 +873,7 @@ bool TerminalStrip::fromXml(QDomElement &xml_element)
{ {
//Get all free elements terminal of the project //Get all free elements terminal of the project
const ElementProvider ep(m_project); const ElementProvider ep(m_project);
const auto free_terminals = ep.freeTerminal(); auto free_terminals = ep.freeTerminal();
//Read each physical terminal //Read each physical terminal
for(auto &xml_physical : QETXML::findInDomElement(xml_layout, PhysicalTerminal::xmlTagName())) for(auto &xml_physical : QETXML::findInDomElement(xml_layout, PhysicalTerminal::xmlTagName()))
@@ -824,20 +883,22 @@ bool TerminalStrip::fromXml(QDomElement &xml_element)
//Read each real terminal of the current physical terminal of the loop //Read each real terminal of the current physical terminal of the loop
for (auto &xml_real : QETXML::findInDomElement(xml_physical, RealTerminal::xmlTagName())) for (auto &xml_real : QETXML::findInDomElement(xml_physical, RealTerminal::xmlTagName()))
{ {
auto raw_ptr = new RealTerminal(this); const auto uuid_ = QUuid(xml_real.attribute(QStringLiteral("element_uuid")));
auto real_t = raw_ptr->sharedRef(); for (auto terminal_elmt : qAsConst(free_terminals))
real_t->fromXml(xml_real, free_terminals);
if(real_t->isElement())
{ {
m_terminal_elements_vector.append(real_t->element()); if (terminal_elmt->uuid() == uuid_)
static_cast<TerminalElement*>(real_t->element())->setParentTerminalStrip(this); {
real_t_vector.append(terminal_elmt->realTerminal());
//Remove the actual terminal element from the vector, they dicrease the size
//of the vector and so each iteration have less terminal element to check
free_terminals.removeOne(terminal_elmt);
break;
}
} }
real_t_vector.append(real_t);
} }
auto raw_ptr = new PhysicalTerminal(this, real_t_vector); auto raw_ptr = new PhysicalTerminal(this, real_t_vector);
m_physical_terminals.append(raw_ptr->sharedRef()); m_physical_terminals.append(raw_ptr->sharedRef());
m_real_terminals.append(real_t_vector);
} }
} }
@@ -854,16 +915,3 @@ bool TerminalStrip::fromXml(QDomElement &xml_element)
return true; return true;
} }
/**
* @brief TerminalStrip::rebuildRealVector
* Rebuild the real terminal vector
* to be ordered
*/
void TerminalStrip::rebuildRealVector()
{
m_real_terminals.clear();
for (const auto &phy : qAsConst(m_physical_terminals)) {
m_real_terminals.append(phy->realTerminals());
}
}

View File

@@ -77,16 +77,20 @@ class TerminalStrip : public QObject
TerminalStripData data() const; TerminalStripData data() const;
void setData(const TerminalStripData &data); void setData(const TerminalStripData &data);
bool addTerminal (QSharedPointer<RealTerminal> real_t);
bool removeTerminal (QSharedPointer<RealTerminal> real_t);
bool addTerminal (Element *terminal); bool addTerminal (Element *terminal);
bool removeTerminal (Element *terminal); bool removeTerminal (Element *terminal);
bool addTerminal (QSharedPointer<PhysicalTerminal> phy_t);
bool removeTerminal(QSharedPointer<PhysicalTerminal> phy_t);
int pos(const QSharedPointer<PhysicalTerminal> &terminal) const; int pos(const QSharedPointer<PhysicalTerminal> &terminal) const;
int physicalTerminalCount() const; int physicalTerminalCount() const;
QSharedPointer<PhysicalTerminal> physicalTerminal(int index) const; QSharedPointer<PhysicalTerminal> physicalTerminal(int index) const;
QSharedPointer<PhysicalTerminal> physicalTerminal (const QSharedPointer<RealTerminal> &real_terminal) const; QSharedPointer<PhysicalTerminal> physicalTerminal(const QUuid &uuid) const;
QVector<QSharedPointer<PhysicalTerminal>> physicalTerminal() const; QVector<QSharedPointer<PhysicalTerminal>> physicalTerminal() const;
QSharedPointer<RealTerminal> realTerminal(Element *terminal) const;
QSharedPointer<RealTerminal> realTerminalForUuid(const QUuid &uuid) const; QSharedPointer<RealTerminal> realTerminalForUuid(const QUuid &uuid) const;
QVector<QSharedPointer<RealTerminal>> realTerminals() const;
bool setOrderTo(const QVector<QSharedPointer<PhysicalTerminal>> &sorted_vector); bool setOrderTo(const QVector<QSharedPointer<PhysicalTerminal>> &sorted_vector);
bool groupTerminals(const QSharedPointer<PhysicalTerminal> &receiver_terminal, const QVector<QSharedPointer<RealTerminal>> &added_terminals); bool groupTerminals(const QSharedPointer<PhysicalTerminal> &receiver_terminal, const QVector<QSharedPointer<RealTerminal>> &added_terminals);
@@ -107,20 +111,13 @@ class TerminalStrip : public QObject
QSharedPointer<RealTerminal> previousRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const; QSharedPointer<RealTerminal> previousRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const;
QSharedPointer<RealTerminal> nextRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const; QSharedPointer<RealTerminal> nextRealTerminal(const QSharedPointer<RealTerminal> &real_terminal) const;
QVector<QPointer<Element>> terminalElement() const;
static QString xmlTagName() {return QStringLiteral("terminal_strip");} static QString xmlTagName() {return QStringLiteral("terminal_strip");}
QDomElement toXml(QDomDocument &parent_document); QDomElement toXml(QDomDocument &parent_document);
bool fromXml(QDomElement &xml_element); bool fromXml(QDomElement &xml_element);
private:
void rebuildRealVector();
private: private:
TerminalStripData m_data; TerminalStripData m_data;
QPointer<QETProject> m_project; QPointer<QETProject> m_project;
QVector<QPointer<Element>> m_terminal_elements_vector;
QVector<QSharedPointer<RealTerminal>> m_real_terminals;
QVector<QSharedPointer<PhysicalTerminal>> m_physical_terminals; QVector<QSharedPointer<PhysicalTerminal>> m_physical_terminals;
QVector<QSharedPointer<TerminalStripBridge>> m_bridge; QVector<QSharedPointer<TerminalStripBridge>> m_bridge;
}; };

View File

@@ -90,7 +90,7 @@ QDomElement TerminalStripBridge::toXml(QDomDocument &parent_document) const
if (real_t) if (real_t)
{ {
auto terminal_elmt = parent_document.createElement(QStringLiteral("real_terminal")); auto terminal_elmt = parent_document.createElement(QStringLiteral("real_terminal"));
terminal_elmt.setAttribute(QStringLiteral("uuid"), real_t->uuid().toString()); terminal_elmt.setAttribute(QStringLiteral("uuid"), real_t->elementUuid().toString());
terminals_elmt.appendChild(terminal_elmt); terminals_elmt.appendChild(terminal_elmt);
} }
} }
@@ -163,3 +163,7 @@ void TerminalStripBridge::removeTerminals(const QVector<QSharedPointer<RealTermi
m_real_terminals.removeOne(real_t); m_real_terminals.removeOne(real_t);
} }
} }
void TerminalStripBridge::removeTerminal(const QSharedPointer<RealTerminal> &real_terminal) {
m_real_terminals.removeOne(real_terminal);
}

View File

@@ -50,6 +50,7 @@ class TerminalStripBridge
private: private:
bool addTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals); bool addTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals);
void removeTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals); void removeTerminals(const QVector<QSharedPointer<RealTerminal>> &real_terminals);
void removeTerminal(const QSharedPointer<RealTerminal> &real_terminal);
private: private:

View File

@@ -0,0 +1,258 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "freeterminaleditor.h"
#include "ui_freeterminaleditor.h"
#include "../undocommand/changeelementdatacommand.h"
#include "../../diagram.h"
#include "../../elementprovider.h"
#include "freeterminalmodel.h"
#include "../terminalstrip.h"
#include "../UndoCommand/addterminaltostripcommand.h"
/**
* @brief FreeTerminalEditor::FreeTerminalEditor
* @param project
* @param parent
*/
FreeTerminalEditor::FreeTerminalEditor(QETProject *project, QWidget *parent) :
QWidget(parent),
ui(new Ui::FreeTerminalEditor),
m_project(project)
{
ui->setupUi(this);
ui->m_table_view->setItemDelegate(new FreeTerminalModelDelegate(ui->m_table_view));
m_model = new FreeTerminalModel(m_project, this);
ui->m_table_view->setModel(m_model);
ui->m_table_view->setCurrentIndex(m_model->index(0,0));
//Disabled the move if the table is currently edited (yellow cell)
connect(m_model, &FreeTerminalModel::dataChanged, this, [=] {
this->setDisabledMove();
});
connect(ui->m_table_view, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
{
if (m_model->columnTypeForIndex(index) == FreeTerminalModel::XRef)
{
auto mrtd = m_model->dataAtRow(index.row());
if (mrtd.element_)
{
auto elmt = mrtd.element_;
auto diagram = elmt->diagram();
if (diagram)
{
diagram->showMe();
if (diagram->views().size())
{
auto fit_view = elmt->sceneBoundingRect();
fit_view.adjust(-200,-200,200,200);
diagram->views().at(0)->fitInView(fit_view, Qt::KeepAspectRatioByExpanding);
}
}
}
}
});
}
/**
* @brief FreeTerminalEditor::~FreeTerminalEditor
*/
FreeTerminalEditor::~FreeTerminalEditor()
{
delete ui;
}
/**
* @brief FreeTerminalEditor::reload
* Reload the editor to be up to date with
* the current state of the project.
* Every not applied change will be lost.
*/
void FreeTerminalEditor::reload()
{
m_model->clear();
ui->m_move_in_cb->clear();
if (m_project)
{
const auto strip_vector = m_project->terminalStrip();
for (const auto &strip : strip_vector)
{
QString str(strip->installation() + " " + strip->location() + " " + strip->name());
ui->m_move_in_cb->addItem(str, strip->uuid());
}
setDisabledMove(false);
}
}
/**
* @brief FreeTerminalEditor::apply
* Applu current edited values
*/
void FreeTerminalEditor::apply()
{
const auto modified_data = m_model->modifiedModelRealTerminalData();
if (modified_data.size())
{
m_project->undoStack()->beginMacro(tr("Modifier des propriétés de borniers"));
for (const auto &data_ : modified_data)
{
if (auto element_ = data_.element_)
{
auto current_data = element_->elementData();
current_data.setTerminalType(data_.type_);
current_data.setTerminalFunction(data_.function_);
current_data.setTerminalLED(data_.led_);
current_data.m_informations.addValue(QStringLiteral("label"), data_.label_);
if (element_->elementData() != current_data) {
m_project->undoStack()->push(new ChangeElementDataCommand(element_, current_data));
}
}
}
m_project->undoStack()->endMacro();
}
reload();
}
void FreeTerminalEditor::on_m_type_cb_activated(int index)
{
if (m_model)
{
const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes();
for (auto model_index : index_list)
{
auto type_index = m_model->index(model_index.row(), FreeTerminalModel::Type, model_index.parent());
if (type_index.isValid())
{
ElementData::TerminalType override_type;
switch (index) {
case 0:
override_type = ElementData::TTGeneric; break;
case 1:
override_type = ElementData::TTFuse; break;
case 2:
override_type = ElementData::TTSectional; break;
case 3:
override_type = ElementData::TTDiode; break;
case 4:
override_type = ElementData::TTGround; break;
default:
override_type = ElementData::TTGeneric; break;
}
m_model->setData(type_index, override_type);
}
}
}
}
void FreeTerminalEditor::on_m_function_cb_activated(int index)
{
if (m_model)
{
const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes();
for (auto model_index : index_list)
{
auto function_index = m_model->index(model_index.row(), FreeTerminalModel::Function, model_index.parent());
if (function_index.isValid())
{
ElementData::TerminalFunction override_function;
switch (index) {
case 0:
override_function = ElementData::TFGeneric; break;
case 1:
override_function = ElementData::TFPhase; break;
case 2:
override_function = ElementData::TFNeutral; break;
default:
override_function = ElementData::TFGeneric; break;
}
m_model->setData(function_index, override_function);
}
}
}
}
void FreeTerminalEditor::on_m_led_cb_activated(int index)
{
if (m_model)
{
const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes();
for (auto model_index : index_list)
{
auto led_index = m_model->index(model_index.row(), FreeTerminalModel::Led, model_index.parent());
if (led_index.isValid()) {
m_model->setData(led_index,
index == 0 ? false : true);
}
}
}
}
void FreeTerminalEditor::on_m_move_pb_clicked()
{
//Get the selected real terminal
const auto index_list = ui->m_table_view->selectionModel()->selectedIndexes();
const auto real_t_vector = m_model->realTerminalForIndex(index_list);
if (real_t_vector.isEmpty()) {
return;
}
//Get the terminal strip who receive the real terminal
const auto strip_uuid = ui->m_move_in_cb->currentData().toUuid();
TerminalStrip *terminal_strip{nullptr};
for (const auto &strip : m_project->terminalStrip()) {
if (strip->uuid() == strip_uuid) {
terminal_strip = strip;
break;
}
}
if (!terminal_strip) {
return;
}
//Apply action with an undo command
auto parent_undo = new QUndoCommand(tr("Déplacer des bornes à un groupe de bornes"));
for (const auto &rt_ : real_t_vector) {
new AddTerminalToStripCommand(rt_, terminal_strip, parent_undo);
}
m_project->undoStack()->push(parent_undo);
reload();
}
void FreeTerminalEditor::setDisabledMove(bool b)
{
ui->m_move_label->setDisabled(b);
ui->m_move_in_cb->setDisabled(b);
ui->m_move_pb->setDisabled(b);
}

View File

@@ -0,0 +1,58 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FREETERMINALEDITOR_H
#define FREETERMINALEDITOR_H
#include <QWidget>
class QETProject;
class RealTerminal;
class FreeTerminalModel;
class QTableView;
namespace Ui {
class FreeTerminalEditor;
}
class FreeTerminalEditor : public QWidget
{
Q_OBJECT
public:
explicit FreeTerminalEditor(QETProject *project, QWidget *parent = nullptr);
~FreeTerminalEditor();
void reload();
void apply();
private slots:
void on_m_type_cb_activated(int index);
void on_m_function_cb_activated(int index);
void on_m_led_cb_activated(int index);
void on_m_move_pb_clicked();
private:
void selectionChanged();
void setDisabledMove(bool b=true);
private:
Ui::FreeTerminalEditor *ui;
QETProject *m_project = nullptr;
FreeTerminalModel *m_model = nullptr;
};
#endif // FREETERMINALEDITOR_H

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FreeTerminalEditor</class>
<widget class="QWidget" name="FreeTerminalEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>727</width>
<height>279</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QLabel" name="m_move_label">
<property name="text">
<string>Déplacer dans :</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="m_move_in_cb">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="5" column="2">
<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" rowspan="6">
<widget class="QTableView" name="m_table_view">
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Type :</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>LED :</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="m_move_pb">
<property name="toolTip">
<string>Appliquer le déplacement</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/dialog-ok.png</normaloff>:/ico/22x22/dialog-ok.png</iconset>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QComboBox" name="m_type_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Fusible</string>
</property>
</item>
<item>
<property name="text">
<string>Sectionnable</string>
</property>
</item>
<item>
<property name="text">
<string>Diode</string>
</property>
</item>
<item>
<property name="text">
<string>Terre</string>
</property>
</item>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QComboBox" name="m_function_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Phase</string>
</property>
</item>
<item>
<property name="text">
<string>Neutre</string>
</property>
</item>
</widget>
</item>
<item row="4" column="2" colspan="2">
<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>
</layout>
</widget>
<resources>
<include location="../../../qelectrotech.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,376 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QComboBox>
#include "freeterminalmodel.h"
#include "../../elementprovider.h"
#include "../../utils/qetutils.h"
#include "../../qetgraphicsitem/terminalelement.h"
#include "../realterminal.h"
const int LABEL_CELL = 0;
const int XREF_CELL = 1;
const int TYPE_CELL = 2;
const int FUNCTION_CELL = 3;
const int LED_CELL = 4;
const int ROW_COUNT = 5;
static QVector<bool> UNMODIFIED_CELL_VECTOR{false, false, false, false, false};
FreeTerminalModel::Column FreeTerminalModel::columnTypeForIndex(const QModelIndex &index)
{
if (index.isValid())
{
switch (index.column()) {
case 0 : return Label;
case 1 : return XRef;
case 2 : return Type;
case 3 : return Function;
case 4 : return Led;
default : return Invalid;
}
}
return Invalid;
}
/**
* @brief FreeTerminalModel::FreeTerminalModel
* @param project
* @param parent
*/
FreeTerminalModel::FreeTerminalModel(QETProject *project, QObject *parent) :
QAbstractTableModel(parent),
m_project(project)
{
fillTerminalVector();
}
/**
* @brief FreeTerminalModel::rowCount
* @param parent
*/
int FreeTerminalModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_terminal_vector.size();
}
/**
* @brief FreeTerminalModel::columnCount
* @param parent
*/
int FreeTerminalModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return ROW_COUNT;
}
/**
* @brief FreeTerminalModel::data
* @param index
* @param role
* @return
*/
QVariant FreeTerminalModel::data(const QModelIndex &index, int role) const
{
if (index.row() >= rowCount(QModelIndex())) {
return QVariant();
}
const auto real_t_data = m_real_t_data.at(index.row());
if (role == Qt::DisplayRole)
{
switch (index.column())
{
case LABEL_CELL: return real_t_data.label_;
case XREF_CELL : return real_t_data.Xref_;
case TYPE_CELL : return ElementData::translatedTerminalType(real_t_data.type_);
case FUNCTION_CELL: return ElementData::translatedTerminalFunction(real_t_data.function_);
default : return QVariant();
}
}
else if (role == Qt::EditRole)
{
switch (index.column()) {
case LABEL_CELL : return real_t_data.label_;
default : return QVariant();
}
}
else if (role == Qt::CheckStateRole &&
index.column() == LED_CELL) {
return real_t_data.led_ ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::BackgroundRole && index.column() <= LED_CELL)
{
if (m_modified_cell.contains(real_t_data.real_terminal) &&
m_modified_cell.value(real_t_data.real_terminal).at(index.column()))
{
return QBrush(Qt::yellow);
}
}
return QVariant();
}
bool FreeTerminalModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
auto mrtd = dataAtRow(index.row());
bool modified_ = false;
int modified_cell = -1;
auto column_ = index.column();
if (column_ == LABEL_CELL &&
role == Qt::EditRole &&
mrtd.label_ != value.toString())
{
mrtd.label_ = value.toString();
modified_ = true;
modified_cell = LABEL_CELL;
}
else if (column_ == TYPE_CELL &&
role == Qt::EditRole)
{
mrtd.type_ = value.value<ElementData::TerminalType>();
modified_ = true;
modified_cell = TYPE_CELL;
}
else if (column_ == FUNCTION_CELL &&
role == Qt::EditRole)
{
mrtd.function_ = value.value<ElementData::TerminalFunction>();
modified_ = true;
modified_cell = FUNCTION_CELL;
}
else if (column_ == LED_CELL)
{
mrtd.led_ = value.toBool();
modified_ = true;
modified_cell = LED_CELL;
}
//Set the modification to the terminal data
if (modified_)
{
m_real_t_data.replace(index.row(), mrtd);
QVector<bool> vector_;
if (m_modified_cell.contains(mrtd.real_terminal)) {
vector_ = m_modified_cell.value(mrtd.real_terminal);
} else {
vector_ = UNMODIFIED_CELL_VECTOR;
}
vector_.replace(modified_cell, true);
m_modified_cell.insert(mrtd.real_terminal, vector_);
emit dataChanged(index, index);
return true;
}
return false;
}
/**
* @brief FreeTerminalModel::headerData
* @param section
* @param orientation
* @param role
* @return
*/
QVariant FreeTerminalModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
if (orientation == Qt::Horizontal)
{
switch (section) {
case LABEL_CELL: return tr("Label");
case XREF_CELL: return tr("Référence croisé");
case TYPE_CELL: return tr("Type");
case FUNCTION_CELL: return tr("Fonction");
case LED_CELL: return tr("led");
default : return QVariant();
}
}
}
return QVariant();
}
Qt::ItemFlags FreeTerminalModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
auto c = index.column();
if (c == LABEL_CELL || c == TYPE_CELL || c == FUNCTION_CELL)
flags = flags | Qt::ItemIsEditable;
if (c == LED_CELL) {
flags = flags | Qt::ItemIsUserCheckable;
}
return flags;
}
/**
* @brief FreeTerminalModel::clear
* Clear the model and set it as the current
* state of the project
*/
void FreeTerminalModel::clear()
{
beginResetModel();
m_terminal_vector.clear();
m_real_t_data.clear();
m_modified_cell.clear();
fillTerminalVector();
endResetModel();
}
/**
* @brief FreeTerminalModel::modifiedModelRealTerminalData
* @return a vector of modified terminal.
*/
QVector<modelRealTerminalData> FreeTerminalModel::modifiedModelRealTerminalData() const
{
QVector<modelRealTerminalData> returned_vector;
for (const auto &real_t_data : m_real_t_data) {
if (m_modified_cell.contains(real_t_data.real_terminal)) {
returned_vector.append(real_t_data);
}
}
return returned_vector;
}
/**
* @brief FreeTerminalModel::dataAtRow
* @param row
* @return the current data at row @a row
*/
modelRealTerminalData FreeTerminalModel::dataAtRow(int row) const
{
if (row >= m_terminal_vector.size()) {
return modelRealTerminalData();
} else {
return m_real_t_data.at(row);
}
}
/**
* @brief FreeTerminalModel::realTerminalForIndex
* @param index_list
* @return The QSharedPointer<RealTerminal> associated with the index found in @a index_list
*/
QVector<QSharedPointer<RealTerminal> > FreeTerminalModel::realTerminalForIndex(const QModelIndexList &index_list) const
{
QVector<QSharedPointer<RealTerminal>> vector_;
for (const auto &index : index_list)
{
if (index.isValid()
&& index.model() == this
&& index.row() < m_terminal_vector.size())
{
const auto rt_ = m_terminal_vector.at(index.row());
if (!vector_.contains(rt_)) {
vector_.append(m_terminal_vector.at(index.row()));
}
}
}
return vector_;
}
/**
* @brief FreeTerminalModel::fillTerminalVector
*/
void FreeTerminalModel::fillTerminalVector()
{
ElementProvider provider_(m_project);
auto free_terminal_vector = provider_.freeTerminal();
std::sort(free_terminal_vector.begin(), free_terminal_vector.end(),
[](TerminalElement *a, TerminalElement *b)
{
return QETUtils::sortBeginIntString(a->actualLabel(), b->actualLabel());
});
for (const auto &terminal_ : free_terminal_vector) {
m_terminal_vector.append(terminal_->realTerminal());
m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal()));
}
}
/****************************************************************
* A little delegate for add a combobox to edit type and function
****************************************************************/
FreeTerminalModelDelegate::FreeTerminalModelDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{}
QWidget *FreeTerminalModelDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == TYPE_CELL) {
auto qcb = new QComboBox(parent);
qcb->setObjectName(QLatin1String("terminal_type"));
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGeneric), ElementData::TTGeneric);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTFuse), ElementData::TTFuse);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTSectional), ElementData::TTSectional);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTDiode), ElementData::TTDiode);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGround), ElementData::TTGround);
return qcb;
}
if (index.column() == FUNCTION_CELL) {
auto qcb = new QComboBox(parent);
qcb->setObjectName(QLatin1String("terminal_function"));
qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFGeneric), ElementData::TFGeneric);
qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFPhase), ElementData::TFPhase);
qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFNeutral), ElementData::TFNeutral);
return qcb;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
void FreeTerminalModelDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if (index.isValid())
{
if (editor->objectName() == QLatin1String("terminal_type"))
{
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
model->setData(index, qcb->currentData(), Qt::EditRole);
}
}
else if (editor->objectName() == QLatin1String("terminal_function"))
{
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
model->setData(index, qcb->currentData(), Qt::EditRole);
}
}
else {
QStyledItemDelegate::setModelData(editor, model, index);
}
}
}

View File

@@ -0,0 +1,84 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FREETERMINALMODEL_H
#define FREETERMINALMODEL_H
#include <QAbstractTableModel>
#include <QPointer>
#include <QStyledItemDelegate>
#include "modelTerminalData.h"
#include "../../qetproject.h"
class RealTerminal;
/**
* @brief The FreeTerminalModel class
*/
class FreeTerminalModel : public QAbstractTableModel
{
public:
enum Column {
Label = 0,
XRef = 1,
Type = 2,
Function = 3,
Led = 4,
Invalid = 99
};
static FreeTerminalModel::Column columnTypeForIndex(const QModelIndex &index);
Q_OBJECT
public:
explicit FreeTerminalModel(QETProject *project, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void clear();
QVector<modelRealTerminalData> modifiedModelRealTerminalData() const;
modelRealTerminalData dataAtRow(int row) const;
QVector<QSharedPointer<RealTerminal>> realTerminalForIndex(const QModelIndexList &index_list) const;
private:
void fillTerminalVector();
private:
QPointer<QETProject> m_project;
QVector<QSharedPointer<RealTerminal>> m_terminal_vector;
QVector<modelRealTerminalData> m_real_t_data;
QHash<QSharedPointer<RealTerminal>, QVector<bool>> m_modified_cell;
};
class FreeTerminalModelDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
FreeTerminalModelDelegate(QObject *parent = nullptr);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
};
#endif // FREETERMINALMODEL_H

View File

@@ -0,0 +1,76 @@
/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MODELTERMINALDATA_H
#define MODELTERMINALDATA_H
#include <QString>
#include "../../qetgraphicsitem/element.h"
#include "../realterminal.h"
struct modelRealTerminalData
{
static modelRealTerminalData data(const QSharedPointer<RealTerminal> &real_t)
{
modelRealTerminalData mrtd;
if (!real_t.isNull())
{
mrtd.level_ = real_t->level();
mrtd.label_ = real_t->label();
mrtd.Xref_ = real_t->Xref();
mrtd.cable_ = real_t->cable();
mrtd.cable_wire = real_t->cableWire();
mrtd.conductor_ = real_t->conductor();
mrtd.led_ = real_t->isLed();
mrtd.type_ = real_t->type();
mrtd.function_ = real_t->function();
mrtd.element_ = real_t->element();
mrtd.real_terminal = real_t.toWeakRef();
mrtd.bridged_ = real_t->isBridged();
}
return mrtd;
}
int level_ = -1;
QString label_;
QString Xref_;
QString cable_;
QString cable_wire;
QString conductor_;
bool led_ = false;
bool bridged_ = false;
ElementData::TerminalType type_ = ElementData::TerminalType::TTGeneric;
ElementData::TerminalFunction function_ = ElementData::TerminalFunction::TFGeneric;
QPointer<Element> 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_;
}
#endif // MODELTERMINALDATA_H

View File

@@ -1,4 +1,4 @@
/* /*
Copyright 2006-2021 The QElectroTech Team Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech. This file is part of QElectroTech.
@@ -17,17 +17,10 @@
*/ */
#include "terminalstripeditor.h" #include "terminalstripeditor.h"
#include "ui_terminalstripeditor.h" #include "ui_terminalstripeditor.h"
#include "terminalstripcreatordialog.h"
#include "../../qetproject.h" #include "../../qetproject.h"
#include "../terminalstrip.h" #include "../terminalstrip.h"
#include "../elementprovider.h"
#include "../qetgraphicsitem/terminalelement.h"
#include "../UndoCommand/addterminalstripcommand.h"
#include "../UndoCommand/addterminaltostripcommand.h"
#include "../UndoCommand/changeterminalstripdata.h" #include "../UndoCommand/changeterminalstripdata.h"
#include "../undocommand/changeelementdatacommand.h" #include "../undocommand/changeelementdatacommand.h"
#include "terminalstriptreewidget.h"
#include "../../qeticons.h"
#include "terminalstripmodel.h" #include "terminalstripmodel.h"
#include "../diagram.h" #include "../diagram.h"
#include "../UndoCommand/sortterminalstripcommand.h" #include "../UndoCommand/sortterminalstripcommand.h"
@@ -36,38 +29,25 @@
#include "../UndoCommand/bridgeterminalscommand.h" #include "../UndoCommand/bridgeterminalscommand.h"
#include "../UndoCommand/changeterminalstripcolor.h" #include "../UndoCommand/changeterminalstripcolor.h"
#include "../physicalterminal.h" #include "../physicalterminal.h"
#include "../realterminal.h"
#include "../terminalstripbridge.h" #include "../terminalstripbridge.h"
#include <QTreeWidgetItem>
/** /**
* @brief TerminalStripEditor::TerminalStripEditor * @brief TerminalStripEditor::TerminalStripEditor
* @param project : Project to manage the terminal strip * @param project : Project to manage the terminal strip
* @param parent : paent widget * @param parent : paent widget
*/ */
TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) : TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
QDialog(parent), QWidget{parent},
ui(new Ui::TerminalStripEditor), ui{new Ui::TerminalStripEditor},
m_project(project) m_project{project}
{ {
ui->setupUi(this); ui->setupUi(this);
ui->m_table_widget->setItemDelegate(new TerminalStripModelDelegate(ui->m_terminal_strip_tw)); ui->m_table_widget->setItemDelegate(new TerminalStripModelDelegate{this});
ui->m_remove_terminal_strip_pb->setDisabled(true);
buildTree();
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
ui->m_terminal_strip_tw->expandRecursively(ui->m_terminal_strip_tw->rootIndex());
#else
ui->m_terminal_strip_tw->expandAll();
#endif
//Setup the bridge color //Setup the bridge color
ui->m_bridge_color_cb->setColors(TerminalStripBridge::bridgeColor().toList()); ui->m_bridge_color_cb->setColors(TerminalStripBridge::bridgeColor().toList());
setUpUndoConnections();
//Call for update the state of child widgets //Call for update the state of child widgets
selectionChanged(); selectionChanged();
@@ -103,190 +83,6 @@ TerminalStripEditor::~TerminalStripEditor() {
delete ui; delete ui;
} }
void TerminalStripEditor::setUpUndoConnections()
{
connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalAddedToStrip, this,
[=](QUuid terminal_uuid, QUuid strip_uuid)
{
auto terminal = m_uuid_terminal_H.value(terminal_uuid);
auto strip = m_uuid_strip_H.value(strip_uuid);
if (!terminal || !strip) {
return;
}
auto undo = new AddTerminalToStripCommand(terminal, strip);
m_project->undoStack()->push(undo);
});
connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalMovedFromStripToStrip, this,
[=] (QUuid terminal_uuid, QUuid old_strip_uuid, QUuid new_strip_uuid)
{
auto terminal = m_uuid_terminal_H.value(terminal_uuid);
auto old_strip = m_uuid_strip_H.value(old_strip_uuid);
auto new_strip = m_uuid_strip_H.value(new_strip_uuid);
if (!terminal || !old_strip || !new_strip) {
return;
}
auto undo = new AddTerminalToStripCommand(terminal, old_strip, new_strip);
m_project->undoStack()->push(undo);
});
connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalRemovedFromStrip, this,
[=] (QUuid terminal_uuid, QUuid old_strip_uuid)
{
auto terminal_ = m_uuid_terminal_H.value(terminal_uuid);
auto strip_ = m_uuid_strip_H.value(old_strip_uuid);
if (!terminal_ || !strip_) {
return;
}
auto undo = new RemoveTerminalFromStripCommand(terminal_, strip_);
m_project->undoStack()->push(undo);
});
}
/**
* @brief TerminalStripEditor::buildTree
* Build the tree widget use to explore terminal strip
*/
void TerminalStripEditor::buildTree()
{
ui->m_terminal_strip_tw->clear();
auto title = m_project->title();
if (title.isEmpty()) {
title = tr("Projet sans titre");
}
QStringList strl{title};
new QTreeWidgetItem(ui->m_terminal_strip_tw, strl, TerminalStripTreeWidget::Root);
QStringList ftstrl(tr("Bornes indépendante"));
new QTreeWidgetItem(ui->m_terminal_strip_tw, ftstrl, TerminalStripTreeWidget::FreeTerminal);
auto ts_vector = m_project->terminalStrip();
std::sort(ts_vector.begin(), ts_vector.end(), [](TerminalStrip *a, TerminalStrip *b) {
return a->name() < b->name();});
for (const auto ts : qAsConst(ts_vector)) {
addTerminalStrip(ts);
}
addFreeTerminal();
}
/**
* @brief TerminalStripEditor::addTerminalStrip
* Add a new terminal strip to the list of displayed terminal strip
* in the tree widget
* @param terminal_strip
* @return the QTreeWidgetItem who represent the terminal strip
* both if created or already exist
*/
QTreeWidgetItem* TerminalStripEditor::addTerminalStrip(TerminalStrip *terminal_strip)
{
if (auto item = m_item_strip_H.key(terminal_strip)) {
return item;
}
auto root_item = ui->m_terminal_strip_tw->topLevelItem(0);
//Check if installation already exist
//if not create a new one
auto installation_str = terminal_strip->installation();
QTreeWidgetItem *inst_qtwi = nullptr;
for (int i = 0 ; i<root_item->childCount() ; ++i) {
auto child_inst = root_item->child(i);
if (child_inst->data(0, Qt::DisplayRole).toString() == installation_str) {
inst_qtwi = child_inst;
break;
}
}
if (!inst_qtwi) {
QStringList inst_strl{installation_str};
inst_qtwi = new QTreeWidgetItem(root_item, inst_strl, TerminalStripTreeWidget::Installation);
}
//Check if location already exist
//if not create a new one
auto location_str = terminal_strip->location();
QTreeWidgetItem *loc_qtwi = nullptr;
for (int i = 0 ; i<inst_qtwi->childCount() ; ++i) {
auto child_loc = inst_qtwi->child(i);
if (child_loc->data(0, Qt::DisplayRole).toString() == location_str) {
loc_qtwi = child_loc;
break;
}
}
if (!loc_qtwi) {
QStringList loc_strl{location_str};
loc_qtwi = new QTreeWidgetItem(inst_qtwi, loc_strl, TerminalStripTreeWidget::Location);
}
//Add the terminal strip
QStringList name{terminal_strip->name()};
auto strip_item = new QTreeWidgetItem(loc_qtwi, name, TerminalStripTreeWidget::Strip);
strip_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, terminal_strip->uuid());
strip_item->setIcon(0, QET::Icons::TerminalStrip);
//Add child terminal of the strip
for (auto i=0 ; i<terminal_strip->physicalTerminalCount() ; ++i)
{
auto phy_t = terminal_strip->physicalTerminal(i);
if (phy_t->realTerminalCount())
{
const auto real_t = phy_t->realTerminals().at(0);
auto terminal_item = new QTreeWidgetItem(strip_item, QStringList(real_t->label()), TerminalStripTreeWidget::Terminal);
terminal_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, real_t->elementUuid());
terminal_item->setIcon(0, QET::Icons::ElementTerminal);
if (real_t->element()) {
m_uuid_terminal_H.insert(real_t->elementUuid(), qgraphicsitem_cast<TerminalElement *>(real_t->element()));
}
}
}
m_item_strip_H.insert(strip_item, terminal_strip);
m_uuid_strip_H.insert(terminal_strip->uuid(), terminal_strip);
return strip_item;
}
/**
* @brief TerminalStripEditor::addFreeTerminal
* Add free terminal (aka terminal which not belong to a terminal strip)
* in the tree widget
*/
void TerminalStripEditor::addFreeTerminal()
{
ElementProvider ep(m_project);
auto vector_ = ep.freeTerminal();
if (vector_.isEmpty()) {
return;
}
//Sort the terminal element by label
std::sort(vector_.begin(), vector_.end(), [](TerminalElement *a, TerminalElement *b) {
return a->actualLabel() < b->actualLabel();
});
auto free_terminal_item = ui->m_terminal_strip_tw->topLevelItem(1);
for (const auto terminal : qAsConst(vector_))
{
QUuid uuid_ = terminal->uuid();
QStringList strl{terminal->actualLabel()};
auto item = new QTreeWidgetItem(free_terminal_item, strl, TerminalStripTreeWidget::Terminal);
item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, uuid_.toString());
item->setIcon(0, QET::Icons::ElementTerminal);
m_uuid_terminal_H.insert(uuid_, terminal);
}
}
/** /**
* @brief TerminalStripEditor::setCurrentStrip * @brief TerminalStripEditor::setCurrentStrip
* Set the current terminal strip edited to \p strip_ * Set the current terminal strip edited to \p strip_
@@ -299,8 +95,8 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
} }
if (m_current_strip) { if (m_current_strip) {
disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload);
disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload);
} }
if (!strip_) if (!strip_)
@@ -328,20 +124,92 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
m_current_strip = strip_; m_current_strip = strip_;
if (m_model) if (m_model)
m_model->deleteLater(); {
m_model->setTerminalStrip(strip_);
connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged);
}
else
{
m_model = new TerminalStripModel{strip_, this};
ui->m_table_widget->setModel(m_model);
m_model->buildBridgePixmap(setUpBridgeCellWidth());
}
m_model = new TerminalStripModel(strip_, this);
ui->m_table_widget->setModel(m_model);
m_model->buildBridgePixmap(setUpBridgeCellWidth());
spanMultiLevelTerminals(); spanMultiLevelTerminals();
selectionChanged(); //Used to update child widgets selectionChanged(); //Used to update child widgets
connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload);
connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked); connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload);
connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged);
} }
} }
/**
* @brief TerminalStripEditor::reload
* Reload this editor and and reset all
* unapplied change.
*/
void TerminalStripEditor::reload()
{
if (m_current_strip)
{
ui->m_installation_le ->setText(m_current_strip->installation());
ui->m_location_le ->setText(m_current_strip->location());
ui->m_name_le ->setText(m_current_strip->name());
ui->m_comment_le ->setText(m_current_strip->comment());
ui->m_description_te ->setPlainText(m_current_strip->description());
}
if (m_model)
{
m_model->reload();
}
}
/**
* @brief TerminalStripEditor::apply
* Apply current edited values.
*/
void TerminalStripEditor::apply()
{
if (m_current_strip)
{
m_project->undoStack()->beginMacro(tr("Modifier des propriétés de borniers"));
TerminalStripData data;
data.m_installation = ui->m_installation_le->text();
data.m_location = ui->m_location_le->text();
data.m_name = ui->m_name_le->text();
data.m_comment = ui->m_comment_le->text();
data.m_description = ui->m_description_te->toPlainText();
m_project->undoStack()->push(new ChangeTerminalStripData(m_current_strip, data, nullptr));
if (m_model)
{
for (const auto &data_ : m_model->modifiedmodelRealTerminalData())
{
if (auto element = data_.element_)
{
auto current_data = element->elementData();
current_data.setTerminalType(data_.type_);
current_data.setTerminalFunction(data_.function_);
current_data.setTerminalLED(data_.led_);
current_data.m_informations.addValue(QStringLiteral("label"), data_.label_);
if (element->elementData() != current_data)
m_project->undoStack()->push(new ChangeElementDataCommand(element, current_data));
if (data_.level_ != data_.real_terminal.toStrongRef()->level())
m_project->undoStack()->push(new ChangeTerminalLevel(m_current_strip, data_.real_terminal, data_.level_));
}
}
}
m_project->undoStack()->endMacro();
}
reload();
}
/** /**
* @brief TerminalStripEditor::spanMultiLevelTerminals * @brief TerminalStripEditor::spanMultiLevelTerminals
* Span row of m_table_widget for multi-level terminal * Span row of m_table_widget for multi-level terminal
@@ -527,165 +395,6 @@ QPair<TerminalStripModel::Column, QVector<modelRealTerminalData> > TerminalStrip
return qMakePair(TerminalStripModel::Invalid, QVector<modelRealTerminalData>()); return qMakePair(TerminalStripModel::Invalid, QVector<modelRealTerminalData>());
} }
/**
* @brief TerminalStripEditor::on_m_add_terminal_strip_pb_clicked
* Action when user click on add terminal strip button
*/
void TerminalStripEditor::on_m_add_terminal_strip_pb_clicked()
{
QScopedPointer<TerminalStripCreatorDialog> dialog(new TerminalStripCreatorDialog(m_project, this));
if (auto item = ui->m_terminal_strip_tw->currentItem())
{
if (item->type() == TerminalStripTreeWidget::Strip) {
item = item->parent();
}
if (item->type() == TerminalStripTreeWidget::Location) {
dialog->setLocation(item->data(0, Qt::DisplayRole).toString());
item = item->parent();
}
if (item->type() == TerminalStripTreeWidget::Installation) {
dialog->setInstallation(item->data(0, Qt::DisplayRole).toString());
}
}
if (dialog->exec() == QDialog::Accepted)
{
auto ts = dialog->generatedTerminalStrip();
m_project->undoStack()->push(new AddTerminalStripCommand(ts, m_project));
auto item = addTerminalStrip(ts);
ui->m_terminal_strip_tw->setCurrentItem(item);
}
}
/**
* @brief TerminalStripEditor::on_m_remove_terminal_strip_pb_clicked
* Action when user click on remove terminal strip button
*/
void TerminalStripEditor::on_m_remove_terminal_strip_pb_clicked()
{
auto item = ui->m_terminal_strip_tw->currentItem();
if (auto strip = m_item_strip_H.value(item))
{
m_item_strip_H.remove(item);
m_uuid_strip_H.remove(strip->uuid());
delete item;
m_project->undoStack()->push(new RemoveTerminalStripCommand(strip, m_project));
}
on_m_reload_pb_clicked();
}
/**
* @brief TerminalStripEditor::on_m_reload_pb_clicked
*/
void TerminalStripEditor::on_m_reload_pb_clicked()
{
auto current_ = m_current_strip;
ui->m_terminal_strip_tw->clear();
m_item_strip_H.clear();
m_uuid_terminal_H.clear();
m_uuid_strip_H.clear();
qDeleteAll(m_item_strip_H.keyBegin(), m_item_strip_H.keyEnd());
buildTree();
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
ui->m_terminal_strip_tw->expandRecursively(ui->m_terminal_strip_tw->rootIndex());
#else
ui->m_terminal_strip_tw->expandAll();
#endif
//Reselect the tree widget item of the current edited strip
auto item = m_item_strip_H.key(current_);
if (item) {
ui->m_terminal_strip_tw->setCurrentItem(item);
}
}
/**
* @brief TerminalStripEditor::on_m_terminal_strip_tw_currentItemChanged
* @param current
* @param previous
*/
void TerminalStripEditor::on_m_terminal_strip_tw_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
Q_UNUSED(previous)
if (!current) {
setCurrentStrip(nullptr);
ui->m_remove_terminal_strip_pb->setDisabled(true);
return;
}
TerminalStrip *strip_ = nullptr;
if (current->type() == TerminalStripTreeWidget::Strip) {
strip_ = m_item_strip_H.value(current);
ui->m_remove_terminal_strip_pb->setEnabled(true);
}
else if (current->type() == TerminalStripTreeWidget::Terminal
&& current->parent()
&& current->parent()->type() == TerminalStripTreeWidget::Strip) {
strip_ = m_item_strip_H.value(current->parent());
ui->m_remove_terminal_strip_pb->setDisabled(true);
} else {
ui->m_remove_terminal_strip_pb->setDisabled(true);
}
setCurrentStrip(strip_);
}
void TerminalStripEditor::on_m_dialog_button_box_clicked(QAbstractButton *button)
{
Q_UNUSED(button)
auto role = ui->m_dialog_button_box->buttonRole(button);
if (role == QDialogButtonBox::ApplyRole)
{
if (m_current_strip)
{
m_project->undoStack()->beginMacro(tr("Modifier des propriétés de borniers"));
TerminalStripData data;
data.m_installation = ui->m_installation_le->text();
data.m_location = ui->m_location_le->text();
data.m_name = ui->m_name_le->text();
data.m_comment = ui->m_comment_le->text();
data.m_description = ui->m_description_te->toPlainText();
m_project->undoStack()->push(new ChangeTerminalStripData(m_current_strip, data, nullptr));
if (m_model)
{
for (const auto &data_ : m_model->modifiedmodelRealTerminalData())
{
if (auto element = data_.element_)
{
auto current_data = element->elementData();
current_data.setTerminalType(data_.type_);
current_data.setTerminalFunction(data_.function_);
current_data.setTerminalLED(data_.led_);
current_data.m_informations.addValue(QStringLiteral("label"), data_.label_);
if (element->elementData() != current_data)
m_project->undoStack()->push(new ChangeElementDataCommand(element, current_data));
if (data_.level_ != data_.real_terminal.toStrongRef()->level())
m_project->undoStack()->push(new ChangeTerminalLevel(m_current_strip, data_.real_terminal, data_.level_));
}
}
}
m_project->undoStack()->endMacro();
}
}
on_m_reload_pb_clicked();
}
/** /**
* @brief TerminalStripEditor::on_m_auto_pos_pb_clicked * @brief TerminalStripEditor::on_m_auto_pos_pb_clicked
*/ */
@@ -707,7 +416,7 @@ void TerminalStripEditor::on_m_group_terminals_pb_clicked()
if (mrtd_vector.size() >= 2) if (mrtd_vector.size() >= 2)
{ {
//At this step get the first physical terminal as receiver //At this step get the first physical terminal as receiver
auto receiver_ = m_current_strip->physicalTerminal(mrtd_vector.first().real_terminal); auto receiver_ = mrtd_vector.first().real_terminal.toStrongRef()->physicalTerminal();
QVector<QSharedPointer<RealTerminal>> vector_; QVector<QSharedPointer<RealTerminal>> vector_;
int count_ = 0; int count_ = 0;
@@ -718,11 +427,11 @@ void TerminalStripEditor::on_m_group_terminals_pb_clicked()
//Get the better physical terminal as receiver //Get the better physical terminal as receiver
//(physical terminal with the max of real terminal) //(physical terminal with the max of real terminal)
const auto current_physical = m_current_strip->physicalTerminal(real_t); const auto current_physical = real_t->physicalTerminal();
int real_t_count = current_physical->realTerminalCount(); int real_t_count = current_physical->realTerminalCount();
if (real_t_count > 1 && real_t_count > count_) { if (real_t_count > 1 && real_t_count > count_) {
count_ = real_t_count; count_ = real_t_count;
receiver_ = m_current_strip->physicalTerminal(real_t); receiver_ = real_t->physicalTerminal();
} }
} }

View File

@@ -18,7 +18,7 @@
#ifndef TERMINALSTRIPEDITOR_H #ifndef TERMINALSTRIPEDITOR_H
#define TERMINALSTRIPEDITOR_H #define TERMINALSTRIPEDITOR_H
#include <QDialog> #include <QWidget>
#include "terminalstripmodel.h" #include "terminalstripmodel.h"
@@ -28,29 +28,24 @@ namespace Ui {
class QETProject; class QETProject;
class TerminalStrip; class TerminalStrip;
class QTreeWidgetItem;
class TerminalElement;
class QAbstractButton;
/** /**
* @brief The TerminalStripEditor class * @brief The TerminalStripEditor class
* Main dialog used to edit terminal strip * Main dialog used to edit terminal strip
* of a project * of a project
*/ */
class TerminalStripEditor : public QDialog class TerminalStripEditor : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TerminalStripEditor(QETProject *project, QWidget *parent = nullptr); explicit TerminalStripEditor(QETProject *project, QWidget *parent = nullptr);
~TerminalStripEditor() override; ~TerminalStripEditor() override;
void setCurrentStrip(TerminalStrip *strip_);
void reload();
void apply();
private: private:
void setUpUndoConnections();
void buildTree();
QTreeWidgetItem* addTerminalStrip(TerminalStrip *terminal_strip);
void addFreeTerminal();
void setCurrentStrip(TerminalStrip *strip_);
void spanMultiLevelTerminals(); void spanMultiLevelTerminals();
void selectionChanged(); void selectionChanged();
QSize setUpBridgeCellWidth(); QSize setUpBridgeCellWidth();
@@ -58,11 +53,6 @@ class TerminalStripEditor : public QDialog
QPair<TerminalStripModel::Column, QVector<modelRealTerminalData>> singleColumnData() const; QPair<TerminalStripModel::Column, QVector<modelRealTerminalData>> singleColumnData() const;
private slots: private slots:
void on_m_add_terminal_strip_pb_clicked();
void on_m_remove_terminal_strip_pb_clicked();
void on_m_reload_pb_clicked();
void on_m_terminal_strip_tw_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void on_m_dialog_button_box_clicked(QAbstractButton *button);
void on_m_auto_ordering_pb_clicked(); void on_m_auto_ordering_pb_clicked();
void on_m_group_terminals_pb_clicked(); void on_m_group_terminals_pb_clicked();
void on_m_ungroup_pb_clicked(); void on_m_ungroup_pb_clicked();
@@ -76,13 +66,9 @@ class TerminalStripEditor : public QDialog
private: private:
Ui::TerminalStripEditor *ui; Ui::TerminalStripEditor *ui;
QETProject *m_project = nullptr; QETProject *m_project {nullptr};
TerminalStrip *m_current_strip {nullptr};
QHash<QTreeWidgetItem *, TerminalStrip *> m_item_strip_H; TerminalStripModel *m_model {nullptr};
QHash<QUuid, QPointer<TerminalElement>> m_uuid_terminal_H;
QHash<QUuid, QPointer<TerminalStrip>> m_uuid_strip_H;
TerminalStrip *m_current_strip = nullptr;
TerminalStripModel *m_model = nullptr;
}; };
#endif // TERMINALSTRIPEDITOR_H #endif // TERMINALSTRIPEDITOR_H

View File

@@ -1,191 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>TerminalStripEditor</class> <class>TerminalStripEditor</class>
<widget class="QDialog" name="TerminalStripEditor"> <widget class="QWidget" name="TerminalStripEditor">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1206</width> <width>922</width>
<height>645</height> <height>516</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Gestionnaire de borniers</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item row="1" column="0"> <item>
<widget class="QSplitter" name="splitter"> <widget class="QTabWidget" name="m_tab_widget">
<property name="orientation"> <property name="currentIndex">
<enum>Qt::Horizontal</enum> <number>0</number>
</property> </property>
<widget class="TerminalStripTreeWidget" name="m_terminal_strip_tw"> <widget class="QWidget" name="m_layout_tab">
<property name="sizePolicy"> <attribute name="title">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding"> <string>Disposition</string>
<horstretch>0</horstretch> </attribute>
<verstretch>0</verstretch> <layout class="QVBoxLayout" name="verticalLayout">
</sizepolicy>
</property>
<property name="dragEnabled">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="autoExpandDelay">
<number>500</number>
</property>
<property name="animated">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Explorateur de bornier</string>
</property>
</column>
</widget>
<widget class="QWidget" name="widget_3" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QTabWidget" name="m_tab_widget"> <widget class="QTableView" name="m_table_widget"/>
<property name="sizePolicy"> </item>
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> </layout>
<horstretch>1</horstretch> </widget>
<verstretch>0</verstretch> <widget class="QWidget" name="m_data_tab">
</sizepolicy> <attribute name="title">
<string>Propriétés</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Nom :</string>
</property> </property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="m_layout_tab">
<attribute name="title">
<string>Disposition</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableView" name="m_table_widget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_data_tab">
<attribute name="title">
<string>Propriétés</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Nom :</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="m_name_le"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPlainTextEdit" name="m_description_te"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_installation_le"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Commentaire</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="m_comment_le"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Installation :</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="m_location_le"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Localisation :</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item> <item row="3" column="0">
<widget class="QDialogButtonBox" name="m_dialog_button_box"> <widget class="QLabel" name="label_4">
<property name="standardButtons"> <property name="text">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Reset</set> <string>Commentaire :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Installation :</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="m_location_le"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_installation_le"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="m_comment_le"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Localisation :</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="m_name_le"/>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPlainTextEdit" name="m_description_te"/>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item>
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_2">
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Type :</string>
</property>
</widget>
</item>
<item row="5" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QPushButton" name="m_bridge_terminals_pb">
<property name="text">
<string>Ponter les bornes</string>
</property>
</widget>
</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="9" column="0" colspan="2">
<widget class="QPushButton" name="m_unbridge_terminals_pb">
<property name="text">
<string>Déponter les bornes</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="3" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Étage :</string> <string>Étage :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="10" column="1">
<widget class="KColorCombo" name="m_bridge_color_cb"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>LED :</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="m_type_cb"> <widget class="QComboBox" name="m_type_cb">
<item> <item>
<property name="text"> <property name="text">
@@ -214,96 +186,7 @@
</item> </item>
</widget> </widget>
</item> </item>
<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"> <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"> <widget class="QComboBox" name="m_function_cb">
<item> <item>
<property name="text"> <property name="text">
@@ -322,80 +205,57 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="10" column="0" colspan="2"> <item row="7" column="0" colspan="2">
<widget class="QPushButton" name="m_bridge_terminals_pb"> <widget class="Line" name="line_2">
<property name="text">
<string>Ponter les bornes</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QPushButton" name="m_unbridge_terminals_pb">
<property name="text">
<string>Déponter les bornes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="m_add_terminal_strip_pb">
<property name="text">
<string>Ajouter un bornier</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_remove_terminal_strip_pb">
<property name="text">
<string>Supprimer le bornier</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_reload_pb">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="m_level_sb">
<property name="maximum">
<number>6</number>
</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="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="10" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Couleur pont :</string>
</property>
</widget>
</item>
<item row="11" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>20</width>
<height>20</height> <height>40</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@@ -411,31 +271,7 @@
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>kcolorcombo.h</header> <header>kcolorcombo.h</header>
</customwidget> </customwidget>
<customwidget>
<class>TerminalStripTreeWidget</class>
<extends>QTreeWidget</extends>
<header location="global">terminalstriptreewidget.h</header>
</customwidget>
</customwidgets> </customwidgets>
<tabstops> <resources/>
<tabstop>m_add_terminal_strip_pb</tabstop>
<tabstop>m_remove_terminal_strip_pb</tabstop>
<tabstop>m_reload_pb</tabstop>
<tabstop>m_auto_ordering_pb</tabstop>
<tabstop>m_group_terminals_pb</tabstop>
<tabstop>m_ungroup_pb</tabstop>
<tabstop>m_level_sb</tabstop>
<tabstop>m_terminal_strip_tw</tabstop>
<tabstop>m_table_widget</tabstop>
<tabstop>m_description_te</tabstop>
<tabstop>m_comment_le</tabstop>
<tabstop>m_name_le</tabstop>
<tabstop>m_tab_widget</tabstop>
<tabstop>m_installation_le</tabstop>
<tabstop>m_location_le</tabstop>
</tabstops>
<resources>
<include location="../../../qelectrotech.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@@ -0,0 +1,185 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ui_terminalstripeditorwindow.h"
#include "../UndoCommand/addterminalstripcommand.h"
#include "freeterminaleditor.h"
#include "../../qetproject.h"
#include "../realterminal.h"
#include "../terminalstrip.h"
#include "terminalstripcreatordialog.h"
#include "terminalstripeditor.h"
#include "terminalstripeditorwindow.h"
#include "terminalstriptreedockwidget.h"
static const int EMPTY_PAGE = 0;
static const int FREE_TERMINAL_PAGE = 1;
static const int TERMINAL_STRIP_PAGE = 2;
/**
* @brief TerminalStripEditorWindow::TerminalStripEditorWindow
* @param project
* @param parent
*/
TerminalStripEditorWindow::TerminalStripEditorWindow(QETProject *project, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::TerminalStripEditorWindow),
m_project(project)
{
ui->setupUi(this);
ui->m_remove_terminal->setDisabled(true);
addTreeDockWidget();
m_free_terminal_editor = new FreeTerminalEditor(m_project, this);
m_terminal_strip_editor = new TerminalStripEditor{m_project, this};
connect(m_tree_dock, &TerminalStripTreeDockWidget::currentStripChanged, this, &TerminalStripEditorWindow::currentStripChanged);
ui->m_stacked_widget->insertWidget(EMPTY_PAGE, new QWidget(ui->m_stacked_widget));
ui->m_stacked_widget->insertWidget(FREE_TERMINAL_PAGE, m_free_terminal_editor);
ui->m_stacked_widget->insertWidget(TERMINAL_STRIP_PAGE, m_terminal_strip_editor);
}
/**
* @brief TerminalStripEditorWindow::~TerminalStripEditorWindow
*/
TerminalStripEditorWindow::~TerminalStripEditorWindow()
{
delete ui;
}
/**
* @brief TerminalStripEditorWindow::addTreeDockWidget
*/
void TerminalStripEditorWindow::addTreeDockWidget()
{
m_tree_dock = new TerminalStripTreeDockWidget(m_project, this);
m_tree_dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
addDockWidget(Qt::LeftDockWidgetArea, m_tree_dock);
}
/**
* @brief TerminalStripEditorWindow::currentStripChanged
* @param strip
*/
void TerminalStripEditorWindow::currentStripChanged(TerminalStrip *strip)
{
Q_UNUSED(strip)
updateUi();
}
void TerminalStripEditorWindow::updateUi()
{
ui->m_remove_terminal->setEnabled(m_tree_dock->currentIsStrip());
ui->m_stacked_widget->setCurrentIndex(EMPTY_PAGE);
if (auto real_terminal = m_tree_dock->currentRealTerminal())
{
if (!real_terminal->parentStrip())
{
ui->m_stacked_widget->setCurrentIndex(FREE_TERMINAL_PAGE);
m_free_terminal_editor->reload();
}
} else if (auto strip_ = m_tree_dock->currentStrip()) {
ui->m_stacked_widget->setCurrentIndex(TERMINAL_STRIP_PAGE);
m_terminal_strip_editor->setCurrentStrip(strip_);
}
}
/**
* @brief TerminalStripEditorWindow::on_m_add_terminal_strip_triggered
* Action when user click on add terminal strip button
*/
void TerminalStripEditorWindow::on_m_add_terminal_strip_triggered()
{
QScopedPointer<TerminalStripCreatorDialog> dialog(new TerminalStripCreatorDialog(m_project, this));
dialog->setLocation(m_tree_dock->currentLocation());
dialog->setInstallation(m_tree_dock->currentInstallation());
if (dialog->exec() == QDialog::Accepted)
{
auto ts = dialog->generatedTerminalStrip();
m_project->undoStack()->push(new AddTerminalStripCommand(ts, m_project));
m_tree_dock->reload();
m_tree_dock->setSelectedStrip(ts);
}
}
/**
* @brief TerminalStripEditorWindow::on_m_remove_terminal_triggered
*/
void TerminalStripEditorWindow::on_m_remove_terminal_triggered()
{
if (m_tree_dock->currentIsStrip())
{
if (auto strip_ = m_tree_dock->currentStrip())
{
m_project->undoStack()->push(new RemoveTerminalStripCommand(strip_, m_project));
m_tree_dock->reload();
}
}
}
/**
* @brief TerminalStripEditorWindow::on_m_reload_triggered
*/
void TerminalStripEditorWindow::on_m_reload_triggered() {
m_tree_dock->reload();
m_terminal_strip_editor->reload();
m_free_terminal_editor->reload();
}
/**
* @brief TerminalStripEditorWindow::on_m_button_box_clicked
* Action when user click on the apply/reset button
* @param button
*/
void TerminalStripEditorWindow::on_m_button_box_clicked(QAbstractButton *button)
{
auto role_{ui->m_button_box->buttonRole(button)};
if (role_ == QDialogButtonBox::ApplyRole)
{
switch (ui->m_stacked_widget->currentIndex()) {
case FREE_TERMINAL_PAGE:
m_free_terminal_editor->apply();
break;
case TERMINAL_STRIP_PAGE:
m_terminal_strip_editor->apply();
break;
default:
break;
}
}
else if (role_ == QDialogButtonBox::ResetRole)
{
m_terminal_strip_editor->reload();
m_free_terminal_editor->reload();
}
}
void TerminalStripEditorWindow::on_m_stacked_widget_currentChanged(int arg1) {
ui->m_button_box->setHidden(arg1 == EMPTY_PAGE);
}

View File

@@ -0,0 +1,63 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TERMINALSTRIPEDITORWINDOW_H
#define TERMINALSTRIPEDITORWINDOW_H
#include <QMainWindow>
class QETProject;
class TerminalStripTreeDockWidget;
class TerminalStrip;
class FreeTerminalEditor;
class TerminalStripEditor;
class QAbstractButton;
namespace Ui {
class TerminalStripEditorWindow;
}
class TerminalStripEditorWindow : public QMainWindow
{
Q_OBJECT
public:
explicit TerminalStripEditorWindow(QETProject *project, QWidget *parent = nullptr);
~TerminalStripEditorWindow();
private slots:
void on_m_add_terminal_strip_triggered();
void on_m_remove_terminal_triggered();
void on_m_reload_triggered();
void on_m_button_box_clicked(QAbstractButton *button);
void on_m_stacked_widget_currentChanged(int arg1);
private:
void addTreeDockWidget();
void currentStripChanged(TerminalStrip *strip);
void updateUi();
private:
Ui::TerminalStripEditorWindow *ui{nullptr};
QETProject *m_project {nullptr};
TerminalStripTreeDockWidget *m_tree_dock{nullptr};
FreeTerminalEditor *m_free_terminal_editor {nullptr};
TerminalStripEditor *m_terminal_strip_editor {nullptr};
};
#endif // TERMINALSTRIPEDITORWINDOW_H

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TerminalStripEditorWindow</class>
<widget class="QMainWindow" name="TerminalStripEditorWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1364</width>
<height>868</height>
</rect>
</property>
<property name="windowTitle">
<string>Gestionnaire de borniers</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QStackedWidget" name="m_stacked_widget"/>
</item>
<item>
<widget class="QDialogButtonBox" name="m_button_box">
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Reset</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1364</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="m_add_terminal_strip"/>
<addaction name="m_remove_terminal"/>
<addaction name="m_reload"/>
</widget>
<action name="m_add_terminal_strip">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
</property>
<property name="text">
<string>Ajouter un bornier</string>
</property>
<property name="toolTip">
<string>Ajouter un bornier au projet</string>
</property>
</action>
<action name="m_remove_terminal">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
</property>
<property name="text">
<string>Supprimer le bornier</string>
</property>
<property name="toolTip">
<string>Supprimer le bornier du projet</string>
</property>
</action>
<action name="m_reload">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
</property>
<property name="text">
<string>Recharger</string>
</property>
<property name="toolTip">
<string>Recharger les borniers</string>
</property>
</action>
</widget>
<resources>
<include location="../../../qelectrotech.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -116,6 +116,17 @@ TerminalStripModel::TerminalStripModel(TerminalStrip *terminal_strip, QObject *p
}); });
} }
/**
* @brief TerminalStripModel::setTerminalStrip
* set the current terminal strip of this model to @a terminal_strip.
* @param terminal_strip
*/
void TerminalStripModel::setTerminalStrip(TerminalStrip *terminal_strip)
{
m_terminal_strip = terminal_strip;
reload();
}
int TerminalStripModel::rowCount(const QModelIndex &parent) const int TerminalStripModel::rowCount(const QModelIndex &parent) const
{ {
Q_UNUSED(parent) Q_UNUSED(parent)
@@ -190,10 +201,6 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
index.column() == LEVEL_3_CELL)) index.column() == LEVEL_3_CELL))
{ {
return bridgePixmapFor(index); return bridgePixmapFor(index);
auto pixmap_ = bridgePixmapFor(index);
if (!pixmap_.isNull()) {
return pixmap_;
}
} }
return QVariant(); return QVariant();
@@ -310,8 +317,7 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const
/** /**
* @brief TerminalStripModel::modifiedRealTerminalData * @brief TerminalStripModel::modifiedRealTerminalData
* @return a vector of QPair of modified terminal. * @return a vector of modified terminal.
* the first value of the QPair is the original data, the second value is the edited data
*/ */
QVector<modelRealTerminalData> TerminalStripModel::modifiedmodelRealTerminalData() const QVector<modelRealTerminalData> TerminalStripModel::modifiedmodelRealTerminalData() const
{ {
@@ -484,6 +490,19 @@ void TerminalStripModel::buildBridgePixmap(const QSize &pixmap_size)
} }
} }
/**
* @brief TerminalStripModel::reload
* Reload (reset) the model
*/
void TerminalStripModel::reload()
{
beginResetModel();
m_physical_data.clear();
m_modified_cell.clear();
fillPhysicalTerminalData();
endResetModel();
}
void TerminalStripModel::fillPhysicalTerminalData() void TerminalStripModel::fillPhysicalTerminalData()
{ {
//Get all physical terminal //Get all physical terminal
@@ -499,7 +518,7 @@ void TerminalStripModel::fillPhysicalTerminalData()
{ {
if (!real_t.isNull()) if (!real_t.isNull())
{ {
mptd.real_data.append(modelRealData(real_t)); mptd.real_data.append(modelRealTerminalData::data(real_t));
} }
} }
@@ -681,21 +700,21 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
//Check if we need to draw a none bridge pixmap //Check if we need to draw a none bridge pixmap
//Check previous //Check previous
auto phy_t = m_terminal_strip->physicalTerminal(mrtd.real_terminal); auto phy_t = mrtd.real_terminal.toStrongRef()->physicalTerminal();
auto current_real_terminal = mrtd; auto current_real_terminal = mrtd;
auto current_phy_uuid = phy_t->uuid(); auto current_phy_uuid = phy_t->uuid();
bool already_jumped_to_previous = false; bool already_jumped_to_previous = false;
modelRealTerminalData previous_data; modelRealTerminalData previous_data;
do { do {
current_real_terminal = modelRealData(m_terminal_strip->previousRealTerminal(current_real_terminal.real_terminal)); current_real_terminal = modelRealTerminalData::data(m_terminal_strip->previousRealTerminal(current_real_terminal.real_terminal));
if (current_real_terminal.level_ == -1) { if (current_real_terminal.level_ == -1) {
break; break;
} }
//We are in the same physical terminal as previous loop //We are in the same physical terminal as previous loop
if (current_phy_uuid == m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid()) if (current_phy_uuid == current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid())
{ {
if (current_real_terminal.bridged_ && if (current_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) { current_real_terminal.level_ == level_column) {
@@ -707,7 +726,7 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
break; break;
} else { } else {
already_jumped_to_previous = true; already_jumped_to_previous = true;
current_phy_uuid = m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid(); current_phy_uuid = current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid();
if (current_real_terminal.bridged_ && if (current_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) { current_real_terminal.level_ == level_column) {
previous_data = current_real_terminal; previous_data = current_real_terminal;
@@ -723,14 +742,14 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
modelRealTerminalData next_data; modelRealTerminalData next_data;
do { do {
current_real_terminal = modelRealData(m_terminal_strip->nextRealTerminal(current_real_terminal.real_terminal)); current_real_terminal = modelRealTerminalData::data(m_terminal_strip->nextRealTerminal(current_real_terminal.real_terminal));
if (current_real_terminal.level_ == -1) { if (current_real_terminal.level_ == -1) {
break; break;
} }
//We are in the same physical terminal as previous loop //We are in the same physical terminal as previous loop
if (current_phy_uuid == m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid()) if (current_phy_uuid == current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid())
{ {
if (current_real_terminal.bridged_ && if (current_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) { current_real_terminal.level_ == level_column) {
@@ -742,7 +761,7 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
break; break;
} else { } else {
already_jumped_to_next = true; already_jumped_to_next = true;
current_phy_uuid = m_terminal_strip->physicalTerminal(current_real_terminal.real_terminal)->uuid(); current_phy_uuid = current_real_terminal.real_terminal.toStrongRef()->physicalTerminal()->uuid();
if (current_real_terminal.bridged_ && if (current_real_terminal.bridged_ &&
current_real_terminal.level_ == level_column) { current_real_terminal.level_ == level_column) {
next_data = current_real_terminal; next_data = current_real_terminal;
@@ -762,29 +781,6 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
return QPixmap(); 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;
}
/*********************************************************** /***********************************************************
* A little 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 * and a spinbox to edit the level of a terminal

View File

@@ -26,7 +26,7 @@
#include <QColor> #include <QColor>
#include "../terminalstrip.h" #include "../terminalstrip.h"
#include "../../qetgraphicsitem/element.h" #include "modelTerminalData.h"
//Code to use QColor as key for QHash //Code to use QColor as key for QHash
inline uint qHash(const QColor &key, uint seed) { inline uint qHash(const QColor &key, uint seed) {
@@ -43,37 +43,6 @@ inline uint qHash(const QPointer<Element> &key, uint seed) {
class TerminalStrip; 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 class TerminalStripModel : public QAbstractTableModel
{ {
public: public:
@@ -101,6 +70,7 @@ class TerminalStripModel : public QAbstractTableModel
Q_OBJECT Q_OBJECT
public: public:
TerminalStripModel(TerminalStrip *terminal_strip, QObject *parent = nullptr); TerminalStripModel(TerminalStrip *terminal_strip, QObject *parent = nullptr);
void setTerminalStrip(TerminalStrip *terminal_strip);
virtual int rowCount (const QModelIndex &parent = QModelIndex()) const override; virtual int rowCount (const QModelIndex &parent = QModelIndex()) const override;
virtual int columnCount (const QModelIndex &parent = QModelIndex()) const override; virtual int columnCount (const QModelIndex &parent = QModelIndex()) const override;
@@ -116,6 +86,8 @@ class TerminalStripModel : public QAbstractTableModel
void buildBridgePixmap(const QSize &pixmap_size); void buildBridgePixmap(const QSize &pixmap_size);
void reload();
private: private:
void fillPhysicalTerminalData(); void fillPhysicalTerminalData();
modelRealTerminalData dataAtRow(int row) const; modelRealTerminalData dataAtRow(int row) const;
@@ -124,8 +96,6 @@ class TerminalStripModel : public QAbstractTableModel
modelRealTerminalData realDataAtIndex(int index) const; modelRealTerminalData realDataAtIndex(int index) const;
QPixmap bridgePixmapFor(const QModelIndex &index) const; QPixmap bridgePixmapFor(const QModelIndex &index) const;
static modelRealTerminalData modelRealData(const QWeakPointer<RealTerminal> &real_terminal);
private: private:
QPointer<TerminalStrip> m_terminal_strip; QPointer<TerminalStrip> m_terminal_strip;
QHash<QPointer<Element>, QVector<bool>> m_modified_cell; QHash<QPointer<Element>, QVector<bool>> m_modified_cell;

View File

@@ -0,0 +1,385 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "terminalstriptreedockwidget.h"
#include "ui_terminalstriptreedockwidget.h"
#include "../UndoCommand/addterminaltostripcommand.h"
#include "../../elementprovider.h"
#include "../physicalterminal.h"
#include "../../qeticons.h"
#include "../../qetproject.h"
#include "../realterminal.h"
#include "../../qetgraphicsitem/terminalelement.h"
#include "../terminalstrip.h"
#include "terminalstriptreewidget.h"
TerminalStripTreeDockWidget::TerminalStripTreeDockWidget(QETProject *project, QWidget *parent) :
QDockWidget(parent),
ui(new Ui::TerminalStripTreeDockWidget),
m_project(project)
{
ui->setupUi(this);
buildTree();
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex());
#else
ui->m_tree_view->expandAll();
#endif
setupUndoConnections();
}
TerminalStripTreeDockWidget::~TerminalStripTreeDockWidget()
{
delete ui;
}
/**
* @brief TerminalStripTreeDockWidget::reload
*/
void TerminalStripTreeDockWidget::reload()
{
auto current_ = m_current_strip;
ui->m_tree_view->clear();
m_item_strip_H.clear();
m_uuid_terminal_H.clear();
m_uuid_strip_H.clear();
for (const auto &connection_ : qAsConst(m_strip_changed_connection)) {
disconnect(connection_);
}
m_strip_changed_connection.clear();
buildTree();
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex());
#else
ui->m_terminal_strip_tw->expandAll();
#endif
//Reselect the tree widget item of the current edited strip
auto item = m_item_strip_H.key(current_);
if (item) {
ui->m_tree_view->setCurrentItem(item);
}
}
/**
* @brief TerminalStripTreeDockWidget::currentIsStrip
* @return true if the current selected item is a terminal strip.
*/
bool TerminalStripTreeDockWidget::currentIsStrip() const {
return m_item_strip_H.contains(ui->m_tree_view->currentItem());
}
/**
* @brief TerminalStripTreeDockWidget::currentStrip
* @return The current selected strip or nullptr if there is
* no strip selected;
*/
TerminalStrip *TerminalStripTreeDockWidget::currentStrip() const {
return m_current_strip;
}
/**
* @brief TerminalStripTreeDockWidget::currentInstallation
* @return the installation according to the current selection
*/
QString TerminalStripTreeDockWidget::currentInstallation() const
{
if (m_current_strip) {
return m_current_strip->installation();
}
if (auto item = ui->m_tree_view->currentItem())
{
if (item->type() == TerminalStripTreeWidget::Location) {
item = item->parent();
}
if (item->type() == TerminalStripTreeWidget::Installation) {
return item->data(0, Qt::DisplayRole).toString();
}
}
return QString();
}
/**
* @brief TerminalStripTreeDockWidget::currentLocation
* @return the location according to the current selection
*/
QString TerminalStripTreeDockWidget::currentLocation() const
{
if (m_current_strip) {
return m_current_strip->location();
}
if (auto item = ui->m_tree_view->currentItem()) {
if (item->type() == TerminalStripTreeWidget::Location) {
return item->data(0, Qt::DisplayRole).toString();
}
}
return QString();
}
/**
* @brief TerminalStripTreeDockWidget::setSelectedStrip
* @param strip
*/
void TerminalStripTreeDockWidget::setSelectedStrip(TerminalStrip *strip) {
ui->m_tree_view->setCurrentItem(m_item_strip_H.key(strip));
}
/**
* @brief TerminalStripTreeDockWidget::currentRealTerminal
* @return the current real terminal or a null QSharedPointer.
*/
QSharedPointer<RealTerminal> TerminalStripTreeDockWidget::currentRealTerminal() const
{
if (auto item = ui->m_tree_view->currentItem()) {
if (item->type() == TerminalStripTreeWidget::Terminal) {
return m_uuid_terminal_H.value(item->data(0,TerminalStripTreeWidget::UUID_USER_ROLE).toUuid());
}
}
return QSharedPointer<RealTerminal>();
}
/**
* @brief TerminalStripTreeDockWidget::on_m_tree_view_currentItemChanged
* @param current
* @param previous
*/
void TerminalStripTreeDockWidget::on_m_tree_view_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
Q_UNUSED(previous)
if (!current) {
setCurrentStrip(nullptr);
return;
}
TerminalStrip *strip_ = nullptr;
if (current->type() == TerminalStripTreeWidget::Strip) {
strip_ = m_item_strip_H.value(current);
}
else if (current->type() == TerminalStripTreeWidget::Terminal
&& current->parent()
&& current->parent()->type() == TerminalStripTreeWidget::Strip) {
strip_ = m_item_strip_H.value(current->parent());
}
if (strip_ != m_current_strip) {
setCurrentStrip(strip_);
}
}
/**
* @brief TerminalStripTreeDockWidget::buildTree
*/
void TerminalStripTreeDockWidget::buildTree()
{
auto title_ = m_project->title();
if (title_.isEmpty()) {
title_ = tr("Projet sans titre");
}
QStringList strl{title_};
new QTreeWidgetItem(ui->m_tree_view, strl, TerminalStripTreeWidget::Root);
QStringList ftstrl(tr("Bornes indépendante"));
new QTreeWidgetItem(ui->m_tree_view, ftstrl, TerminalStripTreeWidget::FreeTerminal);
auto ts_vector = m_project->terminalStrip();
std::sort(ts_vector.begin(), ts_vector.end(), [](TerminalStrip *a, TerminalStrip *b) {
return a->name() < b->name();
});
for (const auto &ts : qAsConst(ts_vector)) {
addTerminalStrip(ts);
}
addFreeTerminal();
}
QTreeWidgetItem* TerminalStripTreeDockWidget::addTerminalStrip(TerminalStrip *terminal_strip)
{
if (auto item = m_item_strip_H.key(terminal_strip)) {
return item;
}
auto root_item = ui->m_tree_view->topLevelItem(0);
//Check if installation already exist
//if not create a new one
auto installation_str = terminal_strip->installation();
QTreeWidgetItem *inst_qtwi = nullptr;
for (int i = 0 ; i<root_item->childCount() ; ++i) {
auto child_inst = root_item->child(i);
if (child_inst->data(0, Qt::DisplayRole).toString() == installation_str) {
inst_qtwi = child_inst;
break;
}
}
if (!inst_qtwi) {
QStringList inst_strl{installation_str};
inst_qtwi = new QTreeWidgetItem(root_item, inst_strl, TerminalStripTreeWidget::Installation);
}
//Check if location already exist
//if not create a new one
auto location_str = terminal_strip->location();
QTreeWidgetItem *loc_qtwi = nullptr;
for (int i = 0 ; i<inst_qtwi->childCount() ; ++i) {
auto child_loc = inst_qtwi->child(i);
if (child_loc->data(0, Qt::DisplayRole).toString() == location_str) {
loc_qtwi = child_loc;
break;
}
}
if (!loc_qtwi) {
QStringList loc_strl{location_str};
loc_qtwi = new QTreeWidgetItem(inst_qtwi, loc_strl, TerminalStripTreeWidget::Location);
}
//Add the terminal strip
QStringList name{terminal_strip->name()};
auto strip_item = new QTreeWidgetItem(loc_qtwi, name, TerminalStripTreeWidget::Strip);
strip_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, terminal_strip->uuid());
strip_item->setIcon(0, QET::Icons::TerminalStrip);
//Add child terminal of the strip
for (auto i=0 ; i<terminal_strip->physicalTerminalCount() ; ++i)
{
auto phy_t = terminal_strip->physicalTerminal(i);
if (phy_t->realTerminalCount())
{
QString text_;
for (const auto &real_t : phy_t->realTerminals())
{
if (text_.isEmpty())
text_ = real_t->label();
else
text_.append(QStringLiteral(", ")).append(real_t->label());
}
const auto real_t = phy_t->realTerminals().at(0);
auto terminal_item = new QTreeWidgetItem(strip_item, QStringList(text_), TerminalStripTreeWidget::Terminal);
terminal_item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, phy_t->uuid());
terminal_item->setIcon(0, QET::Icons::ElementTerminal);
}
}
m_item_strip_H.insert(strip_item, terminal_strip);
m_uuid_strip_H.insert(terminal_strip->uuid(), terminal_strip);
m_strip_changed_connection.append(connect(terminal_strip, &TerminalStrip::orderChanged, this, &TerminalStripTreeDockWidget::reload));
return strip_item;
}
/**
* @brief TerminalStripTreeDockWidget::addFreeTerminal
*/
void TerminalStripTreeDockWidget::addFreeTerminal()
{
ElementProvider ep(m_project);
auto vector_ = ep.freeTerminal();
if (vector_.isEmpty()) {
return;
}
//Sort the terminal element by label
std::sort(vector_.begin(), vector_.end(), [](TerminalElement *a, TerminalElement *b) {
return a->actualLabel() < b->actualLabel();
});
auto free_terminal_item = ui->m_tree_view->topLevelItem(1);
for (const auto terminal : qAsConst(vector_))
{
QUuid uuid_ = terminal->uuid();
QStringList strl{terminal->actualLabel()};
auto item = new QTreeWidgetItem(free_terminal_item, strl, TerminalStripTreeWidget::Terminal);
item->setData(0, TerminalStripTreeWidget::UUID_USER_ROLE, uuid_.toString());
item->setIcon(0, QET::Icons::ElementTerminal);
m_uuid_terminal_H.insert(uuid_, terminal->realTerminal());
}
}
void TerminalStripTreeDockWidget::setupUndoConnections()
{
connect(ui->m_tree_view, &TerminalStripTreeWidget::terminalAddedToStrip, this,
[=](QUuid terminal_uuid, QUuid strip_uuid)
{
auto terminal = m_uuid_terminal_H.value(terminal_uuid);
auto strip = m_uuid_strip_H.value(strip_uuid);
if (!terminal || !strip) {
return;
}
auto undo = new AddTerminalToStripCommand(terminal, strip);
m_project->undoStack()->push(undo);
});
connect(ui->m_tree_view, &TerminalStripTreeWidget::terminalMovedFromStripToStrip, this,
[=] (QUuid terminal_uuid, QUuid old_strip_uuid, QUuid new_strip_uuid)
{
auto old_strip = m_uuid_strip_H.value(old_strip_uuid);
auto new_strip = m_uuid_strip_H.value(new_strip_uuid);
if (!old_strip || !new_strip) {
return;
}
auto terminal = old_strip->physicalTerminal(terminal_uuid);
if (!terminal) {
return;
}
auto undo = new MoveTerminalCommand(terminal, old_strip, new_strip);
m_project->undoStack()->push(undo);
});
connect(ui->m_tree_view, &TerminalStripTreeWidget::terminalRemovedFromStrip, this,
[=] (QUuid terminal_uuid, QUuid old_strip_uuid)
{
auto strip_ = m_uuid_strip_H.value(old_strip_uuid);
if (!strip_) {
return;
}
auto terminal_ = strip_->physicalTerminal(terminal_uuid);
if (!terminal_) {
return;
}
auto undo = new RemoveTerminalFromStripCommand(terminal_, strip_);
m_project->undoStack()->push(undo);
});
}
void TerminalStripTreeDockWidget::setCurrentStrip(TerminalStrip *strip)
{
m_current_strip = strip;
emit currentStripChanged(strip);
}

View File

@@ -0,0 +1,73 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TERMINALSTRIPTREEDOCKWIDGET_H
#define TERMINALSTRIPTREEDOCKWIDGET_H
#include <QDockWidget>
#include <QPointer>
class QETProject;
class QTreeWidgetItem;
class TerminalStrip;
class RealTerminal;
namespace Ui {
class TerminalStripTreeDockWidget;
}
class TerminalStripTreeDockWidget : public QDockWidget
{
Q_OBJECT
public:
explicit TerminalStripTreeDockWidget(QETProject *project, QWidget *parent = nullptr);
~TerminalStripTreeDockWidget();
void reload();
bool currentIsStrip() const;
TerminalStrip* currentStrip() const;
QString currentInstallation() const;
QString currentLocation() const;
void setSelectedStrip(TerminalStrip *strip);
QSharedPointer<RealTerminal> currentRealTerminal() const;
signals:
void currentStripChanged(TerminalStrip *strip);
private slots:
void on_m_tree_view_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
private:
void buildTree();
QTreeWidgetItem* addTerminalStrip(TerminalStrip *terminal_strip);
void addFreeTerminal();
void setupUndoConnections();
void setCurrentStrip(TerminalStrip *strip);
private:
Ui::TerminalStripTreeDockWidget *ui;
QPointer<QETProject> m_project;
QPointer<TerminalStrip> m_current_strip;
QHash<QTreeWidgetItem *, TerminalStrip *> m_item_strip_H;
QHash<QUuid, QSharedPointer<RealTerminal>> m_uuid_terminal_H;
QHash<QUuid, QPointer<TerminalStrip>> m_uuid_strip_H;
QVector<QMetaObject::Connection> m_strip_changed_connection;
};
#endif // TERMINALSTRIPTREEDOCKWIDGET_H

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TerminalStripTreeDockWidget</class>
<widget class="QDockWidget" name="TerminalStripTreeDockWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>397</width>
<height>542</height>
</rect>
</property>
<property name="windowTitle">
<string>Explorateur de bornier</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="TerminalStripTreeWidget" name="m_tree_view">
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="animated">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>TerminalStripTreeWidget</class>
<extends>QTreeWidget</extends>
<header location="global">terminalstriptreewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -23,8 +23,6 @@
#include <QMimeData> #include <QMimeData>
#include <QDragMoveEvent> #include <QDragMoveEvent>
int TerminalStripTreeWidget::UUID_USER_ROLE = Qt::UserRole + 1;
TerminalStripTreeWidget::TerminalStripTreeWidget(QWidget *parent) : TerminalStripTreeWidget::TerminalStripTreeWidget(QWidget *parent) :
QTreeWidget(parent) QTreeWidget(parent)
{} {}

View File

@@ -39,7 +39,7 @@ class TerminalStripTreeWidget : public QTreeWidget
}; };
//Role used for data in QTreeWidgetItem //Role used for data in QTreeWidgetItem
static int UUID_USER_ROLE; static constexpr int UUID_USER_ROLE{Qt::UserRole + 1};
signals: signals:
/** /**

View File

@@ -42,7 +42,7 @@
#include "undocommand/rotateselectioncommand.h" #include "undocommand/rotateselectioncommand.h"
#include "undocommand/rotatetextscommand.h" #include "undocommand/rotatetextscommand.h"
#include "diagram.h" #include "diagram.h"
#include "TerminalStrip/ui/terminalstripeditor.h" #include "TerminalStrip/ui/terminalstripeditorwindow.h"
#include "ui/diagrameditorhandlersizewidget.h" #include "ui/diagrameditorhandlersizewidget.h"
#ifdef BUILD_WITHOUT_KF5 #ifdef BUILD_WITHOUT_KF5
@@ -427,7 +427,7 @@ void QETDiagramEditor::setUpActions()
//Add a nomenclature item //Add a nomenclature item
m_add_nomenclature = new QAction(QET::Icons::TableOfContent, tr("Ajouter une nomenclature"), this); m_add_nomenclature = new QAction(QET::Icons::TableOfContent, tr("Ajouter une nomenclature"), this);
connect(m_add_nomenclature, &QAction::triggered, [this]() { connect(m_add_nomenclature, &QAction::triggered, this, [=]() {
if(this->currentDiagramView()) { if(this->currentDiagramView()) {
QetGraphicsTableFactory::createAndAddNomenclature(this->currentDiagramView()->diagram()); QetGraphicsTableFactory::createAndAddNomenclature(this->currentDiagramView()->diagram());
} }
@@ -435,19 +435,19 @@ void QETDiagramEditor::setUpActions()
//Add a summary item //Add a summary item
m_add_summary = new QAction(QET::Icons::TableOfContent, tr("Ajouter un sommaire"), this); m_add_summary = new QAction(QET::Icons::TableOfContent, tr("Ajouter un sommaire"), this);
connect(m_add_summary, &QAction::triggered, [this]() { connect(m_add_summary, &QAction::triggered, this, [=]() {
if(this->currentDiagramView()) { if(this->currentDiagramView()) {
QetGraphicsTableFactory::createAndAddSummary(this->currentDiagramView()->diagram()); QetGraphicsTableFactory::createAndAddSummary(this->currentDiagramView()->diagram());
} }
}); });
m_terminal_strip_dialog = new QAction(QET::Icons::TerminalStrip, tr("Gestionnaire de borniers (DEV)"), this); m_terminal_strip_dialog = new QAction(QET::Icons::TerminalStrip, tr("Gestionnaire de borniers (DEV)"), this);
connect(m_terminal_strip_dialog, &QAction::triggered, [this]() connect(m_terminal_strip_dialog, &QAction::triggered, this, [=]()
{ {
if (auto project = this->currentProject()) if (auto project = this->currentProject())
{ {
auto str = new TerminalStripEditor(project, this); auto tsew {new TerminalStripEditorWindow{project, this}};
str->show(); tsew->show();
} }
}); });

View File

@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>. along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "terminalelement.h" #include "terminalelement.h"
#include"../TerminalStrip/realterminal.h"
/** /**
@brief TerminalElement::TerminalElement @brief TerminalElement::TerminalElement
@@ -27,7 +28,10 @@
TerminalElement::TerminalElement(const ElementsLocation &location, TerminalElement::TerminalElement(const ElementsLocation &location,
QGraphicsItem *qgi, int *state) : QGraphicsItem *qgi, int *state) :
Element(location, qgi, state, Element::Terminale) Element(location, qgi, state, Element::Terminale)
{} {
auto rt = new RealTerminal(this);
m_real_terminal = rt->sharedRef();
}
TerminalElement::~TerminalElement() TerminalElement::~TerminalElement()
{} {}
@@ -41,17 +45,11 @@ void TerminalElement::initLink(QETProject *project) {
} }
/** /**
* @brief TerminalElement::setParentTerminalStrip * @brief TerminalElement::realTerminal
* Set \p strip as parent terminal strip. * @return the real terminal of this terminal element.
* Be carefull, this function only set internally the parent terminal strip.
* This function don't check if there is a previous
* parent terminal strip and don't check
* if the new terminal strip have this terminal element
* in her list of terminal element.
* @param strip
*/ */
void TerminalElement::setParentTerminalStrip(TerminalStrip *strip) { QSharedPointer<RealTerminal> TerminalElement::realTerminal() const {
m_parent_terminal_strip = strip; return m_real_terminal;
} }
/** /**
@@ -60,6 +58,9 @@ void TerminalElement::setParentTerminalStrip(TerminalStrip *strip) {
* terminal element or nullptr if not. * terminal element or nullptr if not.
*/ */
TerminalStrip *TerminalElement::parentTerminalStrip() const { TerminalStrip *TerminalElement::parentTerminalStrip() const {
return m_parent_terminal_strip.data(); if (m_real_terminal) {
return m_real_terminal->parentStrip();
}
return nullptr;
} }

View File

@@ -23,6 +23,7 @@
#include "../TerminalStrip/terminalstrip.h" #include "../TerminalStrip/terminalstrip.h"
class QETProject; class QETProject;
class RealTerminal;
/** /**
@brief The TerminalElement class @brief The TerminalElement class
*/ */
@@ -35,11 +36,12 @@ class TerminalElement : public Element
~TerminalElement() override; ~TerminalElement() override;
void initLink(QETProject *project) override; void initLink(QETProject *project) override;
QSharedPointer<RealTerminal> realTerminal() const;
void setParentTerminalStrip(TerminalStrip *strip); void setParentTerminalStrip(TerminalStrip *strip);
TerminalStrip *parentTerminalStrip() const; TerminalStrip *parentTerminalStrip() const;
private: private:
QPointer<TerminalStrip> m_parent_terminal_strip; QSharedPointer<RealTerminal> m_real_terminal;
}; };
#endif // TERMINALELEMENT_H #endif // TERMINALELEMENT_H

View File

@@ -87,3 +87,48 @@ qreal QETUtils::graphicsHandlerSize(QGraphicsItem *item)
//Default value //Default value
return 10; return 10;
} }
/**
* @brief QETUtils::sortBeginIntString
* Sort the string @a str_a and @a str_b and take in
* count if string begin with an int to sort it
* as int and not as string in this case.
* For exemple if we have to sort the string :
* "3str", 10str", "100str", "2str", "20str".
* The default behavior when sorting QString with the comparaison operator will be:
* "10str" "100str" "2str", "20str", "3str"
* When sorting with this function, the result will be :
* "10str", "2str", "3str", "20str", "100str"
* @param str_a
* @param str_b
* @return
*/
bool QETUtils::sortBeginIntString(const QString &str_a, const QString &str_b)
{
const QRegularExpression rx(QStringLiteral("^\\d+"));
int int_a =-1;
int int_b =-1;
auto match_a = rx.match(str_a);
if (match_a.hasMatch()) {
int_a = match_a.captured(0).toInt();
}
auto match_b = rx.match(str_b);
if (match_b.hasMatch()) {
int_b = match_b.captured(0).toInt();
}
//Sort as numbers if both string
//start at least by a digit and
//the number of each string are different.
//Else sort as string
if (int_a >= 0 &&
int_b >= 0 &&
int_a != int_b) {
return int_a<int_b;
}
else {
return str_a<str_b;
}
}

View File

@@ -32,6 +32,8 @@ namespace QETUtils
QMargins marginsFromString(const QString &string); QMargins marginsFromString(const QString &string);
qreal graphicsHandlerSize(QGraphicsItem *item); qreal graphicsHandlerSize(QGraphicsItem *item);
bool sortBeginIntString(const QString &str_a, const QString &str_b);
template <typename T> template <typename T>
QVector<QWeakPointer<T>> sharedVectorToWeak(const QVector<QSharedPointer<T>> &vector) QVector<QWeakPointer<T>> sharedVectorToWeak(const QVector<QSharedPointer<T>> &vector)
{ {