diff --git a/src/blackmisc/loghandler.cpp b/src/blackmisc/loghandler.cpp index 23c09fdb6..0604a7e0e 100644 --- a/src/blackmisc/loghandler.cpp +++ b/src/blackmisc/loghandler.cpp @@ -132,4 +132,46 @@ namespace BlackMisc m_patternHandlers.erase(newEnd, m_patternHandlers.end()); } + void CLogSubscriber::changeSubscription(const CLogPattern &pattern) + { + Q_ASSERT(CLogHandler::instance()->thread() == QThread::currentThread()); + unsubscribe(); + m_handler = CLogHandler::instance()->handlerForPattern(pattern); + + if (! m_inheritFallThrough) + { + m_handler->enableConsoleOutput(m_enableFallThrough); + } + connect(m_handler, &CLogPatternHandler::messageLogged, this, &CLogSubscriber::ps_logMessage); + } + + void CLogSubscriber::unsubscribe() + { + Q_ASSERT(CLogHandler::instance()->thread() == QThread::currentThread()); + if (m_handler) + { + m_handler->disconnect(this); + } + } + + void CLogSubscriber::inheritConsoleOutput() + { + Q_ASSERT(CLogHandler::instance()->thread() == QThread::currentThread()); + m_inheritFallThrough = true; + if (m_handler) + { + m_handler->inheritConsoleOutput(); + } + } + + void CLogSubscriber::enableConsoleOutput(bool enable) + { + Q_ASSERT(CLogHandler::instance()->thread() == QThread::currentThread()); + m_inheritFallThrough = false; + m_enableFallThrough = enable; + if (m_handler) + { + m_handler->enableConsoleOutput(enable); + } + } } diff --git a/src/blackmisc/loghandler.h b/src/blackmisc/loghandler.h index ce2247ccc..9659aec58 100644 --- a/src/blackmisc/loghandler.h +++ b/src/blackmisc/loghandler.h @@ -16,6 +16,7 @@ #include "statusmessage.h" #include #include +#include namespace BlackMisc { @@ -166,6 +167,48 @@ namespace BlackMisc return ! isSignalConnected(signal); } }; + + /*! + * A helper class for subscribing to log messages matching a particular pattern, with the ability to + * change the pattern at runtime. + */ + class CLogSubscriber : public QObject + { + Q_OBJECT + + public: + //! Construct a subscriber which forwards messages to the given slot of parent. + template + CLogSubscriber(T *parent, F slot) : QObject(parent) + { + Q_ASSERT(CLogHandler::instance()->thread() == QThread::currentThread()); + QObject::connect(this, &CLogSubscriber::ps_messageLogged, parent, slot); + } + + //! Change the pattern which you want to subscribe to. + void changeSubscription(const CLogPattern &pattern); + + //! Unsubscribe from all messages. + void unsubscribe(); + + //! \copydoc CLogPatternHandler::enableConsoleOutput + void enableConsoleOutput(bool enable); + + //! \copydoc CLogPatternHandler::inheritConsoleOutput + void inheritConsoleOutput(); + + signals: + //! \private + void ps_messageLogged(const CStatusMessage &message); + + private slots: + void ps_logMessage(const CStatusMessage &message) { emit ps_messageLogged(message); } + + private: + QPointer m_handler; + bool m_inheritFallThrough = true; + bool m_enableFallThrough = true; + }; } #endif diff --git a/src/swiftgui_standard/mainwindow.h b/src/swiftgui_standard/mainwindow.h index cfa088a7b..6ade8a1cb 100644 --- a/src/swiftgui_standard/mainwindow.h +++ b/src/swiftgui_standard/mainwindow.h @@ -32,6 +32,7 @@ #include "blackgui/models/statusmessagelistmodel.h" #include "blackgui/models/keyboardkeylistmodel.h" #include "blackmisc/nwtextmessage.h" +#include "blackmisc/loghandler.h" #include "blacksound/soundgenerator.h" #include #include @@ -88,6 +89,8 @@ private: GuiModes::WindowMode m_windowMode; BlackInput::IKeyboard *m_keyboard; //!< hotkeys + BlackMisc::CLogSubscriber m_logSubscriber { this, &MainWindow::ps_displayStatusMessageInGui }; + // contexts bool m_coreAvailable; bool m_contextNetworkAvailable; diff --git a/src/swiftgui_standard/mainwindow_init.cpp b/src/swiftgui_standard/mainwindow_init.cpp index 99c569716..f1e6c6888 100644 --- a/src/swiftgui_standard/mainwindow_init.cpp +++ b/src/swiftgui_standard/mainwindow_init.cpp @@ -21,7 +21,6 @@ #include "blackmisc/avselcal.h" #include "blackmisc/project.h" #include "blackmisc/hotkeyfunction.h" -#include "blackmisc/loghandler.h" #include "blackmisc/logmessage.h" #include #include @@ -112,7 +111,7 @@ void MainWindow::init(const CRuntimeConfig &runtimeConfig) this->connect(this->ui->comp_MainInfoArea->getSettingsComponent(), &CSettingsComponent::changedAtcStationsUpdateInterval, this->ui->comp_MainInfoArea->getAtcStationComponent(), &::CAtcStationComponent::setUpdateIntervalSeconds); // log messages - CLogHandler::instance()->handlerForPattern(CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityInfo))->subscribe(this, &MainWindow::ps_displayStatusMessageInGui); + m_logSubscriber.changeSubscription(CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityInfo)); Q_ASSERT(connect); Q_UNUSED(connect); // suppress GCC warning in release build