diff --git a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp index 7c3a19b61..ebab33488 100644 --- a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp +++ b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp @@ -49,32 +49,23 @@ UnBridgeTerminalsCommand::UnBridgeTerminalsCommand(TerminalStrip *strip, { setText(QObject::tr("Supprimer des ponts de bornes")); - for (const auto &real_t : real_terminal) + if (strip->canUnBridge(real_terminal)) { - auto bridge_ = strip->bridgeFor(real_t); - if (bridge_) { - m_bridge_terminal_hash.insert(bridge_.toWeakRef(), real_t); - } + m_terminals = real_terminal; + m_bridge = strip->bridgeFor(real_terminal.first()); } } void UnBridgeTerminalsCommand::undo() { - if (m_strip) - { - for (const auto &bridge_ : m_bridge_terminal_hash.uniqueKeys()) - { - if (!bridge_.isNull()) { - auto terminal_list = m_bridge_terminal_hash.values(bridge_); - m_strip->setBridge(bridge_.toStrongRef() , terminal_list.toVector()); - } - } + if (m_strip && m_bridge) { + m_strip->setBridge(m_bridge.toStrongRef(), m_terminals); } } void UnBridgeTerminalsCommand::redo() { if (m_strip) { - m_strip->unBridge(m_bridge_terminal_hash.values().toVector()); + m_strip->unBridge(m_terminals); } } diff --git a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h index 96f1c795a..424384b05 100644 --- a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h +++ b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.h @@ -61,8 +61,8 @@ class UnBridgeTerminalsCommand : public QUndoCommand private: QPointer m_strip; - QMultiHash, QWeakPointer> m_bridge_terminal_hash; ///Key a is bridge, value is real terminal - + QWeakPointer m_bridge; + QVector> m_terminals; }; #endif // BRIDGETERMINALSCOMMAND_H diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp index 6dc4c2a7a..7f22aa964 100644 --- a/sources/TerminalStrip/terminalstrip.cpp +++ b/sources/TerminalStrip/terminalstrip.cpp @@ -883,20 +883,85 @@ bool TerminalStrip::setBridge(const QSharedPointer &bridge, /** * @brief TerminalStrip::unBridge - * Unbridge all real terminal of @a real_terminals - * @param real_terminals_uuid + * Unbridge all real terminals of @a real_terminals + * @sa TerminalStrip::canUnBridge + * @param real_terminals */ void TerminalStrip::unBridge(const QVector> &real_terminals) { - for (const auto &real_t : qAsConst(real_terminals)) + if (canUnBridge(real_terminals)) { - auto bridge_ = bridgeFor(real_t); - if (bridge_) { + auto bridge_ = isBridged(real_terminals.first().toStrongRef()); + for (const auto &real_t : qAsConst(real_terminals)) { bridge_->real_terminals.removeOne(real_t.toStrongRef()); } + + emit bridgeChanged(); + } +} + +/** + * @brief TerminalStrip::canUnBridge + * @param m_real_terminals + * @return True if all terminals of @a real_terminals can be unbridged. + * For this method return True, all terminals must be bridged together, + * be consecutive and in an one or the both extremities of the bridge. + */ +bool TerminalStrip::canUnBridge(const QVector > &real_terminals) const +{ + if (real_terminals.isEmpty()) { + return false; + } + + //Get the bridge of first terminal + const auto compar_bridge = isBridged(real_terminals.first().toStrongRef()); + if (compar_bridge) + { + QMap> sorted_terminal; + + //Check if all terminals are bridged and if it's the same bridge. + //If true insert the terminal in sorted_terminal QMap + //with for key the position of the parent physical terminal + for (const auto &real_t : real_terminals) { + if (compar_bridge != isBridged(real_t.toStrongRef())) { + return false; + } else { + sorted_terminal.insert(m_physical_terminals.indexOf(physicalTerminal(real_t.toStrongRef())), + real_t); + } + } + + //Check if consecutive + const auto count_ = sorted_terminal.size(); + const auto min_max = std::minmax_element(sorted_terminal.keyBegin(), sorted_terminal.keyEnd()); + if ((*min_max.second - *min_max.first) + 1 != count_) { + return false; + } + + //Check if first terminal is the begin of bridge + const auto previous_real_t = previousTerminalInLevel(sorted_terminal.first()); + if (previous_real_t.isNull()) + return true; + else { + const auto previous_bridge = isBridged(previous_real_t.realTerminal()); + if (compar_bridge != previous_bridge) { + return true; + } + } + + //Check if last terminal is the end of bridge + const auto next_real_t = nextTerminalInLevel(sorted_terminal.last()); + if (next_real_t.isNull()) { + return true; + } else { + const auto next_bridge = isBridged(next_real_t.realTerminal()); + if (compar_bridge != next_bridge) { + return true; + } + } } - emit bridgeChanged(); + return false; } QSharedPointer TerminalStrip::bridgeFor(const QWeakPointer &real_terminal) const diff --git a/sources/TerminalStrip/terminalstrip.h b/sources/TerminalStrip/terminalstrip.h index 0eccf21b3..d4b36cc6b 100644 --- a/sources/TerminalStrip/terminalstrip.h +++ b/sources/TerminalStrip/terminalstrip.h @@ -40,20 +40,6 @@ struct TerminalStripBridge QUuid uuid_ = QUuid::createUuid(); }; -inline bool operator == (const TerminalStripBridge &bridge_1, const TerminalStripBridge &bridge_2) { - return (bridge_1.uuid_ == bridge_2.uuid_); -} - -inline uint qHash(const QWeakPointer &key, uint seed) -{ - const auto bridge = key.toStrongRef(); - if (bridge) { - return qHash(bridge->uuid_, seed); - } else { - return qHash(QUuid (), seed); - } -} - class RealTerminalData { friend class TerminalStrip; @@ -188,6 +174,7 @@ class TerminalStrip : public QObject bool setBridge(const QVector> &real_terminals); bool setBridge(const QSharedPointer &bridge, const QVector> &real_terminals); void unBridge(const QVector> &real_terminals); + bool canUnBridge(const QVector > &real_terminals) const; QSharedPointer bridgeFor(const QWeakPointer &real_terminal) const; RealTerminalData previousTerminalInLevel(const QWeakPointer &real_terminal) const; diff --git a/sources/TerminalStrip/ui/terminalstripeditor.cpp b/sources/TerminalStrip/ui/terminalstripeditor.cpp index 4f0b6d396..02a9533bb 100644 --- a/sources/TerminalStrip/ui/terminalstripeditor.cpp +++ b/sources/TerminalStrip/ui/terminalstripeditor.cpp @@ -429,37 +429,21 @@ void TerminalStripEditor::selectionChanged() //One column must be selected and the column must be a level column int level_ = TerminalStripModel::levelForColumn(isSingleColumnSelected()); - if (level_ >= 0) + if (level_ >= 0 && m_current_strip) { //Select only terminals of corresponding level cell selection QVector model_real_terminal_level_vector; - for (const auto &mrtd : model_real_terminal_vector) { - if (mrtd.level_ == level_) { + QVector> real_terminal_in_level_vector; + for (const auto &mrtd : model_real_terminal_vector) + { + if (mrtd.level_ == level_) + { model_real_terminal_level_vector.append(mrtd); + real_terminal_in_level_vector.append(mrtd.real_terminal); } } - - QVector model_rtd_vector; - for (const auto &mrtd : model_real_terminal_level_vector) { - model_rtd_vector << mrtd; - } - if (m_current_strip) - { - QVector> vector_; - for (const auto &mrtd : qAsConst(model_rtd_vector)) { - vector_.append(mrtd.real_terminal); - } - enable_bridge = m_current_strip->isBridgeable(vector_); - } - - for (const auto &mrtd : model_real_terminal_level_vector) - { - if (mrtd.bridged_ && - mrtd.level_ == level_) { - enable_unbridge = true; - break; - } - } + enable_bridge = m_current_strip->isBridgeable(real_terminal_in_level_vector); + enable_unbridge = m_current_strip->canUnBridge(real_terminal_in_level_vector); } ui->m_bridge_terminals_pb->setEnabled(enable_bridge); ui->m_unbridge_terminals_pb->setEnabled(enable_unbridge);