diff --git a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp
new file mode 100644
index 000000000..663683a7e
--- /dev/null
+++ b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp
@@ -0,0 +1,77 @@
+/*
+ Copyright 2006-2021 The QElectroTech Team
+ This file is part of QElectroTech.
+
+ QElectroTech is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ QElectroTech is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QElectroTech. If not, see .
+*/
+#include "bridgeterminalscommand.h"
+#include "../terminalstrip.h"
+
+BridgeTerminalsCommand::BridgeTerminalsCommand(TerminalStrip *strip,
+ QVector real_terminal_uuid,
+ QUndoCommand *parent):
+ QUndoCommand(parent),
+ m_strip(strip),
+ m_uuid_vector(real_terminal_uuid)
+{
+ setText(QObject::tr("Ponter des bornes entre-elles"));
+}
+
+void BridgeTerminalsCommand::undo()
+{
+ if (m_strip) {
+ m_strip->unBridge(m_uuid_vector);
+ }
+}
+
+void BridgeTerminalsCommand::redo()
+{
+ if (m_strip) {
+ m_strip->setBridge(m_uuid_vector);
+ }
+}
+
+UnBridgeTerminalsCommand::UnBridgeTerminalsCommand(TerminalStrip *strip,
+ QVector real_terminal_uuid,
+ QUndoCommand *parent):
+ QUndoCommand(parent),
+ m_strip(strip)
+{
+ setText(QObject::tr("Supprimer des ponts de bornes"));
+
+ for (const auto &t_uuid : real_terminal_uuid)
+ {
+ auto bridge = m_strip->bridgeFor(t_uuid);
+ if (bridge) {
+ m_bridge_terminal_map.insert(bridge->uuid_, t_uuid);
+ }
+ }
+}
+
+void UnBridgeTerminalsCommand::undo()
+{
+ if (m_strip) {
+ for (const auto &bridge_uuid : m_bridge_terminal_map.uniqueKeys()) {
+ auto terminal_list = m_bridge_terminal_map.values(bridge_uuid);
+ m_strip->setBridge(bridge_uuid, terminal_list.toVector());
+ }
+ }
+}
+
+void UnBridgeTerminalsCommand::redo()
+{
+ if (m_strip) {
+ m_strip->unBridge(m_bridge_terminal_map.values().toVector());
+ }
+}
diff --git a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h
new file mode 100644
index 000000000..03a6e8b17
--- /dev/null
+++ b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h
@@ -0,0 +1,69 @@
+/*
+ Copyright 2006-2021 The QElectroTech Team
+ This file is part of QElectroTech.
+
+ QElectroTech is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ QElectroTech is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QElectroTech. If not, see .
+*/
+#ifndef BRIDGETERMINALSCOMMAND_H
+#define BRIDGETERMINALSCOMMAND_H
+
+#include
+#include
+#include
+#include
+#include
+
+class TerminalStrip;
+
+/**
+ * @brief The BridgeTerminalsCommand class
+ * UndoCommand use to create bridge betwen terminals
+ * of a terminals strip
+ */
+class BridgeTerminalsCommand : public QUndoCommand
+{
+ public:
+ BridgeTerminalsCommand(TerminalStrip *strip, QVector real_terminal_uuid, QUndoCommand *parent = nullptr);
+ ~BridgeTerminalsCommand() override {}
+
+ void undo() override;
+ void redo() override;
+
+ private:
+ QPointer m_strip;
+ QVector m_uuid_vector;
+};
+
+
+/**
+ * @brief The UnBridgeTerminalsCommand class
+ * UndoCommand use to remove bridge betwen terminals
+ * of a terminals strip
+ */
+class UnBridgeTerminalsCommand : public QUndoCommand
+{
+ public:
+ UnBridgeTerminalsCommand(TerminalStrip *strip, QVector real_terminal_uuid, QUndoCommand *parent = nullptr);
+ ~UnBridgeTerminalsCommand() override{}
+
+ void undo() override;
+ void redo() override;
+
+ private:
+ QPointer m_strip;
+ QMultiMap m_bridge_terminal_map; ///Key is bridge uuid, value is real terminal uuid
+
+};
+
+#endif // BRIDGETERMINALSCOMMAND_H
diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp
index 02fac72e9..657f0c013 100644
--- a/sources/TerminalStrip/terminalstrip.cpp
+++ b/sources/TerminalStrip/terminalstrip.cpp
@@ -39,6 +39,7 @@ using shared_physical_terminal = QSharedPointer;
* A real terminal can be a drawed terminal in a folio
* or a terminal set by user but not present
* on any folio (for example a reserved terminal).
+ * @sa RealTerminalData
*/
class RealTerminal
{
@@ -79,7 +80,7 @@ class RealTerminal
if (!m_element.isNull()) {
return m_element->actualLabel();
} else {
- return QStringLiteral("");
+ return QLatin1String();
}
}
@@ -198,11 +199,11 @@ class RealTerminal
/**
* @brief The PhysicalTerminal class
* Represent a physical terminal.
- * A physical terminal is composed a least by one real terminal.
+ * A physical terminal is composed a least by one RealTerminal.
* When a physical terminal have more than one real terminal
* that mean the physical terminal have levels (one by real terminal).
- * The index of terminals returned by the function terminals()
- * is the same as the real level of the physical terminal, the index are from back to front.
+ * The index of real terminals returned by the function terminals()
+ * is the same as the real level of the real terminal, the index are from back to front.
*
* Example for a 3 levels terminal.
* index 0 = back (mounting plate)
@@ -224,6 +225,8 @@ class RealTerminal
* t |_|
* e
*
+ * @sa PhysicalTerminalData
+ *
*/
class PhysicalTerminal
{
@@ -243,9 +246,9 @@ class PhysicalTerminal
/**
* @brief setTerminals
- * Set the real terminal of this physical terminal
- * the order of the terminal in \p terminals represent
- * the level index.
+ * Set the RealTerminal who compose this physical terminal.
+ * The position of the RealTerminal in @a terminals
+ * represent the level of these in this physical terminal.
* @param terminals
*/
void setTerminals(QVector terminals) {
@@ -254,7 +257,7 @@ class PhysicalTerminal
/**
* @brief addTerminals
- * Append the real terminal \p terminal
+ * Append the real terminal @a terminal
* to this physical terminal.
* @param terminal
*/
@@ -264,7 +267,7 @@ class PhysicalTerminal
/**
* @brief removeTerminal
- * Remove \p terminal from the list of real terminal
+ * Remove @a terminal from the list of real terminal
* @param terminal
* @return true if sucessfully removed
*/
@@ -314,7 +317,7 @@ class PhysicalTerminal
/**
* @brief terminals
- * @return A vector of real terminal who compose this physical terminal
+ * @return A vector of RealTerminal who compose this PhysicalTerminal
*/
QVector terminals() const {
return m_real_terminal;
@@ -415,7 +418,7 @@ TerminalStripData TerminalStrip::data() const {
/**
* @brief TerminalStrip::setData
- * The internal data of this strip to data.
+ * Set the internal data of this strip to @a data.
* the uuid of the new data is set to the uuid
* of the previous data to keep the uuid
* of the terminal strip unchanged
@@ -726,6 +729,192 @@ bool TerminalStrip::setLevel(const RealTerminalData &real_terminal_data, int lev
return false;
}
+/**
+ * @brief TerminalStrip::isBridgeable
+ * Check if all realTerminal represented by the uuid of @a real_terminals_uuid are bridgeable together.
+ * To be bridgeable, each real terminal must belong to this terminal strip
+ * be at the same level, be consecutive and not belong to the same physicalTerminal
+ * and at least one terminal must be not bridged
+ * @param real_terminals_uuid : a vector of RealTerminal uuid
+ * @sa member real_terminal_uuid of struct RealTerminalData
+ * @return
+ */
+bool TerminalStrip::isBridgeable(const QVector &real_terminals_uuid) const
+{
+ if (real_terminals_uuid.size() < 2) {
+ return false;
+ }
+
+ // Check if first terminal belong to this strip
+ auto first_real_terminal = realTerminalForUuid(real_terminals_uuid.first());
+ if (!first_real_terminal) {
+ return false;
+ }
+ // Get the level of the first terminal
+ int level_ = realTerminalData(first_real_terminal).level_;
+ // Get the physical terminal and pos
+ auto first_physical_terminal = physicalTerminal(first_real_terminal);
+ QVector physical_vector{first_physical_terminal};
+ QVector pos_vector{m_physical_terminals.indexOf(first_physical_terminal)};
+
+ auto bridge_ = isBridged(first_real_terminal);
+ //bool to know at the end of this function if at least one terminal is not bridged
+ bool no_bridged = bridge_ ? false : true;
+
+ // Check for each terminals
+ for (int i=1 ; i &real_terminals_uuid)
+{
+ if (!isBridgeable(real_terminals_uuid)) {
+ return false;
+ }
+ QVector real_terminals_vector;
+
+ for (const auto & uuid_ : real_terminals_uuid) {
+ auto real_t = realTerminalForUuid(uuid_);
+ if (real_t)
+ real_terminals_vector << real_t;
+ }
+
+ auto bridge = bridgeFor(real_terminals_vector);
+ if (bridge.isNull()) {
+ bridge = QSharedPointer::create();
+ m_bridge.append(bridge);
+ }
+
+ for (const auto &real_t : qAsConst(real_terminals_vector))
+ {
+ if (!bridge->real_terminals.contains(real_t))
+ bridge->real_terminals.append(real_t);
+ }
+
+ emit bridgeChanged();
+ return true;
+}
+
+/**
+ * @brief TerminalStrip::setBridge
+ * Bridge the RealTerminal with uuid in @a real_terminals_uuid to
+ * the bridge with uuid @a bridge_uuid.
+ * @param bridge_uuid
+ * @param real_terminals_uuid
+ * @return true if all RealTerminal was successfully bridged
+ */
+bool TerminalStrip::setBridge(const QUuid &bridge_uuid, const QVector &real_terminals_uuid)
+{
+ auto bridge_ = bridgeForUuid(bridge_uuid);
+ if (bridge_)
+ {
+ if (!isBridgeable(real_terminals_uuid)) {
+ return false;
+ }
+
+ bool b_ = false;
+ for (const auto & uuid_ : real_terminals_uuid)
+ {
+ auto real_t = realTerminalForUuid(uuid_);
+ if (real_t &&
+ !bridge_->real_terminals.contains(real_t))
+ {
+ bridge_->real_terminals.append(real_t);
+ b_ = true;
+ }
+ }
+
+ if (b_) {
+ emit bridgeChanged();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * @brief TerminalStrip::unBridge
+ * Unbridge all real terminal represented by they uuid
+ * @param real_terminals_uuid
+ */
+void TerminalStrip::unBridge(const QVector &real_terminals_uuid)
+{
+ for (const auto & uuid_ : real_terminals_uuid)
+ {
+ auto real_t = realTerminalForUuid(uuid_);
+ if (real_t)
+ {
+ auto bridge_ = isBridged(real_t);
+ if (bridge_)
+ bridge_->real_terminals.removeOne(real_t);
+ }
+ }
+
+ emit bridgeChanged();
+}
+
+/**
+ * @brief TerminalStrip::bridgeFor
+ * @param real_terminal_uuid
+ * @return
+ */
+QSharedPointer TerminalStrip::bridgeFor(const QUuid &real_terminal_uuid) const
+{
+ auto rt = realTerminalForUuid(real_terminal_uuid);
+ return bridgeFor(QVector{rt});
+}
+
/**
* @brief TerminalStrip::terminalElement
* @return A vector of all terminal element owned by this strip
@@ -849,7 +1038,7 @@ QSharedPointer TerminalStrip::physicalTerminal(QSharedPointer<
return pt;
}
-RealTerminalData TerminalStrip::realTerminalData(QSharedPointer real_terminal) const
+RealTerminalData TerminalStrip::realTerminalData(const QSharedPointer real_terminal) const
{
RealTerminalData rtd;
@@ -868,6 +1057,7 @@ RealTerminalData TerminalStrip::realTerminalData(QSharedPointer re
rtd.function_ = real_terminal->function();
rtd.led_ = real_terminal->led();
rtd.is_element = real_terminal->isElement();
+ rtd.is_bridged = isBridged(real_terminal);
return rtd;
}
@@ -912,3 +1102,67 @@ QSharedPointer TerminalStrip::realTerminalForUuid(const QUuid &uui
return return_rt;
}
+
+/**
+ * @brief TerminalStrip::isBridged
+ * Check if @a real_terminal is bridged
+ * @param real_terminal
+ * @return a pointer of TerminalStripBridge if bridget or a null QSharedPointer.
+ */
+QSharedPointer TerminalStrip::isBridged(const QSharedPointer real_terminal) const
+{
+ if (real_terminal)
+ {
+ for (const auto &bridge_ : qAsConst(m_bridge)) {
+ if (bridge_->real_terminals.contains(real_terminal))
+ return bridge_;
+ }
+ }
+ return QSharedPointer();
+}
+
+/**
+ * @brief TerminalStrip::bridgeFor
+ * Return the bridge where at least one terminal of @a terminal_vector belong.
+ * If several terminals are bridged but not to the same bridge return
+ * a TerminalStripBridge with 0 real_terminals_uuid_vector
+ * @sa TerminalStripBridge
+ * @param terminal_vector
+ * @return
+ */
+QSharedPointer TerminalStrip::bridgeFor(const QVector > &terminal_vector) const
+{
+ QSharedPointer return_bridge;
+
+ for (const auto &terminal : terminal_vector)
+ {
+ auto bridge_ = isBridged(terminal);
+ if (!bridge_.isNull())
+ {
+ if (return_bridge.isNull()) {
+ return_bridge = bridge_;
+ }
+ else if (return_bridge != bridge_) {
+ return QSharedPointer();
+ }
+ }
+ }
+
+ return return_bridge;
+}
+
+/**
+ * @brief TerminalStrip::bridgeForUuid
+ * @param bridge_uuid
+ * @return the bridge with uuid @a bridge_uuid or null QSharedPointer if not exist
+ */
+QSharedPointer TerminalStrip::bridgeForUuid(const QUuid &bridge_uuid)
+{
+ for (const auto &bridge : qAsConst(m_bridge)) {
+ if (bridge->uuid_ == bridge_uuid) {
+ return bridge;
+ }
+ }
+
+ return QSharedPointer();
+}
diff --git a/sources/TerminalStrip/terminalstrip.h b/sources/TerminalStrip/terminalstrip.h
index dd24cd5cb..837a01dc0 100644
--- a/sources/TerminalStrip/terminalstrip.h
+++ b/sources/TerminalStrip/terminalstrip.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
@@ -20,6 +20,8 @@
#include
#include
+#include
+
#include "terminalstripdata.h"
#include "../properties/elementdata.h"
@@ -31,7 +33,11 @@ class TerminalStripIndex;
class TerminalElement;
-
+/**
+ * @brief The RealTerminalData struct
+ * Conveniant struct to quickly get some values
+ * of a RealTerminal
+ */
struct RealTerminalData
{
int level_ = -1;
@@ -43,17 +49,24 @@ struct RealTerminalData
conductor_;
QUuid element_uuid,
- real_terminal_uuid;
+ real_terminal_uuid,
+ bridge_uuid;
ElementData::TerminalType type_;
ElementData::TerminalFunction function_;
bool led_ = false,
- is_element = false;
+ is_element = false,
+ is_bridged = false;
QPointer element_;
};
+/**
+ * @brief The PhysicalTerminalData struct
+ * Conveniant struct to quickly get some values
+ * of a PhysicalTerminal
+ */
struct PhysicalTerminalData
{
QVector real_terminals_vector;
@@ -70,12 +83,19 @@ inline uint qHash(const PhysicalTerminalData &key, uint seed) {
return qHash(key.uuid_, seed);
}
+struct TerminalStripBridge
+{
+ QVector> real_terminals;
+ QColor color_ = Qt::gray;
+ QUuid uuid_ = QUuid::createUuid();
+};
+
/**
* @brief The TerminalStrip class
* This class hold all the datas and configurations
* of a terminal strip (but the not the visual aspect).
* A terminal strip have some informations (name comment etc...)
- * and is composed by terminals (draw in a diagram or described in the terminal strip)
+ * and is composed by one or several PhysicalTerminal.
*/
class TerminalStrip : public QObject
{
@@ -86,6 +106,7 @@ class TerminalStrip : public QObject
public:
signals:
void orderChanged(); //Emitted when the order of the physical terminal is changed
+ void bridgeChanged();
public:
TerminalStrip(QETProject *project);
@@ -121,6 +142,11 @@ class TerminalStrip : public QObject
bool groupTerminals(const PhysicalTerminalData &receiver_terminal, const QVector &added_terminals);
void unGroupTerminals(const QVector &terminals_to_ungroup);
bool setLevel(const RealTerminalData &real_terminal_data, int level);
+ bool isBridgeable(const QVector &real_terminals_uuid) const;
+ bool setBridge(const QVector &real_terminals_uuid);
+ bool setBridge(const QUuid &bridge_uuid, const QVector &real_terminals_uuid);
+ void unBridge(const QVector &real_terminals_uuid);
+ QSharedPointer bridgeFor(const QUuid &real_terminal_uuid) const;
QVector> terminalElement() const;
@@ -131,9 +157,12 @@ class TerminalStrip : public QObject
private:
QSharedPointer realTerminal(Element *terminal);
QSharedPointer physicalTerminal(QSharedPointer terminal) const;
- RealTerminalData realTerminalData(QSharedPointer real_terminal) const;
+ RealTerminalData realTerminalData(const QSharedPointer real_terminal) const;
QSharedPointer physicalTerminalForUuid (const QUuid &uuid) const;
QSharedPointer realTerminalForUuid(const QUuid &uuid) const;
+ QSharedPointer isBridged(const QSharedPointer real_terminal) const;
+ QSharedPointer bridgeFor (const QVector> &terminal_vector) const;
+ QSharedPointer bridgeForUuid (const QUuid &bridge_uuid);
private:
TerminalStripData m_data;
@@ -141,6 +170,7 @@ class TerminalStrip : public QObject
QVector> m_terminal_elements_vector;
QVector> m_real_terminals;
QVector> m_physical_terminals;
+ QVector> m_bridge;
};
#endif // TERMINALSTRIP_H
diff --git a/sources/TerminalStrip/ui/terminalstripeditor.cpp b/sources/TerminalStrip/ui/terminalstripeditor.cpp
index 31aec27d5..fd9410a58 100644
--- a/sources/TerminalStrip/ui/terminalstripeditor.cpp
+++ b/sources/TerminalStrip/ui/terminalstripeditor.cpp
@@ -33,6 +33,7 @@
#include "../UndoCommand/sortterminalstripcommand.h"
#include "../UndoCommand/groupterminalscommand.h"
#include "../UndoCommand/changeterminallevel.h"
+#include "../UndoCommand/bridgeterminalscommand.h"
#include
@@ -49,6 +50,7 @@ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
ui->setupUi(this);
ui->m_table_widget->setItemDelegate(new TerminalStripModelDelegate(ui->m_terminal_strip_tw));
+
ui->m_remove_terminal_strip_pb->setDisabled(true);
buildTree();
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
@@ -56,13 +58,18 @@ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
#else
ui->m_terminal_strip_tw->expandAll();
#endif
+
+ //Setup the bridge color
+ QList bridge_color{Qt::red, Qt::blue, Qt::white, Qt::gray, Qt::black};
+ ui->m_bridge_color_cb->setColors(bridge_color);
+
setUpUndoConnections();
//Call for update the state of child widgets
selectionChanged();
//Go the diagram of double clicked terminal
- connect(ui->m_table_widget, &QAbstractItemView::doubleClicked, [this](const QModelIndex &index)
+ connect(ui->m_table_widget, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
{
Element *elmt = nullptr;
if (this->m_model->isXrefCell(index, &elmt))
@@ -75,7 +82,7 @@ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
{
auto fit_view = elmt->sceneBoundingRect();
fit_view.adjust(-200,-200,200,200);
- diagram->views().first()->fitInView(fit_view, Qt::KeepAspectRatioByExpanding);
+ diagram->views().at(0)->fitInView(fit_view, Qt::KeepAspectRatioByExpanding);
}
}
}
@@ -91,8 +98,8 @@ TerminalStripEditor::~TerminalStripEditor() {
void TerminalStripEditor::setUpUndoConnections()
{
- connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalAddedToStrip,
- [this](QUuid terminal_uuid, QUuid strip_uuid)
+ connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalAddedToStrip, this,
+ [=](QUuid terminal_uuid, QUuid strip_uuid)
{
auto terminal = m_uuid_terminal_H.value(terminal_uuid);
auto strip = m_uuid_strip_H.value(strip_uuid);
@@ -105,8 +112,8 @@ void TerminalStripEditor::setUpUndoConnections()
m_project->undoStack()->push(undo);
});
- connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalMovedFromStripToStrip,
- [this] (QUuid terminal_uuid, QUuid old_strip_uuid, QUuid new_strip_uuid)
+ connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalMovedFromStripToStrip, this,
+ [=] (QUuid terminal_uuid, QUuid old_strip_uuid, QUuid new_strip_uuid)
{
auto terminal = m_uuid_terminal_H.value(terminal_uuid);
auto old_strip = m_uuid_strip_H.value(old_strip_uuid);
@@ -120,8 +127,8 @@ void TerminalStripEditor::setUpUndoConnections()
m_project->undoStack()->push(undo);
});
- connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalRemovedFromStrip,
- [this] (QUuid terminal_uuid, QUuid old_strip_uuid)
+ connect(ui->m_terminal_strip_tw, &TerminalStripTreeWidget::terminalRemovedFromStrip, this,
+ [=] (QUuid terminal_uuid, QUuid old_strip_uuid)
{
auto terminal_ = m_uuid_terminal_H.value(terminal_uuid);
auto strip_ = m_uuid_strip_H.value(old_strip_uuid);
@@ -286,6 +293,7 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
if (m_current_strip) {
disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked);
+ disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked);
}
if (!strip_)
@@ -317,10 +325,12 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
m_model = new TerminalStripModel(strip_, this);
ui->m_table_widget->setModel(m_model);
+ setUpBridgeCellWidth();
spanMultiLevelTerminals();
selectionChanged(); //Used to update child widgets
connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked);
+ connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked);
connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged);
}
}
@@ -361,6 +371,10 @@ void TerminalStripEditor::selectionChanged()
ui->m_type_cb ->setDisabled(true);
ui->m_function_cb ->setDisabled(true);
ui->m_led_cb ->setDisabled(true);
+
+ ui->m_bridge_terminals_pb ->setDisabled(true);
+ ui->m_unbridge_terminals_pb->setDisabled(true);
+ ui->m_bridge_color_cb ->setDisabled(true);
return;
}
@@ -378,13 +392,14 @@ void TerminalStripEditor::selectionChanged()
ui->m_led_cb ->setEnabled(true);
}
- const auto terminal_vector = m_model->physicalTerminalDataForIndex(index_list);
+ const auto physical_terminal_vector = m_model->physicalTerminalDataForIndex(index_list);
+ const auto real_terminal_vector = m_model->realTerminalDataForIndex(index_list);
//Enable/disable group button
- ui->m_group_terminals_pb->setEnabled(terminal_vector.size() > 1 ? true : false);
+ ui->m_group_terminals_pb->setEnabled(physical_terminal_vector.size() > 1 ? true : false);
//Enable/disable ungroup button
- auto it_= std::find_if(terminal_vector.constBegin(), terminal_vector.constEnd(), [](const PhysicalTerminalData &data)
+ auto it_= std::find_if(physical_terminal_vector.constBegin(), physical_terminal_vector.constEnd(), [](const PhysicalTerminalData &data)
{
if (data.real_terminals_vector.size() >= 2) {
return true;
@@ -392,11 +407,11 @@ void TerminalStripEditor::selectionChanged()
return false;
}
});
- ui->m_ungroup_pb->setDisabled(it_ == terminal_vector.constEnd());
+ ui->m_ungroup_pb->setDisabled(it_ == physical_terminal_vector.constEnd());
//Enable/disable level spinbox
bool enable_ = false;
- for (const auto &physical : terminal_vector)
+ for (const auto &physical : physical_terminal_vector)
{
if (physical.real_terminals_vector.size() > 1) {
enable_ = true;
@@ -404,6 +419,91 @@ void TerminalStripEditor::selectionChanged()
}
}
ui->m_level_sb->setEnabled(enable_);
+
+ //Enable/disable bridge and unbridge
+ bool enable_bridge = false;
+ bool enable_unbridge = false;
+
+ //One column must be selected and the column must be a level column
+ int level_ = TerminalStripModel::levelForColumn(isSingleColumnSelected());
+ if (level_ >= 0)
+ {
+ //Select only terminals of corresponding level cell selection
+ QVector real_terminal_level_vector;
+ for (const auto &rtd : real_terminal_vector) {
+ if (rtd.level_ == level_) {
+ real_terminal_level_vector.append(rtd);
+ }
+ }
+
+ QVector uuid_v;
+ for (const auto &rtd : real_terminal_level_vector) {
+ uuid_v << rtd.real_terminal_uuid;
+ }
+ if (m_current_strip) {
+ enable_bridge = m_current_strip->isBridgeable(uuid_v);
+ }
+
+ for (const auto &rtd : real_terminal_level_vector)
+ {
+ if (rtd.is_bridged &&
+ rtd.level_ == level_) {
+ enable_unbridge = true;
+ break;
+ }
+ }
+ }
+ ui->m_bridge_terminals_pb->setEnabled(enable_bridge);
+ ui->m_unbridge_terminals_pb->setEnabled(enable_unbridge);
+}
+
+void TerminalStripEditor::setUpBridgeCellWidth()
+{
+ if (ui->m_table_widget->verticalHeader() &&
+ m_model)
+ {
+ auto section_size = ui->m_table_widget->verticalHeader()->defaultSectionSize();
+ auto h_header = ui->m_table_widget->horizontalHeader();
+
+ h_header->setSectionResizeMode(2, QHeaderView::Fixed);
+ h_header->resizeSection(2, section_size);
+ h_header->setSectionResizeMode(3, QHeaderView::Fixed);
+ h_header->resizeSection(3, section_size);
+ h_header->setSectionResizeMode(4, QHeaderView::Fixed);
+ h_header->resizeSection(4, section_size);
+ h_header->setSectionResizeMode(5, QHeaderView::Fixed);
+ h_header->resizeSection(5, section_size);
+ }
+}
+
+/**
+ * @brief TerminalStripEditor::isSingleColumnSelected
+ * If all current QModelIndex are in the same column
+ * return the column type
+ * @sa TerminalStripModel::Column
+ * @return
+ */
+TerminalStripModel::Column TerminalStripEditor::isSingleColumnSelected() const
+{
+ if (m_current_strip &&
+ ui->m_table_widget->selectionModel())
+ {
+ const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
+ if (index_list.isEmpty()) {
+ return TerminalStripModel::Invalid;
+ }
+
+ auto column_ = index_list.first().column();
+ for (const auto &index : index_list) {
+ if (index.column() != column_) {
+ return TerminalStripModel::Invalid;
+ }
+ }
+
+ return TerminalStripModel::columnTypeForIndex(index_list.first());
+ }
+
+ return TerminalStripModel::Invalid;
}
/**
@@ -617,7 +717,7 @@ void TerminalStripEditor::on_m_level_sb_valueChanged(int arg1)
for (auto index : index_list)
{
- auto level_index = m_model->index(index.row(), 1, index.parent());
+ auto level_index = m_model->index(index.row(), TerminalStripModel::Level, index.parent());
if (level_index.isValid())
{
m_model->setData(level_index, arg1);
@@ -634,7 +734,7 @@ void TerminalStripEditor::on_m_type_cb_activated(int index)
for (auto model_index : index_list)
{
- auto type_index = m_model->index(model_index.row(), 6, model_index.parent());
+ auto type_index = m_model->index(model_index.row(), TerminalStripModel::Type, model_index.parent());
if (type_index.isValid())
{
ElementData::TerminalType override_type;
@@ -667,7 +767,7 @@ void TerminalStripEditor::on_m_function_cb_activated(int index)
for (auto model_index : index_list)
{
- auto function_index = m_model->index(model_index.row(), 7, model_index.parent());
+ auto function_index = m_model->index(model_index.row(), TerminalStripModel::Function, model_index.parent());
if (function_index.isValid())
{
ElementData::TerminalFunction override_function;
@@ -696,7 +796,7 @@ void TerminalStripEditor::on_m_led_cb_activated(int index)
for (auto model_index : index_list)
{
- auto led_index = m_model->index(model_index.row(), 8, model_index.parent());
+ auto led_index = m_model->index(model_index.row(), TerminalStripModel::Led, model_index.parent());
if (led_index.isValid()) {
m_model->setData(led_index,
@@ -706,3 +806,72 @@ void TerminalStripEditor::on_m_led_cb_activated(int index)
}
}
+/**
+ * @brief TerminalStripEditor::on_m_bridge_terminals_pb_clicked
+ */
+void TerminalStripEditor::on_m_bridge_terminals_pb_clicked()
+{
+ if (m_current_strip)
+ {
+ int level_ = isSingleColumnSelected();
+ if (level_ >= TerminalStripModel::Level0 &&
+ level_ <= TerminalStripModel::Level3)
+ {
+ if(level_ == TerminalStripModel::Level0){level_ = 0;}
+ else if(level_ == TerminalStripModel::Level1){level_ = 1;}
+ else if(level_ == TerminalStripModel::Level2){level_ = 2;}
+ else if(level_ == TerminalStripModel::Level3){level_ = 3;}
+
+ const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
+ const auto rtd_vector = m_model->realTerminalDataForIndex(index_list);
+ QVector uuid_vector;
+ for (const auto &rtd : rtd_vector)
+ {
+ if (rtd.level_ == level_) {
+ uuid_vector.append(rtd.real_terminal_uuid);
+ }
+ }
+ if (m_current_strip->isBridgeable(uuid_vector)) {
+ m_project->undoStack()->push(new BridgeTerminalsCommand(m_current_strip, uuid_vector));
+ }
+ }
+ }
+}
+
+/**
+ * @brief TerminalStripEditor::on_m_unbridge_terminals_pb_clicked
+ */
+void TerminalStripEditor::on_m_unbridge_terminals_pb_clicked()
+{
+ if (m_current_strip)
+ {
+ int level_ = isSingleColumnSelected();
+ if (level_ >= TerminalStripModel::Level0 &&
+ level_ <= TerminalStripModel::Level3)
+ {
+ if(level_ == TerminalStripModel::Level0){level_ = 0;}
+ else if(level_ == TerminalStripModel::Level1){level_ = 1;}
+ else if(level_ == TerminalStripModel::Level2){level_ = 2;}
+ else if(level_ == TerminalStripModel::Level3){level_ = 3;}
+
+ const auto index_list = ui->m_table_widget->selectionModel()->selectedIndexes();
+ const auto rtd_vector = m_model->realTerminalDataForIndex(index_list);
+ QVector uuid_vector;
+ for (const auto &rtd : rtd_vector)
+ {
+ if (rtd.level_ == level_
+ && rtd.is_bridged) {
+ uuid_vector.append(rtd.real_terminal_uuid);
+ }
+ }
+ m_project->undoStack()->push(new UnBridgeTerminalsCommand(m_current_strip, uuid_vector));
+ }
+ }
+}
+
+
+void TerminalStripEditor::on_m_bridge_color_cb_activated(const QColor &col)
+{
+
+}
+
diff --git a/sources/TerminalStrip/ui/terminalstripeditor.h b/sources/TerminalStrip/ui/terminalstripeditor.h
index 05f9eaa1e..df07b5acf 100644
--- a/sources/TerminalStrip/ui/terminalstripeditor.h
+++ b/sources/TerminalStrip/ui/terminalstripeditor.h
@@ -20,6 +20,8 @@
#include
+#include "terminalstripmodel.h"
+
namespace Ui {
class TerminalStripEditor;
}
@@ -29,7 +31,6 @@ class TerminalStrip;
class QTreeWidgetItem;
class TerminalElement;
class QAbstractButton;
-class TerminalStripModel;
/**
* @brief The TerminalStripEditor class
@@ -52,6 +53,8 @@ class TerminalStripEditor : public QDialog
void setCurrentStrip(TerminalStrip *strip_);
void spanMultiLevelTerminals();
void selectionChanged();
+ void setUpBridgeCellWidth();
+ TerminalStripModel::Column isSingleColumnSelected() const;
private slots:
void on_m_add_terminal_strip_pb_clicked();
@@ -66,6 +69,9 @@ class TerminalStripEditor : public QDialog
void on_m_type_cb_activated(int index);
void on_m_function_cb_activated(int index);
void on_m_led_cb_activated(int index);
+ void on_m_bridge_terminals_pb_clicked();
+ void on_m_unbridge_terminals_pb_clicked();
+ void on_m_bridge_color_cb_activated(const QColor &col);
private:
Ui::TerminalStripEditor *ui;
diff --git a/sources/TerminalStrip/ui/terminalstripeditor.ui b/sources/TerminalStrip/ui/terminalstripeditor.ui
index e31862a37..410adace0 100644
--- a/sources/TerminalStrip/ui/terminalstripeditor.ui
+++ b/sources/TerminalStrip/ui/terminalstripeditor.ui
@@ -178,34 +178,14 @@
-
-
-
-
+
-
+
- Type :
+ Étage :
- -
-
-
- Degrouper les bornes
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
+
-
-
@@ -234,10 +214,96 @@
- -
-
+
-
+
+
+ LED :
+
+
-
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Position automatique
+
+
+
+ -
+
+
+ Fonction :
+
+
+
+ -
+
+
+ Couleur pont :
+
+
+
+ -
+
+
+ Grouper les bornes
+
+
+
+ -
+
+
+ Degrouper les bornes
+
+
+
+ -
+
+
+ Type :
+
+
+
+ -
+
+
-
+
+ Sans
+
+
+ -
+
+ Avec
+
+
+
+
+ -
+
+
+ -
-
@@ -256,52 +322,17 @@
- -
-
+
-
+
- Position automatique
+ Ponter les bornes
- -
-
+
-
+
- Étage :
-
-
-
- -
-
-
- Grouper les bornes
-
-
-
- -
-
-
- Fonction :
-
-
-
- -
-
-
-
-
- Sans
-
-
- -
-
- Avec
-
-
-
-
- -
-
-
- LED :
+ Déponter les bornes
@@ -375,6 +406,11 @@
+
+ KColorCombo
+ QComboBox
+
+
TerminalStripTreeWidget
QTreeWidget
diff --git a/sources/TerminalStrip/ui/terminalstripmodel.cpp b/sources/TerminalStrip/ui/terminalstripmodel.cpp
index fb873db10..5bed80079 100644
--- a/sources/TerminalStrip/ui/terminalstripmodel.cpp
+++ b/sources/TerminalStrip/ui/terminalstripmodel.cpp
@@ -23,25 +23,77 @@
#include
#include
#include
+#include
/**
* Some const int who describe what a column contain
*/
const int POS_CELL = 0;
const int LEVEL_CELL = 1;
-const int LABEL_CELL = 2;
-const int XREF_CELL = 3;
-const int CABLE_CELL = 4;
-const int CABLE_WIRE_CELL = 5;
-const int TYPE_CELL = 6;
-const int FUNCTION_CELL = 7;
-const int LED_CELL = 8;
-const int CONDUCTOR_CELL = 9;
+const int LEVEL_0_CELL = 2;
+const int LEVEL_1_CELL = 3;
+const int LEVEL_2_CELL = 4;
+const int LEVEL_3_CELL = 5;
+const int LABEL_CELL = 6;
+const int XREF_CELL = 7;
+const int CABLE_CELL = 8;
+const int CABLE_WIRE_CELL = 9;
+const int TYPE_CELL = 10;
+const int FUNCTION_CELL = 11;
+const int LED_CELL = 12;
+const int CONDUCTOR_CELL = 13;
-const int ROW_COUNT = 9;
+const int ROW_COUNT = 13;
-static QVector UNMODIFIED_CELL_VECTOR{false, false, false, false, false, false, false, false, false, false};
+static QVector UNMODIFIED_CELL_VECTOR{false, false, false, false, false, false, false, false, false, false, false, false, false, false};
+/**
+ * @brief TerminalStripModel::levelForColumn
+ * Return the terminal level for column @a column
+ * or -1 if column is not a level column
+ * @param column
+ * @return
+ */
+int TerminalStripModel::levelForColumn(Column column)
+{
+ switch (column) {
+ case Level0: return 0;
+ case Level1: return 1;
+ case Level2: return 2;
+ case Level3: return 3;
+ default: return -1;
+ }
+}
+
+/**
+ * @brief TerminalStripModel::columnTypeForIndex
+ * @param index
+ * @return the thing (pos, level, type, function etc...) for @a index
+ */
+TerminalStripModel::Column TerminalStripModel::columnTypeForIndex(const QModelIndex &index)
+{
+ if (index.isValid())
+ {
+ switch (index.column()) {
+ case 0: return Pos;
+ case 1: return Level;
+ case 2 : return Level0;
+ case 3 : return Level1;
+ case 4 : return Level2;
+ case 5 : return Level3;
+ case 6 : return Label;
+ case 7 : return XRef;
+ case 8 : return Cable;
+ case 9 : return CableWire;
+ case 10 : return Type;
+ case 11 : return Function;
+ case 12 : return Led;
+ case 13 : return Conductor;
+ default : return Invalid;
+ }
+ }
+ return Invalid;
+}
/**
* @brief TerminalStripModel::TerminalStripModel
@@ -91,6 +143,18 @@ QVariant TerminalStripModel::data(const QModelIndex &index, int role) const
switch (index.column()) {
case POS_CELL : return physicalDataAtIndex(index.row()).pos_;
case LEVEL_CELL : return rtd.level_;
+ case LEVEL_0_CELL :
+ if (rtd.level_ == 0 && rtd.is_bridged) return "0";
+ break;
+ case LEVEL_1_CELL :
+ if (rtd.level_ == 1 && rtd.is_bridged) return "0";
+ break;
+ case LEVEL_2_CELL :
+ if (rtd.level_ == 2 && rtd.is_bridged) return "0";
+ break;
+ case LEVEL_3_CELL :
+ if (rtd.level_ == 3 && rtd.is_bridged) return "0";
+ break;
case LABEL_CELL : return rtd.label_;
case XREF_CELL : return rtd.Xref_;
case CABLE_CELL : return rtd.cable_;
@@ -202,6 +266,10 @@ QVariant TerminalStripModel::headerData(int section, Qt::Orientation orientation
switch (section) {
case POS_CELL: return tr("Position");
case LEVEL_CELL: return tr("Étage");
+ case LEVEL_0_CELL: return QStringLiteral("0");
+ case LEVEL_1_CELL: return QStringLiteral("1");
+ case LEVEL_2_CELL: return QStringLiteral("2");
+ case LEVEL_3_CELL: return QStringLiteral("3");
case LABEL_CELL: return tr("Label");
case XREF_CELL: return tr("Référence croisé");
case CABLE_CELL: return tr("Câble");
@@ -284,6 +352,40 @@ bool TerminalStripModel::isXrefCell(const QModelIndex &index, Element **element)
return false;
}
+/**
+ * @brief TerminalStripModel::levelCellCount
+ * Check for each index of @a index_list if the cell represented by the index
+ * is a level cell (level 0 to level 3) and if the corresponding real terminal is in the same level
+ *
+ * The returned vector contain how many index has matched
+ * the vector have 4 int,
+ * the first int is the number of matched level 0
+ * the second int is the number of matched level 1
+ * the third int is the number of matched level 2
+ * the fourth int is the number of matched level 4
+ * @param index_list
+ * @return
+ */
+QVector TerminalStripModel::levelCellCount(const QModelIndexList &index_list) const
+{
+ QVector vector_(4,0);
+
+ for (const auto &index : index_list)
+ {
+ if(index.isValid())
+ {
+ const auto rtd_ = realDataAtIndex(index.row());
+ const auto level_ = rtd_.level_;
+ const auto index_column = index.column();
+ if (level_ + 2 == index_column) {
+ vector_.replace(level_, vector_.at(level_)+1);
+ }
+ }
+ }
+
+ return vector_;
+}
+
/**
* @brief TerminalStripModel::terminalsForIndex
* @param index_list
diff --git a/sources/TerminalStrip/ui/terminalstripmodel.h b/sources/TerminalStrip/ui/terminalstripmodel.h
index 25a06a057..4eb1d1f0c 100644
--- a/sources/TerminalStrip/ui/terminalstripmodel.h
+++ b/sources/TerminalStrip/ui/terminalstripmodel.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright 2006-2021 The QElectroTech Team
This file is part of QElectroTech.
@@ -30,6 +30,28 @@ class TerminalStrip;
class TerminalStripModel : public QAbstractTableModel
{
+ public:
+ enum Column {
+ Pos = 0,
+ Level = 1,
+ Level0 = 2,
+ Level1 = 3,
+ Level2 = 4,
+ Level3 = 5,
+ Label = 6,
+ XRef = 7,
+ Cable = 8,
+ CableWire = 9,
+ Type = 10,
+ Function = 11,
+ Led = 12,
+ Conductor = 13,
+ Invalid = 99
+ };
+
+ static int levelForColumn(TerminalStripModel::Column column);
+ static TerminalStripModel::Column columnTypeForIndex(const QModelIndex &index);
+
Q_OBJECT
public:
TerminalStripModel(TerminalStrip *terminal_strip, QObject *parent = nullptr);
@@ -40,10 +62,10 @@ class TerminalStripModel : public QAbstractTableModel
virtual bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
virtual Qt::ItemFlags flags (const QModelIndex &index) const override;
-
QVector> modifiedRealTerminalData() const;
bool isXrefCell(const QModelIndex &index, Element **element = nullptr);
+ QVector levelCellCount(const QModelIndexList &index_list) const;
QVector physicalTerminalDataForIndex(QModelIndexList index_list) const;
QVector realTerminalDataForIndex(QModelIndexList index_list) const;
@@ -58,6 +80,10 @@ class TerminalStripModel : public QAbstractTableModel
QPointer m_terminal_strip;
QVector m_edited_terminal_data, m_original_terminal_data;
QHash> m_modified_cell;
+ QPixmap m_bridge_top,
+ m_bride_bottom,
+ m_bridge,
+ m_bride_both;
};
class TerminalStripModelDelegate : public QStyledItemDelegate