[Companion] Add optional logging of all debug output. (#4974)

* [AppDebugMessageHandler] Add ability to write debug output to any number of QIODevices.

* [Simulator][DebugOutput] Use new QIODevice hook in AppDebugMessageHandler instead of signal/slot.

* [AppData] Add new settings for debug logging; Refactor property creation macro to work with any data type and add varName_init() method to set default; Refactor all boolean settings to use new macro (others to be migrated later).

* [AppPreferencesDialog] Add UI for appDebugLog, fwTraceLog, & appLogsDir settings; Clean up layout on application prefs. tab, move and re-label a couple items.

* [Companion][Simulator] Enable optional application debug output logging.

* [Simulator] Enable optional logging of firmware debug output to file.

* [EEPROMInterface] Use qDebug() instead of std::cout so that now all debug output can be routed via custom message handler/logger.

* [Companion][Simulator] Add missing #include.
This commit is contained in:
Max Paperno
2017-06-10 23:33:03 +02:00
committed by Bertrand Songis
parent 2e4775b19a
commit f50ee3fb39
16 changed files with 680 additions and 498 deletions
+30 -1
View File
@@ -20,6 +20,8 @@
#include "appdebugmessagehandler.h"
#include <QFileDevice>
AppDebugMessageHandler::AppDebugMessageHandler(QObject * parent) :
QObject(parent),
m_appDebugOutputLevel(APP_DBG_HANDLER_DEFAULT_LEVEL),
@@ -55,6 +57,25 @@ void AppDebugMessageHandler::setShowFunctionDeclarations(bool showFunctionDeclar
m_showFunctionDeclarations = showFunctionDeclarations;
}
void AppDebugMessageHandler::addOutputDevice(QIODevice * device)
{
if (device && !m_outputDevices.contains(device))
m_outputDevices.append(device);
}
void AppDebugMessageHandler::removeOutputDevice(QIODevice * device)
{
if (device) {
// no QVector::removeAll() in Qt < 5.4
int i = 0;
foreach (QIODevice * d, m_outputDevices) {
if (d == device)
m_outputDevices.remove(i);
++i;
}
}
}
void AppDebugMessageHandler::installAppMessageHandler()
{
m_defaultHandler = qInstallMessageHandler(g_appDebugMessageHandler);
@@ -98,7 +119,7 @@ void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogCon
qSetMessagePattern(msgPattern);
if (!m_defaultHandler || receivers(SIGNAL(messageOutput(quint8, const QString &)))) {
if (!m_defaultHandler || m_outputDevices.size() || receivers(SIGNAL(messageOutput(quint8, const QString &)))) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
msgPattern = qFormatLogMessage(type, context, msg);
#else
@@ -112,6 +133,14 @@ void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogCon
#endif
emit messageOutput(lvl, msgPattern);
foreach (QIODevice * d, m_outputDevices) {
if (d && d->isWritable() && (!d->property("level").isValid() || d->property("level").toInt() <= lvl)) {
d->write(qPrintable(msgPattern % "\n"));
if (QFileDevice * fd = qobject_cast<QFileDevice *>(d))
fd->flush();
}
}
}
// if (QThread::currentThread() == qApp->thread()) // gui thread
+5 -1
View File
@@ -26,6 +26,7 @@
#include <QApplication>
#include <QDebug>
#include <QIODevice>
#include <QMessageLogContext>
#include <QObject>
#include <QRegularExpression>
@@ -94,7 +95,7 @@
#else
#define qInfo qDebug
#endif
#define QtInfoMsg 4
#define QtInfoMsg QtMsgType(4)
#endif
class AppDebugMessageHandler : public QObject
@@ -110,6 +111,8 @@ class AppDebugMessageHandler : public QObject
void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
void setShowSourcePath(bool showSourcePath);
void setShowFunctionDeclarations(bool showFunctionDeclarations);
void addOutputDevice(QIODevice * device);
void removeOutputDevice(QIODevice * device);
void installAppMessageHandler();
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
@@ -123,6 +126,7 @@ class AppDebugMessageHandler : public QObject
QRegularExpression m_srcPathFilter;
QRegularExpression m_functionFilter;
quint8 m_appDebugOutputLevel;
QVector<QIODevice *> m_outputDevices;
bool m_showSourcePath;
bool m_showFunctionDeclarations;
+29 -2
View File
@@ -41,6 +41,8 @@ AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
initSettings();
connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(baseFirmwareChanged()));
connect(ui->opt_appDebugLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
connect(ui->opt_fwTraceLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
connect(this, SIGNAL(accepted()), this, SLOT(writeValues()));
#if !defined(JOYSTICKS)
@@ -77,6 +79,10 @@ void AppPreferencesDialog::writeValues()
g.embedSplashes(ui->splashincludeCB->currentIndex());
g.enableBackup(ui->backupEnable->isChecked());
g.appDebugLog(ui->opt_appDebugLog->isChecked());
g.fwTraceLog(ui->opt_fwTraceLog->isChecked());
g.appLogsDir(ui->appLogsDir->text());
if (ui->joystickChkB ->isChecked() && ui->joystickCB->isEnabled()) {
g.jsSupport(ui->joystickChkB ->isChecked());
g.jsCtrl(ui->joystickCB ->currentIndex());
@@ -168,10 +174,15 @@ void AppPreferencesDialog::initSettings()
}
}
else {
ui->backupEnable->setDisabled(true);
ui->backupEnable->setDisabled(true);
}
ui->splashincludeCB->setCurrentIndex(g.embedSplashes());
ui->opt_appDebugLog->setChecked(g.appDebugLog());
ui->opt_fwTraceLog->setChecked(g.fwTraceLog());
ui->appLogsDir->setText(g.appLogsDir());
toggleAppLogSettings();
#if defined(JOYSTICKS)
ui->joystickChkB->setChecked(g.jsSupport());
if (ui->joystickChkB->isChecked()) {
@@ -286,6 +297,15 @@ void AppPreferencesDialog::on_ProfilebackupPathButton_clicked()
}
}
void AppPreferencesDialog::on_btn_appLogsDir_clicked()
{
QString fileName = QFileDialog::getExistingDirectory(this, tr("Select a folder for application logs"), ui->appLogsDir->text());
if (!fileName.isEmpty()) {
ui->appLogsDir->setText(fileName);
}
}
void AppPreferencesDialog::on_ge_pathButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Google Earth executable"),ui->ge_lineedit->text());
@@ -458,6 +478,14 @@ void AppPreferencesDialog::firmwareOptionChanged(bool state)
}
}
void AppPreferencesDialog::toggleAppLogSettings()
{
bool vis = (ui->opt_appDebugLog->isChecked() || ui->opt_fwTraceLog->isChecked());
ui->appLogsDir->setVisible(vis);
ui->lbl_appLogsDir->setVisible(vis);
ui->btn_appLogsDir->setVisible(vis);
}
void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
{
const Firmware * parent = firmware->getFirmwareBase();
@@ -539,4 +567,3 @@ void AppPreferencesDialog::shrink()
{
adjustSize();
}
+2
View File
@@ -62,6 +62,7 @@ class AppPreferencesDialog : public QDialog
void shrink();
void baseFirmwareChanged();
void firmwareOptionChanged(bool state);
void toggleAppLogSettings();
void writeValues();
void on_libraryPathButton_clicked();
@@ -74,6 +75,7 @@ class AppPreferencesDialog : public QDialog
void on_sdPathButton_clicked();
void on_SplashSelect_clicked();
void on_clearImageButton_clicked();
void on_btn_appLogsDir_clicked();
#if defined(JOYSTICKS)
void on_joystickChkB_clicked();
+447 -345
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>623</width>
<height>537</height>
<width>703</width>
<height>534</height>
</rect>
</property>
<property name="sizePolicy">
@@ -26,9 +26,6 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
@@ -763,189 +760,454 @@ Mode 4:
<attribute name="title">
<string>Application Settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="14" column="0">
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_3">
<property name="spacing">
<number>6</number>
</property>
<property name="text">
<string>Automatic Backup Folder</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="3">
<widget class="QCheckBox" name="autoCheckCompanion">
<property name="text">
<string>Automatic check for Companion updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QCheckBox" name="showSplash">
<property name="text">
<string>Show splash screen when Companion starts</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="historySize">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>40</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="useFirmwareNightlyBuilds">
<property name="text">
<string>Use OpenTX firmware nightly builds</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QLineEdit" name="backupPath">
<property name="minimumSize">
<size>
<width>350</width>
<height>0</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="QComboBox" name="splashincludeCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Only show user splash images</string>
</property>
<item row="7" column="1">
<layout class="QGridLayout" name="gridLayout_6">
<item row="1" column="1">
<widget class="QCheckBox" name="useCompanionNightlyBuilds">
<property name="text">
<string>Use Companion nightly builds</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useFirmwareNightlyBuilds">
<property name="text">
<string>Use firmware nightly builds</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="autoCheckFirmware">
<property name="text">
<string>Automatic check for OpenTX firmware updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="autoCheckCompanion">
<property name="text">
<string>Automatic check for Companion updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<property name="text">
<string>Show user and companion splash images</string>
</property>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_10" stretch="0,1">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QSpinBox" name="historySize">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>40</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>most recently used files</string>
</property>
</widget>
</item>
</layout>
</item>
</widget>
<item row="6" column="0" rowspan="2">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Startup Settings</string>
</property>
</widget>
</item>
<item row="20" column="0">
<widget class="QLabel" name="ge_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Google Earth Executable</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatic Backup Folder</string>
</property>
</widget>
</item>
<item row="10" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remember</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="showSplash">
<property name="text">
<string>Show splash screen when Companion starts</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLineEdit" name="backupPath">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="backupPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="17" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLineEdit" name="libraryPath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="libraryPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="23" column="0">
<widget class="QLabel" name="lbl_appLogsDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Output Logs Folder</string>
</property>
</widget>
</item>
<item row="4" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="opt_removeBlankSlots">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. &lt;/p&gt;&lt;p&gt;When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Remove empty model slots when deleting models (only applies for radios w/out categories)</string>
</property>
</widget>
</item>
<item row="8" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="opt_newMdl_useWizard">
<property name="text">
<string>Use model wizard</string>
</property>
<attribute name="buttonGroup">
<string notr="true">btnGrp_newModelActions</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="opt_newMdl_useEditor">
<property name="text">
<string>Open model editor</string>
</property>
<attribute name="buttonGroup">
<string notr="true">btnGrp_newModelActions</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="opt_newMdl_useNone">
<property name="text">
<string>Just create the model</string>
</property>
<attribute name="buttonGroup">
<string notr="true">btnGrp_newModelActions</string>
</attribute>
</widget>
</item>
</layout>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="backupEnable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable automatic backup before writing firmware</string>
</property>
</widget>
</item>
<item row="22" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Debug Output Logging</string>
</property>
</widget>
</item>
<item row="18" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QComboBox" name="splashincludeCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Only show user splash images</string>
</property>
</item>
<item>
<property name="text">
<string>Show user and companion splash images</string>
</property>
</item>
</widget>
</item>
<item row="14" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="20" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLineEdit" name="ge_lineedit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ge_pathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Executable</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="23" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="appLogsDir">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_appLogsDir">
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="22" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="opt_appDebugLog">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Keep a log of all debugging messages generated by the desktop Companion/Simulator applications. An OpenTX developer may request this to help diagnose an issue.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Application (Companion/Simulator)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="opt_fwTraceLog">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Keep a log of all messages generated by the radio firmware when running in Simulator. This is the same information one would also see in the Simulator &lt;span style=&quot; font-style:italic;&quot;&gt;Debug Output&lt;/span&gt; window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Radio Firmware (in Simulator)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="16" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Splash Screen Library</string>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>User Splash Screens</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Action on New Model</string>
</property>
</widget>
</item>
<item row="21" column="0" colspan="2">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1" colspan="3">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Files to keep</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="13" column="1" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="1" colspan="3">
<widget class="QCheckBox" name="autoCheckFirmware">
<property name="text">
<string>Automatic check for OpenTX firmware updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="14" column="2" colspan="2">
<widget class="QPushButton" name="backupPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Splash Screen Library</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="ge_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Google Earth Executable</string>
</property>
</widget>
</item>
<item row="20" column="1">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -958,155 +1220,6 @@ Mode 4:
</property>
</spacer>
</item>
<item row="15" column="1" colspan="3">
<widget class="QCheckBox" name="backupEnable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable automatic backup before writing firmware</string>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QLineEdit" name="libraryPath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="16" column="1" colspan="3">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>User Splash Screens</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="useCompanionNightlyBuilds">
<property name="text">
<string>Use Companion nightly builds</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="ge_lineedit">
<property name="minimumSize">
<size>
<width>350</width>
<height>0</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2" colspan="2">
<widget class="QPushButton" name="ge_pathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Executable</string>
</property>
</widget>
</item>
<item row="18" column="2" colspan="2">
<widget class="QPushButton" name="libraryPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Action on New Model</string>
</property>
</widget>
</item>
<item row="11" column="1" colspan="3">
<widget class="QCheckBox" name="opt_removeBlankSlots">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. &lt;/p&gt;&lt;p&gt;When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Remove empty model slots when deleting models (only applies for radios w/out categories)</string>
</property>
</widget>
</item>
<item row="12" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="opt_newMdl_useWizard">
<property name="text">
<string>Use model wizard</string>
</property>
<attribute name="buttonGroup">
<string notr="true">btnGrp_newModelActions</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="opt_newMdl_useEditor">
<property name="text">
<string>Open model editor</string>
</property>
<attribute name="buttonGroup">
<string notr="true">btnGrp_newModelActions</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="opt_newMdl_useNone">
<property name="text">
<string>Just create the model</string>
</property>
<attribute name="buttonGroup">
<string notr="true">btnGrp_newModelActions</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="simulatorTab">
@@ -1181,7 +1294,7 @@ Mode 4:
</sizepolicy>
</property>
<property name="text">
<string>Simulator capture folder</string>
<string>Screenshot capture folder</string>
</property>
</widget>
</item>
@@ -1363,18 +1476,7 @@ Mode 4:
<tabstop>channelorderCB</tabstop>
<tabstop>renameFirmware</tabstop>
<tabstop>burnFirmware</tabstop>
<tabstop>ge_lineedit</tabstop>
<tabstop>ge_pathButton</tabstop>
<tabstop>historySize</tabstop>
<tabstop>showSplash</tabstop>
<tabstop>autoCheckFirmware</tabstop>
<tabstop>autoCheckCompanion</tabstop>
<tabstop>backupPath</tabstop>
<tabstop>backupPathButton</tabstop>
<tabstop>backupEnable</tabstop>
<tabstop>splashincludeCB</tabstop>
<tabstop>libraryPath</tabstop>
<tabstop>libraryPathButton</tabstop>
<tabstop>snapshotPath</tabstop>
<tabstop>snapshotPathButton</tabstop>
<tabstop>snapshotClipboardCKB</tabstop>
+18 -2
View File
@@ -19,6 +19,9 @@
*/
#include <QApplication>
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QSplashScreen>
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
#include <SDL.h>
@@ -77,14 +80,21 @@ int main(int argc, char *argv[])
exit(0);
}
QFile dbgLog;
if (AppDebugMessageHandler::instance() && g.appDebugLog() && !g.appLogsDir().isEmpty() && QDir().mkpath(g.appLogsDir())) {
QString fn = g.appLogsDir() % "/CompanionDebug_" % QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss") % ".log";
dbgLog.setFileName(fn);
if (dbgLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
AppDebugMessageHandler::instance()->addOutputDevice(&dbgLog);
}
}
#ifdef __APPLE__
app.setStyle(new MyProxyStyle);
#endif
Translations::installTranslators();
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
uint32_t sdlFlags = 0;
#ifdef JOYSTICKS
@@ -139,5 +149,11 @@ int main(int argc, char *argv[])
#endif
qDebug() << "COMPANION EXIT" << result;
if (dbgLog.isOpen()) {
AppDebugMessageHandler::instance()->removeOutputDevice(&dbgLog);
dbgLog.close();
}
return result;
}
+16 -12
View File
@@ -82,7 +82,9 @@ inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
#if 0
unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
{
std::cout << "trying er9x xml import... ";
QDebug dbg = qDebug();
dbg.setAutoInsertSpaces(false);
dbg << "trying er9x xml import... ";
std::bitset<NUM_ERRORS> errors;
@@ -94,7 +96,7 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
}
else {
radioData.generalSettings=er9xGeneral;
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
}
for (int i=0; i<getCapability(Models); i++) {
Er9xModelData er9xModel;
@@ -104,7 +106,7 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
radioData.models[i] = er9xModel;
}
}
std::cout << "ok\n";
dbg << "ok";
errors.set(ALL_OK);
return errors.to_ulong();
}
@@ -112,18 +114,20 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
{
std::cout << "trying er9x import... ";
QDebug dbg = qDebug();
dbg.setAutoInsertSpaces(false);
dbg << "trying er9x import... ";
std::bitset<NUM_ERRORS> errors;
if (size != Boards::getEEpromSize(Board::BOARD_STOCK)) {
std::cout << "wrong size\n";
dbg << "wrong size";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_STOCK)) {
std::cout << "wrong file system\n";
dbg << "wrong file system";
errors.set(WRONG_FILE_SYSTEM);
return errors.to_ulong();
}
@@ -132,16 +136,16 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
Er9xGeneral er9xGeneral;
if (efile->readRlc1((uint8_t*)&er9xGeneral, 1) != 1) {
std::cout << "no\n";
dbg << "no";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
switch(er9xGeneral.myVers) {
case 3:
std::cout << "(old gruvin9x) ";
dbg << "(old gruvin9x) ";
case 4:
// case 5:
case 6:
@@ -151,14 +155,14 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
case 10:
break;
default:
std::cout << "not er9x\n";
dbg << "not er9x";
errors.set(NOT_ER9X);
return errors.to_ulong();
}
efile->openRd(FILE_GENERAL);
if (!efile->readRlc1((uint8_t*)&er9xGeneral, sizeof(Er9xGeneral))) {
std::cout << "ko\n";
dbg << "ko";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
@@ -177,7 +181,7 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
}
}
std::cout << "ok\n";
dbg << "ok";
errors.set(ALL_OK);
return errors.to_ulong();
}
@@ -116,7 +116,9 @@ inline void applyStickModeToModel(Ersky9xModelData_v11 & model, unsigned int mod
#if 0
unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
{
std::cout << "trying ersky9x xml import... ";
QDebug dbg = qDebug();
dbg.setAutoInsertSpaces(false);
dbg << "trying ersky9x xml import... ";
std::bitset<NUM_ERRORS> errors;
@@ -128,25 +130,25 @@ unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
}
else {
radioData.generalSettings=ersky9xGeneral;
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
}
for(int i=0; i<getCapability(Models); i++) {
if (ersky9xGeneral.myVers == 10) {
if (!loadModelDataXML<Ersky9xModelData_v10>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
std::cout << "ko\n";
dbg << "ko";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
}
else {
if (!loadModelDataXML<Ersky9xModelData_v11>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
std::cout << "ko\n";
dbg << "ko";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
}
}
std::cout << "ok\n";
dbg << "ok";
errors.set(ALL_OK);
return errors.to_ulong();
}
@@ -154,18 +156,20 @@ unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
{
std::cout << "trying ersky9x import... ";
QDebug dbg = qDebug();
dbg.setAutoInsertSpaces(false);
dbg << "trying ersky9x import... ";
std::bitset<NUM_ERRORS> errors;
if (size != Boards::getEEpromSize(Board::BOARD_SKY9X)) {
std::cout << "wrong size\n";
dbg << "wrong size";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_SKY9X)) {
std::cout << "wrong file system\n";
dbg << "wrong file system";
errors.set(WRONG_FILE_SYSTEM);
return errors.to_ulong();
}
@@ -174,12 +178,12 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
Ersky9xGeneral ersky9xGeneral;
if (efile->readRlc2((uint8_t*)&ersky9xGeneral, 1) != 1) {
std::cout << "no\n";
dbg << "no";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
switch(ersky9xGeneral.myVers) {
case 10:
@@ -187,13 +191,13 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
case 11:
break;
default:
std::cout << "not ersky9x\n";
dbg << "not ersky9x";
errors.set(NOT_ERSKY9X);
return errors.to_ulong();
}
efile->openRd(FILE_GENERAL);
if (!efile->readRlc2((uint8_t*)&ersky9xGeneral, sizeof(Ersky9xGeneral))) {
std::cout << "ko\n";
dbg << "ko";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
@@ -225,7 +229,7 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
}
}
std::cout << "ok\n";
dbg << "ok";
errors.set(ALL_OK);
return errors.to_ulong();
}
@@ -107,7 +107,7 @@ bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings & settings,
return checkVariant(settings.version, settings.variant);
}
else {
std::cout << " error when loading general settings";
qWarning() << " error when loading general settings";
return false;
}
}
@@ -180,7 +180,9 @@ bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data)
unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size)
{
std::cout << "trying " << getName() << " import...";
QDebug dbg = qDebug();
dbg.setAutoInsertSpaces(false);
dbg << "trying " << getName() << " import...";
std::bitset<NUM_ERRORS> errors;
@@ -193,7 +195,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
}
}
if (notnull) {
std::cout << " wrong size (" << size << ")\n";
dbg << " wrong size (" << size << ")";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
@@ -204,14 +206,14 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
}
}
else {
std::cout << " wrong size (" << size << "/" << Boards::getEEpromSize(board) << ")\n";
dbg << " wrong size (" << size << "/" << Boards::getEEpromSize(board) << ")";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
}
if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) {
std::cout << " wrong file system\n";
dbg << " wrong file system";
errors.set(WRONG_FILE_SYSTEM);
return errors.to_ulong();
}
@@ -220,12 +222,12 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
uint8_t version;
if (efile->readRlc2(&version, 1) != 1) {
std::cout << " no\n";
dbg << " no";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
std::cout << " version " << (unsigned int) version;
dbg << " version " << (unsigned int) version;
EepromLoadErrors version_error = checkVersion(version);
if (version_error == OLD_VERSION) {
@@ -234,24 +236,24 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
ShowEepromWarnings(NULL, QObject::tr("Warning"), errors.to_ulong());
}
else if (version_error == NOT_OPENTX) {
std::cout << " not open9x\n";
dbg << " not open9x";
errors.set(version_error);
return errors.to_ulong();
}
if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) {
std::cout << " ko\n";
dbg << " ko";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
std::cout << " variant " << radioData.generalSettings.variant;
dbg << " variant " << radioData.generalSettings.variant;
if (getCurrentFirmware()->getCapability(Models) == 0) {
radioData.models.resize(firmware->getCapability(Models));
}
for (int i = 0; i < firmware->getCapability(Models); i++) {
if (i < (int)radioData.models.size() && !loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) {
std::cout << " ko\n";
dbg << " ko";
errors.set(UNKNOWN_ERROR);
if (getCurrentFirmware()->getCapability(Models) == 0) {
radioData.models.resize(i);
@@ -259,7 +261,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
return errors.to_ulong();
}
}
std::cout << " ok\n";
dbg << " ok";
errors.set(ALL_OK);
return errors.to_ulong();
}
@@ -939,29 +941,29 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
efile->openRd(i);
int sz = efile->readRlc2(tmp, sizeof(tmp));
if (sz == 849) {
std::cout << " warning: M128 variant not set (but model size seems ok)";
qWarning() << " warning: M128 variant not set (but model size seems ok)";
return true;
}
}
}
std::cout << " wrong variant (" << variant << ")";
qWarning() << " wrong variant (" << variant << ")";
return false;
}
else if (IS_TARANIS_X9E(board)) {
if (variant != TARANIS_X9E_VARIANT) {
std::cout << " wrong variant (" << variant << ")";
qWarning() << " wrong variant (" << variant << ")";
return false;
}
}
else if (IS_TARANIS_X7(board)) {
if (variant != TARANIS_X7_VARIANT) {
std::cout << " wrong variant (" << variant << ")";
qWarning() << " wrong variant (" << variant << ")";
return false;
}
}
else if (IS_TARANIS(board)) {
if (variant != 0) {
std::cout << " wrong variant (" << variant << ")";
qWarning() << " wrong variant (" << variant << ")";
return false;
}
}
@@ -994,10 +996,12 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
{
std::bitset<NUM_ERRORS> errors;
std::cout << "trying " << getName() << " backup import...";
QDebug dbg = qDebug();
dbg.setAutoInsertSpaces(false);
dbg << "trying " << getName() << " backup import...";
if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) {
std::cout << " no\n";
dbg << " no\n";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
@@ -1014,13 +1018,13 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
backupBoard = BOARD_GRUVIN9X;
break;
default:
std::cout << " unknown board\n";
dbg << " unknown board";
errors.set(UNKNOWN_BOARD);
return errors.to_ulong();
}
if (backupBoard != board) {
std::cout << " not right board\n";
dbg << " not right board";
errors.set(WRONG_BOARD);
return errors.to_ulong();
}
@@ -1030,7 +1034,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6];
uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8];
std::cout << " version " << (unsigned int) version << " ";
dbg << " version " << (unsigned int) version << " ";
EepromLoadErrors version_error = checkVersion(version);
if (version_error == OLD_VERSION) {
@@ -1038,31 +1042,31 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
errors.set(HAS_WARNINGS);
}
else if (version_error == NOT_OPENTX) {
std::cout << " not open9x\n";
dbg << " not open9x";
errors.set(version_error);
return errors.to_ulong();
}
if (size > esize - 8) {
std::cout << " wrong size\n";
dbg << " wrong size";
errors.set(WRONG_SIZE);
return errors.to_ulong();
}
if (bcktype == 'M') {
if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) {
std::cout << " ko\n";
dbg << " ko";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
}
else {
std::cout << " backup type not supported\n";
dbg << " backup type not supported";
errors.set(BACKUP_NOT_SUPPORTED);
return errors.to_ulong();
}
std::cout << " ok\n";
dbg << " ok";
errors.set(ALL_OK);
return errors.to_ulong();
}
+7 -12
View File
@@ -94,8 +94,11 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
connect(ui->actionToggleFilter, &QAction::toggled, this, &DebugOutput::onFilterToggled);
connect(ui->filterText, &QComboBox::currentTextChanged, this, &DebugOutput::onFilterTextChanged);
if (AppDebugMessageHandler::instance())
connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
if (AppDebugMessageHandler::instance()) {
// send application Info/Warning/Error events to our data collector
m_dataBufferDevice->setProperty("level", 1);
AppDebugMessageHandler::instance()->addOutputDevice(m_dataBufferDevice);
}
// send firmware TRACE events to our data collector
m_simulator->addTracebackDevice(m_dataBufferDevice);
@@ -103,10 +106,9 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
DebugOutput::~DebugOutput()
{
if (AppDebugMessageHandler::instance())
disconnect(AppDebugMessageHandler::instance(), 0, this, 0);
if (m_dataBufferDevice) {
if (AppDebugMessageHandler::instance())
AppDebugMessageHandler::instance()->removeOutputDevice(m_dataBufferDevice);
m_simulator->removeTracebackDevice(m_dataBufferDevice);
disconnect(m_dataBufferDevice, 0, this, 0);
disconnect(this, 0, m_dataBufferDevice, 0);
@@ -201,13 +203,6 @@ void DebugOutput::onDataBufferOverflow(const qint64 len)
}
}
void DebugOutput::onAppDebugMessage(quint8 level, const QString & msg)
{
if (level > 0 && m_dataBufferDevice) {
m_dataBufferDevice->write(qPrintable(msg % "\n"));
}
}
/*
* UI handlers
*/
-1
View File
@@ -72,7 +72,6 @@ class DebugOutput : public QWidget
void restoreState();
void processBytesReceived();
void onDataBufferOverflow(const qint64 len);
void onAppDebugMessage(quint8 level, const QString & msg);
void onFilterStateChanged();
void onFilterTextChanged(const QString &);
void onFilterToggled(bool enable);
@@ -33,6 +33,7 @@
#endif
#include <QDebug>
#include <QDir>
#include <QLabel>
#include <QMessageBox>
@@ -69,6 +70,14 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwa
return;
}
if (g.fwTraceLog() && !g.appLogsDir().isEmpty() && QDir().mkpath(g.appLogsDir())) {
// send firmware TRACE events to log file
QString fn = g.appLogsDir() % "/FirmwareDebug_" % QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss") % ".log";
m_simuLogFile.setFileName(fn);
if (m_simuLogFile.open(QIODevice::WriteOnly | QIODevice::Text))
m_simulator->addTracebackDevice(&m_simuLogFile);
}
m_simulator->moveToThread(&simuThread);
simuThread.start();
@@ -140,8 +149,6 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwa
connect(ui->actionScreenshot, &QAction::triggered, m_simulatorWidget, &SimulatorWidget::captureScreenshot);
connect(m_simulatorWidget, &SimulatorWidget::windowTitleChanged, this, &SimulatorMainWindow::setWindowTitle);
}
}
SimulatorMainWindow::~SimulatorMainWindow()
@@ -164,6 +171,10 @@ SimulatorMainWindow::~SimulatorMainWindow()
if (m_simulator) {
simuThread.quit();
simuThread.wait();
if (m_simuLogFile.isOpen()) {
m_simulator->removeTracebackDevice(&m_simuLogFile);
m_simuLogFile.close();
}
delete m_simulator;
}
SimulatorLoader::unloadSimulator(m_simulatorId);
@@ -24,6 +24,7 @@
#include "simulator.h"
#include <QDockWidget>
#include <QFile>
#include <QMainWindow>
#include <QThread>
@@ -99,6 +100,7 @@ class SimulatorMainWindow : public QMainWindow
QDockWidget * m_outputsDockWidget;
QThread simuThread;
QFile m_simuLogFile;
QVector<keymapHelp_t> m_keymapHelp;
QString m_simulatorId;
QString m_exitStatusMsg;
+16 -3
View File
@@ -19,6 +19,7 @@
*/
#include <QApplication>
#include <QDateTime>
#include <QCommandLineParser>
#include <QMessageBox>
#include <QString>
@@ -42,6 +43,7 @@
using namespace Simulator;
QFile simuDbgLog;
int finish(int exitCode);
void showMessage(const QString & message, enum QMessageBox::Icon icon = QMessageBox::NoIcon, bool useConsole = false)
@@ -56,10 +58,9 @@ void showMessage(const QString & message, enum QMessageBox::Icon icon = QMessage
}
// use GUI
QMessageBox msgBox;
QString escMsg(message);
escMsg.replace("<", "&lt;");
msgBox.setText("<html><body><pre>" + escMsg + "</pre></body></html>");
msgBox.setText("<html><body><pre>" + message.toHtmlEscaped() + "</pre></body></html>");
msgBox.setIcon(icon);
msgBox.setWindowTitle(QApplication::translate("SimulatorMain", "OpenTx Simulator"));
msgBox.exec();
}
@@ -251,6 +252,14 @@ int main(int argc, char *argv[])
g.init(); // init settings before installing translations
if (AppDebugMessageHandler::instance() && g.appDebugLog() && !g.appLogsDir().isEmpty() && QDir().mkpath(g.appLogsDir())) {
QString fn = g.appLogsDir() % "/SimulatorDebug_" % QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss") % ".log";
simuDbgLog.setFileName(fn);
if (simuDbgLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
AppDebugMessageHandler::instance()->addOutputDevice(&simuDbgLog);
}
}
Translations::installTranslators();
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
@@ -365,5 +374,9 @@ int finish(int exitCode)
#endif
qDebug() << "SIMULATOR EXIT" << exitCode;
if (simuDbgLog.isOpen()) {
AppDebugMessageHandler::instance()->removeOutputDevice(&simuDbgLog);
simuDbgLog.close();
}
return exitCode;
}
+19 -37
View File
@@ -460,16 +460,6 @@ QString AppData::libDir() { return _libDir; }
QString AppData::snapshotDir() { return _snapshotDir; }
QString AppData::updatesDir() { return _updatesDir; }
bool AppData::jsSupport() { return _jsSupport; }
bool AppData::maximized() { return _maximized; }
bool AppData::showSplash() { return _showSplash; }
bool AppData::snapToClpbrd() { return _snapToClpbrd; }
bool AppData::autoCheckApp() { return _autoCheckApp; }
bool AppData::autoCheckFw() { return _autoCheckFw; }
bool AppData::simuSW() { return _simuSW; }
bool AppData::tabbedMdi() { return _tabbedMdi; }
bool AppData::removeModelSlots() { return _remvModelSlots; }
int AppData::newModelAction() { return _newModelAction; }
int AppData::backLight() { return _backLight; }
int AppData::embedSplashes() { return _embedSplashes; }
@@ -517,16 +507,6 @@ void AppData::libDir (const QString x) { store(x, _libDir,
void AppData::snapshotDir (const QString x) { store(x, _snapshotDir, "snapshotpath" );}
void AppData::updatesDir (const QString x) { store(x, _updatesDir, "lastUpdatesDir" );}
void AppData::maximized (const bool x) { store(x, _maximized, "maximized" );}
void AppData::jsSupport (const bool x) { store(x, _jsSupport, "js_support" );}
void AppData::showSplash (const bool x) { store(x, _showSplash, "show_splash" );}
void AppData::snapToClpbrd (const bool x) { store(x, _snapToClpbrd, "snapshot_to_clipboard" );}
void AppData::autoCheckApp (const bool x) { store(x, _autoCheckApp, "startup_check_companion" );}
void AppData::autoCheckFw (const bool x) { store(x, _autoCheckFw, "startup_check_fw" );}
void AppData::simuSW (const bool x) { store(x, _simuSW, "simuSW" );}
void AppData::tabbedMdi (const bool x) { store(x, _tabbedMdi, "tabbedMdi" );}
void AppData::removeModelSlots(const bool x) { store(x, _remvModelSlots, "removeModelSlots" );}
void AppData::newModelAction (const int x) { store(x, _newModelAction, "newModelAction" );}
void AppData::backLight (const int x) { store(x, _backLight, "backLight" );}
void AppData::embedSplashes (const int x) { store(x, _embedSplashes, "embedded_splashes" );}
@@ -610,24 +590,26 @@ void AppData::init()
getset( _libDir, "libraryPath" ,"" );
getset( _snapshotDir, "snapshotpath" ,"" );
getset( _updatesDir, "lastUpdatesDir" ,"" );
appLogsDir_init();
getset( _enableBackup, "enableBackup" ,false );
getset( _backupOnFlash, "backupOnFlash" ,true );
getset( _outputDisplayDetails, "outputDisplayDetails" ,false );
getset( _checkHardwareCompatibility, "checkHardwareCompatibility" ,true );
getset( _useCompanionNightlyBuilds, "useCompanionNightlyBuilds" ,false );
getset( _useFirmwareNightlyBuilds, "useFirmwareNightlyBuilds" ,false );
getset( _jsSupport, "js_support" ,false );
getset( _maximized, "maximized" ,false );
getset( _showSplash, "show_splash" ,true );
getset( _snapToClpbrd, "snapshot_to_clipboard" ,false );
getset( _autoCheckApp, "startup_check_companion" ,true );
getset( _autoCheckFw, "startup_check_fw" ,true );
getset( _simuSW, "simuSW" ,false );
getset( _tabbedMdi, "tabbedMdi" ,false );
getset( _remvModelSlots, "removeModelSlots" ,true );
// booleans
enableBackup_init();
backupOnFlash_init();
outputDisplayDetails_init();
checkHardwareCompatibility_init();
useCompanionNightlyBuilds_init();
useFirmwareNightlyBuilds_init();
removeModelSlots_init();
maximized_init();
simuSW_init();
tabbedMdi_init();
appDebugLog_init();
fwTraceLog_init();
jsSupport_init();
showSplash_init();
snapToClpbrd_init();
autoCheckApp_init();
autoCheckFw_init();
getset( _newModelAction, "newModelAction" ,1 );
getset( _backLight, "backLight" ,0 );
+28 -40
View File
@@ -29,6 +29,7 @@
#include <QStringList>
#include <QString>
#include <QSettings>
#include <QStandardPaths>
#include "simulator.h"
@@ -226,21 +227,37 @@ class Profile: protected CompStoreObj
QString groupId();
};
#define BOOL_PROPERTY(name, dflt) \
#define PROPERTY4(type, name, key, dflt) \
public: \
inline bool name() { return _ ## name; } \
void name(const bool val) { store(val, _ ## name, # name); } \
inline type name() { return _ ## name; } \
void name(const type val) { store(val, _ ## name, # key); } \
private: \
bool _ ## name;
void name ## _init() { getset(_ ## name, # key, dflt); } \
type _ ## name;
#define PROPERTY(type, name, dflt) PROPERTY4(type, name, name, dflt)
class AppData: protected CompStoreObj
{
BOOL_PROPERTY(enableBackup, false)
BOOL_PROPERTY(backupOnFlash, true)
BOOL_PROPERTY(outputDisplayDetails, false)
BOOL_PROPERTY(checkHardwareCompatibility, true)
BOOL_PROPERTY(useCompanionNightlyBuilds, false)
BOOL_PROPERTY(useFirmwareNightlyBuilds, false)
PROPERTY(bool, enableBackup, false)
PROPERTY(bool, backupOnFlash, true)
PROPERTY(bool, outputDisplayDetails, false)
PROPERTY(bool, checkHardwareCompatibility, true)
PROPERTY(bool, useCompanionNightlyBuilds, false)
PROPERTY(bool, useFirmwareNightlyBuilds, false)
PROPERTY(bool, removeModelSlots, true)
PROPERTY(bool, maximized, false)
PROPERTY(bool, simuSW, false)
PROPERTY(bool, tabbedMdi, false)
PROPERTY(bool, appDebugLog, false)
PROPERTY(bool, fwTraceLog, false)
PROPERTY4(bool, jsSupport, js_support ,false)
PROPERTY4(bool, showSplash, show_splash ,true)
PROPERTY4(bool, snapToClpbrd, snapshot_to_clipboard ,false)
PROPERTY4(bool, autoCheckApp, startup_check_companion ,true)
PROPERTY4(bool, autoCheckFw, startup_check_fw ,true)
// All the global variables
public:
@@ -280,16 +297,7 @@ class AppData: protected CompStoreObj
QString _libDir;
QString _snapshotDir;
QString _updatesDir;
bool _maximized;
bool _jsSupport;
bool _showSplash;
bool _snapToClpbrd;
bool _autoCheckApp;
bool _autoCheckFw;
bool _simuSW;
bool _tabbedMdi;
bool _remvModelSlots;
PROPERTY(QString, appLogsDir, QString(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) % "/" COMPANY "/DebugLogs"))
int _newModelAction; // 0=no action; 1=model wizard; 2=model edit
int _backLight;
@@ -341,16 +349,6 @@ class AppData: protected CompStoreObj
QString snapshotDir();
QString updatesDir();
bool jsSupport();
bool maximized();
bool showSplash();
bool snapToClpbrd();
bool autoCheckApp();
bool autoCheckFw();
bool simuSW();
bool tabbedMdi();
bool removeModelSlots();
int newModelAction();
int backLight();
int embedSplashes();
@@ -399,16 +397,6 @@ class AppData: protected CompStoreObj
void snapshotDir (const QString);
void updatesDir (const QString);
void maximized (const bool);
void jsSupport (const bool);
void showSplash (const bool);
void snapToClpbrd (const bool);
void autoCheckApp (const bool);
void autoCheckFw (const bool);
void simuSW (const bool);
void tabbedMdi (const bool);
void removeModelSlots(const bool);
void newModelAction (const int);
void backLight (const int);
void embedSplashes (const int);