diff --git a/src/blackcore/context_simulator_impl.cpp b/src/blackcore/context_simulator_impl.cpp index efd631f3b..381c7f595 100644 --- a/src/blackcore/context_simulator_impl.cpp +++ b/src/blackcore/context_simulator_impl.cpp @@ -306,12 +306,16 @@ namespace BlackCore { if (!this->m_simulator) return; if (statusMessage.getSeverity() != CStatusMessage::SeverityError) return; + + if (statusMessage.wasHandledBy(this)) return; + statusMessage.markAsHandledBy(this); + this->m_simulator->displayStatusMessage(statusMessage); } void CContextSimulator::ps_statusMessagesReceived(const CStatusMessageList &statusMessages) { - foreach(CStatusMessage m, statusMessages) + for(const CStatusMessage &m : statusMessages) { this->ps_statusMessageReceived(m); } diff --git a/src/blackmisc/loghandler.h b/src/blackmisc/loghandler.h index 8c335de13..ba3bb44fd 100644 --- a/src/blackmisc/loghandler.h +++ b/src/blackmisc/loghandler.h @@ -93,6 +93,12 @@ namespace BlackMisc * Emitted when a message is logged in a relevant category. * * When all slots are disconnected from this signal, the CLogCategoryHandler is allowed to delete itself. + * + * Note that if a message matches more that one category handler, then this signal will be emitted for all of them, + * so if a slot is connected to all of them then it will be called multiple times. Use the methods + * CStatusMessage::markAsHandledBy() and CStatusMessage::wasHandledBy() to detect this case in the slot and avoid + * multiple handlings of the same message. Caveat: for this to work, the slot must take its argument by non-const + * reference, and be connected by Qt::DirectConnection (i.e. the receiver is in the same thread as the CLogHandler). */ void messageLogged(const CStatusMessage &message); diff --git a/src/blackmisc/statusmessage.cpp b/src/blackmisc/statusmessage.cpp index 51011fe98..2f1eeaf5a 100644 --- a/src/blackmisc/statusmessage.cpp +++ b/src/blackmisc/statusmessage.cpp @@ -114,6 +114,18 @@ namespace BlackMisc } } + /* + * Handled by + */ + void CStatusMessage::markAsHandledBy(const QObject *object) const + { + this->m_handledByObjects.push_back(quintptr(object)); + } + bool CStatusMessage::wasHandledBy(const QObject *object) const + { + return this->m_handledByObjects.contains(quintptr(object)); + } + /* * To string */ diff --git a/src/blackmisc/statusmessage.h b/src/blackmisc/statusmessage.h index 1124850ef..297c684c0 100644 --- a/src/blackmisc/statusmessage.h +++ b/src/blackmisc/statusmessage.h @@ -86,6 +86,12 @@ namespace BlackMisc //! Message may already have been handled directly bool isRedundant() const { return this->m_redundant; } + //! Mark the message as having been handled by the given object + void markAsHandledBy(const QObject *object) const; + + //! Returns true if the message was marked as having been handled by the given object + bool wasHandledBy(const QObject *object) const; + //! Severity void setSeverity(StatusSeverity severity) { this->m_severity = severity; } @@ -118,11 +124,19 @@ namespace BlackMisc QString m_message; QDateTime m_timestamp; bool m_redundant = false; + mutable QVector m_handledByObjects; }; } // namespace -BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::CStatusMessage, (o.m_category, o.m_severity, o.m_message, o.m_timestamp, o.m_redundant)) +BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::CStatusMessage, ( + o.m_category, + o.m_severity, + o.m_message, + o.m_timestamp, + o.m_redundant, + attr(o.m_handledByObjects, flags()) +)) Q_DECLARE_METATYPE(BlackMisc::CStatusMessage) #endif // guard diff --git a/src/swiftgui_standard/mainwindow.cpp b/src/swiftgui_standard/mainwindow.cpp index cccc59e1e..c0dbde35f 100644 --- a/src/swiftgui_standard/mainwindow.cpp +++ b/src/swiftgui_standard/mainwindow.cpp @@ -300,6 +300,9 @@ void MainWindow::ps_displayStatusMessageInGui(const CStatusMessage &statusMessag if (statusMessage.isRedundant()) return; if (statusMessage.getSeverity() == CStatusMessage::SeverityDebug) return; + if (statusMessage.wasHandledBy(this)) return; + statusMessage.markAsHandledBy(this); + if (!this->m_init) return; this->ui->sb_MainStatusBar->show(); this->m_timerStatusBar->start(3000);