* [Simulator] Create RadioKeyWidget class for UI buttons & refactor ButtonsWidget; Refactor SimulatedUIWidget (and subtypes) to use new RadioKeyWidgets/ButtonsWidget; Centralize help text for key mappings and get creative with some icons; Simplify some radio UI setups with rectangular buttons.
* [Simulator] Convert all simulator data I/O to signals/slots mechanism:
* SimulatorInterface/OpenTxSimulator:
- Now inherits from QObject to allow signal/slot interface;
- Allows data exchange on a per-item basis (eg. each I/O value is treated separately instead of sending whole arrays or structs of data);
- Checks for data changes and only emits signals when change is detected (GUI can now assume only new values are being sent);
- Manages its own 10ms timer (doesn't rely on GUI to do that);
- Sends "heartbeat" signals @ 1Hz for status monitoring;
* Simulator GUI:
- All data is exchanged between GUI elements as well as SimulatorInterface via signals/slots using standardized methods;
- Data is sent immediately, and only, when actually changed (eg. a control is moved) instead of in bulk at specific time intervals;
- Similarly, an asynchronous method is used for reading incoming data, w/out timers or loops;
- Improve VirtualJoystickWidget to be more encapsulated and configurable;
- Pause telemetry simulator if window is hidden;
* [Simulator] Move SimulatorInterface instance to separate thread, ensure safe asynchronous operations & proper timer interactions; Protect/remove some functions, & reorganize the order (cosmetics).
* [Simulator] Traces are now delivered to OpenTxSimulator and one or more QIODevice(s) can be added as recipient(s); Add SimulatorInterface::getCapability() for compile-time settings; Remove reversed POT1/SLIDER1 mixer exception (Taranis) requirement for SIMU; Fix plus/minus key delay on wheel event w/out encoder.
* [Simulator] Add current knob/slider/trim input value in tool-tips (KnobWidget and SliderWidget).
* [Simulator] Fix trims widget internal value not properly updating, and remove trim influence on virtual joystick X/Y value display (closes #4671).
* [SimulatorInterface] Add handling of transmitter input voltage, including a rough conversion of volts to ADC value for different boards, and default battery volts lookup function; Clear analogs array before starting.
* [Simulator] Add SimulatorInterface::init() method to separate pre-startup tasks; Report actual trim range, not just extended on/off; Change how radio widget states are restored; VirtualJoystickWidget: Connect trim changes directly from simulator, connect joystick events directly, report stick mode directly instead of setting values/constraints externally.
* [Simulator] Calculate default Tx V input based on configured range in radio settings (or warning V+2 for radios which don't support a range).
* [Simulator] Add functional aux. trims for Horus (closes #4699).
* [Companion] Remove problematic QMessageLogContext from AppDebugMessageHandler::messageOutput().
* [Simulator] Prevent trim change via slider if disabled for flight mode (closes #4600).
* [OpenTxSimulator] Fixes for Qt < 5.4.
* [OpenTxSimulator] Fix slot name.
139 lines
4.9 KiB
C++
139 lines
4.9 KiB
C++
/*
|
|
* Copyright (C) OpenTX
|
|
*
|
|
* Based on code named
|
|
* th9x - http://code.google.com/p/th9x
|
|
* er9x - http://code.google.com/p/er9x
|
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
|
*
|
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program 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.
|
|
*/
|
|
|
|
#ifndef APPDEBUGMESSAGEHANDLER_H
|
|
#define APPDEBUGMESSAGEHANDLER_H
|
|
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
|
|
#include <QApplication>
|
|
#include <QDebug>
|
|
#include <QMessageLogContext>
|
|
#include <QObject>
|
|
#include <QRegularExpression>
|
|
#include <QString>
|
|
|
|
/*
|
|
* Custom debug/message handler class to work in conjunction with qDebug() family of functions.
|
|
* Formats all stderr output generated by the application in a consistent manner.
|
|
* It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal).
|
|
*
|
|
* Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug).
|
|
*
|
|
* Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_.
|
|
* see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
|
|
*
|
|
* This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance().
|
|
* For example, at start of application:
|
|
*
|
|
* QApplication app(argc, argv);
|
|
* AppDebugMessageHandler::instance()->installAppMessageHandler();
|
|
*
|
|
* To connect to a signal:
|
|
*
|
|
* connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
|
|
*
|
|
* This singleton will self-destruct upon QApplication termination.
|
|
*
|
|
*/
|
|
|
|
#if defined(QT_DEBUG) || defined(DEBUG)
|
|
#define APP_DBG_HANDLER_IS_DBG_BUILD 1
|
|
#else
|
|
#define APP_DBG_HANDLER_IS_DBG_BUILD 0
|
|
#endif
|
|
|
|
// Enable/disable this custom handler handler entirely
|
|
#ifndef APP_DBG_HANDLER_ENABLE
|
|
#define APP_DBG_HANDLER_ENABLE 1
|
|
#endif
|
|
|
|
// Default log level (can also be set with setAppDebugOutputLevel()):
|
|
// 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only
|
|
#ifndef APP_DBG_HANDLER_DEFAULT_LEVEL
|
|
#define APP_DBG_HANDLER_DEFAULT_LEVEL 0
|
|
#endif
|
|
|
|
// Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH)
|
|
#ifndef APP_DBG_HANDLER_SHOW_SRC_PATH
|
|
#define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD
|
|
#endif
|
|
|
|
// Show just the function Class::name vs. full declaration with return and param types
|
|
#ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL
|
|
#define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0
|
|
#endif
|
|
|
|
// base path for source file name filter, everything after this is kept; RegEx, non-greedy
|
|
#ifndef APP_DBG_HANDLER_SRC_PATH
|
|
#define APP_DBG_HANDLER_SRC_PATH ".*src"
|
|
#endif
|
|
|
|
// Make sure to include this header if using qInfo()
|
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
|
|
#if defined(QT_NO_INFO_OUTPUT)
|
|
#define qInfo QT_NO_QDEBUG_MACRO
|
|
#else
|
|
#define qInfo qDebug
|
|
#endif
|
|
#define QtInfoMsg 4
|
|
#endif
|
|
|
|
class AppDebugMessageHandler : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
// This class implements the singleton design pattern and is therefore publicly accessible only through instance().
|
|
static AppDebugMessageHandler * instance();
|
|
AppDebugMessageHandler(AppDebugMessageHandler const &) = delete;
|
|
void operator = (AppDebugMessageHandler const &) = delete;
|
|
|
|
void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
|
|
void setShowSourcePath(bool showSourcePath);
|
|
void setShowFunctionDeclarations(bool showFunctionDeclarations);
|
|
|
|
void installAppMessageHandler();
|
|
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
|
|
|
|
private:
|
|
// This class implements the singleton design pattern and therefore has only a private constructor.
|
|
explicit AppDebugMessageHandler(QObject * parent = Q_NULLPTR);
|
|
~AppDebugMessageHandler() { }
|
|
|
|
QtMessageHandler m_defaultHandler;
|
|
QRegularExpression m_srcPathFilter;
|
|
QRegularExpression m_functionFilter;
|
|
quint8 m_appDebugOutputLevel;
|
|
bool m_showSourcePath;
|
|
bool m_showFunctionDeclarations;
|
|
|
|
signals:
|
|
void messageOutput(quint8 level, const QString & msg);
|
|
};
|
|
|
|
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
|
|
// Use AppDebugMessageHandler::instance()->installAppMessageHandler();
|
|
// instead of installing this function directly (it will verify this handler is enabled, etc).
|
|
void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
|
|
|
|
#endif // APPDEBUGMESSAGEHANDLER_H
|