[companion] Adjust GVAR not possible in global functions (fix #5425)
[opentx.git] / companion / src / appdebugmessagehandler.h
blob7ea6828994399acc9564696b8b7f6127f6e9b8d0
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #ifndef APPDEBUGMESSAGEHANDLER_H
22 #define APPDEBUGMESSAGEHANDLER_H
24 #include <cstdlib>
25 #include <iostream>
27 #include <QApplication>
28 #include <QDebug>
29 #include <QIODevice>
30 #include <QMessageLogContext>
31 #include <QObject>
32 #include <QRegularExpression>
33 #include <QString>
36 * Custom debug/message handler class to work in conjunction with qDebug() family of functions.
37 * Formats all stderr output generated by the application in a consistent manner.
38 * It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal).
40 * Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug).
42 * Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_.
43 * see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
45 * This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance().
46 * For example, at start of application:
48 * QApplication app(argc, argv);
49 * AppDebugMessageHandler::instance()->installAppMessageHandler();
51 * To connect to a signal:
53 * connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
55 * This singleton will self-destruct upon QApplication termination.
59 #if defined(QT_DEBUG) || defined(DEBUG)
60 #define APP_DBG_HANDLER_IS_DBG_BUILD 1
61 #else
62 #define APP_DBG_HANDLER_IS_DBG_BUILD 0
63 #endif
65 // Enable/disable this custom handler handler entirely
66 #ifndef APP_DBG_HANDLER_ENABLE
67 #define APP_DBG_HANDLER_ENABLE 1
68 #endif
70 // Default log level (can also be set with setAppDebugOutputLevel()):
71 // 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only
72 #ifndef APP_DBG_HANDLER_DEFAULT_LEVEL
73 #define APP_DBG_HANDLER_DEFAULT_LEVEL 0
74 #endif
76 // Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH)
77 #ifndef APP_DBG_HANDLER_SHOW_SRC_PATH
78 #define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD
79 #endif
81 // Show just the function Class::name vs. full declaration with return and param types
82 #ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL
83 #define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0
84 #endif
86 // base path for source file name filter, everything after this is kept; RegEx, non-greedy
87 #ifndef APP_DBG_HANDLER_SRC_PATH
88 #define APP_DBG_HANDLER_SRC_PATH ".*src"
89 #endif
91 // Make sure to include this header if using qInfo()
92 #if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
93 #if defined(QT_NO_INFO_OUTPUT)
94 #define qInfo QT_NO_QDEBUG_MACRO
95 #else
96 #define qInfo qDebug
97 #endif
98 #define QtInfoMsg QtMsgType(4)
99 #endif
101 class AppDebugMessageHandler : public QObject
103 Q_OBJECT
105 public:
106 // This class implements the singleton design pattern and is therefore publicly accessible only through instance().
107 static AppDebugMessageHandler * instance();
108 AppDebugMessageHandler(AppDebugMessageHandler const &) = delete;
109 void operator = (AppDebugMessageHandler const &) = delete;
111 void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
112 void setShowSourcePath(bool showSourcePath);
113 void setShowFunctionDeclarations(bool showFunctionDeclarations);
114 void addOutputDevice(QIODevice * device);
115 void removeOutputDevice(QIODevice * device);
117 void installAppMessageHandler();
118 void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
120 private:
121 // This class implements the singleton design pattern and therefore has only a private constructor.
122 explicit AppDebugMessageHandler(QObject * parent = Q_NULLPTR);
123 ~AppDebugMessageHandler() { }
125 QtMessageHandler m_defaultHandler;
126 QRegularExpression m_srcPathFilter;
127 QRegularExpression m_functionFilter;
128 quint8 m_appDebugOutputLevel;
129 QVector<QIODevice *> m_outputDevices;
130 bool m_showSourcePath;
131 bool m_showFunctionDeclarations;
133 signals:
134 void messageOutput(quint8 level, const QString & msg);
137 // Message handler which is installed using qInstallMessageHandler. This needs to be global.
138 // Use AppDebugMessageHandler::instance()->installAppMessageHandler();
139 // instead of installing this function directly (it will verify this handler is enabled, etc).
140 void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
142 #endif // APPDEBUGMESSAGEHANDLER_H