refs #873, updated internals component

* can trigger request of parts
* opening logs
* update parts in UI from aircraft
This commit is contained in:
Klaus Basan
2017-02-01 02:52:27 +01:00
committed by Mathew Sutcliffe
parent d4b2238dc6
commit 273427d3d9
5 changed files with 321 additions and 102 deletions

View File

@@ -16,11 +16,12 @@
#include "blackgui/components/remoteaircraftselector.h"
#include "blackgui/guiapplication.h"
#include "blackgui/uppercasevalidator.h"
#include "blackmisc/simulation/interpolationlogger.h"
#include "blackmisc/simulation/interpolationrenderingsetup.h"
#include "blackmisc/aviation/aircraftenginelist.h"
#include "blackmisc/aviation/aircraftlights.h"
#include "blackmisc/aviation/callsign.h"
#include "blackmisc/network/textmessage.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/statusmessage.h"
#include "ui_internalscomponent.h"
@@ -34,6 +35,7 @@
#include <QTextEdit>
#include <Qt>
#include <QtGlobal>
#include <QDesktopServices>
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
@@ -52,6 +54,7 @@ namespace BlackGui
{
ui->setupUi(this);
ui->tw_Internals->setCurrentIndex(0);
ui->comp_RemoteAircraftSelector->indicatePartsEnabled(true);
ui->le_TxtMsgFrom->setValidator(new CUpperCaseValidator(ui->le_TxtMsgFrom));
ui->le_TxtMsgTo->setValidator(new CUpperCaseValidator(ui->le_TxtMsgFrom));
@@ -63,6 +66,7 @@ namespace BlackGui
connect(ui->pb_AircraftPartsEnginesOn, &QPushButton::pressed, this, &CInternalsComponent::ps_setAllEngines);
connect(ui->pb_AircraftPartsEnginesOff, &QPushButton::pressed, this, &CInternalsComponent::ps_setAllEngines);
connect(ui->pb_AircraftPartsUiToJson, &QPushButton::pressed, this, &CInternalsComponent::ps_guiToJson);
connect(ui->pb_CurrentParts, &QPushButton::pressed, this, &CInternalsComponent::ps_setCurrentParts);
connect(ui->cb_DebugContextAudio, &QCheckBox::stateChanged, this, &CInternalsComponent::ps_enableDebug);
connect(ui->cb_DebugContextApplication, &QCheckBox::stateChanged, this, &CInternalsComponent::ps_enableDebug);
@@ -78,6 +82,10 @@ namespace BlackGui
connect(ui->tb_LogStatusMessage, &QPushButton::pressed, this, &CInternalsComponent::ps_logStatusMessage);
connect(ui->le_StatusMessage, &QLineEdit::returnPressed, this, &CInternalsComponent::ps_logStatusMessage);
connect(ui->pb_LatestInterpolationLog, &QPushButton::pressed, this, &CInternalsComponent::ps_showLogFiles);
connect(ui->pb_LatestPartsLog, &QPushButton::pressed, this, &CInternalsComponent::ps_showLogFiles);
connect(ui->pb_RequestFromNetwork, &QPushButton::pressed, this, &CInternalsComponent::ps_requestPartsFromNetwork);
contextFlagsToGui();
}
@@ -98,7 +106,7 @@ namespace BlackGui
CLogMessage(this).validationError("Cannot send aircraft parts, network not connected");
return;
}
CCallsign callsign(ui->comp_RemoteAircraftSelector->getSelectedCallsign());
const CCallsign callsign(ui->comp_RemoteAircraftSelector->getSelectedCallsign());
if (callsign.isEmpty())
{
CLogMessage(this).validationError("No valid callsign selected");
@@ -106,7 +114,7 @@ namespace BlackGui
}
CAircraftParts parts;
bool json = (QObject::sender() == ui->pb_SendAircraftPartsJson);
const bool json = (QObject::sender() == ui->pb_SendAircraftPartsJson);
if (json)
{
@@ -141,6 +149,7 @@ namespace BlackGui
this->ps_guiToJson();
}
ui->tb_History->setToolTip("");
sGui->getIContextNetwork()->testAddAircraftParts(callsign, parts, ui->cb_AircraftPartsIncremental->isChecked());
CLogMessage(this).info("Added parts for %1") << callsign.toQString();
}
@@ -169,11 +178,30 @@ namespace BlackGui
void CInternalsComponent::ps_guiToJson()
{
QJsonDocument json(guiToAircraftParts().toJson());
const QJsonDocument json(guiToAircraftParts().toJson());
QString j(json.toJson(QJsonDocument::Indented));
ui->te_AircraftPartsJson->setText(j);
}
void CInternalsComponent::ps_setCurrentParts()
{
if (!sGui->getIContextNetwork()->isConnected()) { return; }
const CCallsign callsign(ui->comp_RemoteAircraftSelector->getSelectedCallsign());
if (callsign.isEmpty()) { return; }
const CAircraftPartsList partsList = sGui->getIContextNetwork()->getRemoteAircraftParts(callsign, -1);
if (partsList.isEmpty())
{
CStatusMessage(this).info("No parts for '%1'") << callsign.asString();
return;
}
const CAircraftParts parts = partsList.latestObject();
const CStatusMessageList history = sGui->getIContextNetwork()->getAircraftPartsHistory(callsign);
partsToGui(parts);
ui->te_AircraftPartsJson->setText(parts.toJsonString());
ui->tb_History->setToolTip(history.toHtml());
}
void CInternalsComponent::ps_enableDebug(int state)
{
Q_ASSERT(sGui->getIContextApplication());
@@ -182,9 +210,9 @@ namespace BlackGui
Q_ASSERT(sGui->getIContextOwnAircraft());
Q_ASSERT(sGui->getIContextSimulator());
Qt::CheckState checkState = static_cast<Qt::CheckState>(state);
bool debug = (checkState == Qt::Checked);
QObject *sender = QObject::sender();
const Qt::CheckState checkState = static_cast<Qt::CheckState>(state);
const bool debug = (checkState == Qt::Checked);
const QObject *sender = QObject::sender();
if (sender == ui->cb_DebugContextApplication) { sGui->getIContextApplication()->setDebugEnabled(debug); }
else if (sender == ui->cb_DebugContextAudio) { sGui->getIContextAudio()->setDebugEnabled(debug); }
@@ -247,9 +275,46 @@ namespace BlackGui
CLogMessage::preformatted(sm);
}
void CInternalsComponent::ps_showLogFiles()
{
QString file;
const QObject *sender = QObject::sender();
if (sender == ui->pb_LatestInterpolationLog)
{
file = CInterpolationLogger::getLatestLogFiles().first();
}
else if (sender == ui->pb_LatestPartsLog)
{
file = CInterpolationLogger::getLatestLogFiles().last();
}
if (file.isEmpty()) { return; }
QDesktopServices::openUrl(QUrl::fromLocalFile(file));
}
void CInternalsComponent::ps_requestPartsFromNetwork()
{
const CCallsign callsign(ui->comp_RemoteAircraftSelector->getSelectedCallsign());
if (callsign.isEmpty())
{
CLogMessage(this).validationError("No valid callsign selected");
return;
}
ui->pb_RequestFromNetwork->setEnabled(false);
sGui->getIContextNetwork()->testRequestAircraftConfig(callsign);
CLogMessage(this).info("Request aircraft config for '%1'") << callsign.asString();
// simple approach to update UI when parts are received
QTimer::singleShot(3000, this, [this]
{
ui->pb_CurrentParts->click();
ui->pb_RequestFromNetwork->setEnabled(true);
});
}
CAircraftParts CInternalsComponent::guiToAircraftParts() const
{
CAircraftLights lights(
const CAircraftLights lights(
ui->cb_AircraftPartsLightsStrobe->isChecked(),
ui->cb_AircraftPartsLightsLanding->isChecked(),
ui->cb_AircraftPartsLightsTaxi->isChecked(),
@@ -257,7 +322,7 @@ namespace BlackGui
ui->cb_AircraftPartsLightsNav->isChecked(),
ui->cb_AircraftPartsLightsLogo->isChecked()
);
CAircraftEngineList engines(
const CAircraftEngineList engines(
{
ui->cb_AircraftPartsEngine1->isChecked(),
ui->cb_AircraftPartsEngine2->isChecked(),

View File

@@ -57,6 +57,9 @@ namespace BlackGui
//! GUI to JSON
void ps_guiToJson();
//! Current parts in UI
void ps_setCurrentParts();
//! Enable / disable debugging
void ps_enableDebug(int state);
@@ -66,6 +69,12 @@ namespace BlackGui
//! Send a dummy status message
void ps_logStatusMessage();
//! Show log files
void ps_showLogFiles();
//! Request parts (aka aircraft config) from network
void ps_requestPartsFromNetwork();
private:
QScopedPointer<Ui::CInternalsComponent> ui;
@@ -78,7 +87,6 @@ namespace BlackGui
//! Set the context flags
void contextFlagsToGui();
};
} // namespace
} // namespace

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>289</width>
<height>450</height>
<width>314</width>
<height>590</height>
</rect>
</property>
<property name="windowTitle">
@@ -57,6 +57,18 @@
<string>Contexts</string>
</property>
<layout class="QGridLayout" name="gl_Contexts">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="cb_DebugContextAudio">
<property name="text">
@@ -74,7 +86,7 @@
<item row="0" column="3">
<widget class="QCheckBox" name="cb_DebugContextOwnAircraft">
<property name="text">
<string>Own aircraftt</string>
<string>Own aircraft</string>
</property>
</widget>
</item>
@@ -101,6 +113,18 @@
<string>Driver plugin and interpolator</string>
</property>
<layout class="QGridLayout" name="gl_DriverAndInterpolator">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="cb_DebugDriver">
<property name="text">
@@ -129,10 +153,22 @@
</widget>
</item>
<item>
<widget class="QWidget" name="wi_StatusMessage" native="true">
<widget class="QGroupBox" name="gb_StatusMessage">
<property name="title">
<string>Status message</string>
</property>
<layout class="QGridLayout" name="gl_StatusMessage">
<property name="leftMargin">
<number>3</number>
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item row="0" column="3">
<widget class="QRadioButton" name="rb_StatusMessageWarning">
@@ -180,15 +216,38 @@
</widget>
</item>
<item>
<widget class="QWidget" name="wi_TextMessages" native="true">
<widget class="QGroupBox" name="gb_TextMessages">
<property name="title">
<string>Text message</string>
</property>
<layout class="QGridLayout" name="gl_TextMessages">
<property name="leftMargin">
<number>3</number>
<number>4</number>
</property>
<property name="topMargin">
<number>9</number>
<number>4</number>
</property>
<item row="2" column="1">
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item row="1" column="2">
<widget class="QPushButton" name="pb_SendTextMessage">
<property name="text">
<string>send</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="le_TxtMsgFrom">
<property name="placeholderText">
<string>from</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="dsb_TxtMsgFrequency">
<property name="suffix">
<string>MHz</string>
@@ -210,35 +269,14 @@
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pb_SendTextMessage">
<property name="text">
<string>send</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lbl_TextMessages">
<property name="text">
<string>Text messages:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="le_TxtMsgFrom">
<property name="placeholderText">
<string>from</string>
</property>
</widget>
</item>
<item row="1" column="2">
<item row="0" column="2">
<widget class="QLineEdit" name="le_TxtMsgTo">
<property name="placeholderText">
<string>to</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<item row="2" column="1" colspan="3">
<widget class="QPlainTextEdit" name="pte_TxtMsg">
<property name="placeholderText">
<string>Text message</string>
@@ -265,21 +303,42 @@
</widget>
<widget class="QWidget" name="tb_Statistics">
<attribute name="title">
<string>Statistics</string>
<string>Statistics / Logs</string>
</attribute>
<widget class="QLabel" name="lbl_Disclaimer">
<property name="geometry">
<rect>
<x>80</x>
<y>60</y>
<width>267</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>WORK IN PROGRESS!</string>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="fl_Statistics">
<item row="0" column="0">
<widget class="QLabel" name="lbl_LatestInterpolationLog">
<property name="text">
<string>Latest interpolation log</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pb_LatestInterpolationLog">
<property name="text">
<string>show</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_LatestPartsLog">
<property name="text">
<string>Latest parts log</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pb_LatestPartsLog">
<property name="text">
<string>show</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tb_AircraftParts">
<attribute name="title">
@@ -301,6 +360,12 @@
<item>
<widget class="QFrame" name="fr_Aircraft">
<layout class="QFormLayout" name="fl_Aircraft">
<property name="horizontalSpacing">
<number>4</number>
</property>
<property name="verticalSpacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
@@ -330,6 +395,52 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_PartsNetwork">
<property name="text">
<string>Network</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="wi_PartsNetwork" native="true">
<layout class="QHBoxLayout" name="hl_PartsNetwork">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="pb_RequestFromNetwork">
<property name="toolTip">
<string>Request from network</string>
</property>
<property name="text">
<string>request (network)</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="tb_History">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../blackmisc/blackmisc.qrc">
<normaloff>:/diagona/icons/diagona/icons/table-sheet.png</normaloff>:/diagona/icons/diagona/icons/table-sheet.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
@@ -391,7 +502,7 @@
<item>
<layout class="QGridLayout" name="gl_AircraftParts">
<property name="spacing">
<number>6</number>
<number>4</number>
</property>
<item row="4" column="1">
<widget class="QCheckBox" name="cb_AircraftPartsLightsStrobe">
@@ -400,6 +511,13 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="cb_AircraftPartsLightsBeacon">
<property name="text">
<string>Beacon</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="cb_AircraftPartsLightsLanding">
<property name="text">
@@ -421,13 +539,6 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="cb_AircraftPartsLightsBeacon">
<property name="text">
<string>Beacon</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lbl_AircraftPartsFlapsPercentage">
<property name="text">
@@ -435,13 +546,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="cb_AircraftPartsSpoilers">
<property name="text">
<string>Spoilers</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="cb_AircraftPartsLightsTaxi">
<property name="text">
@@ -449,6 +553,13 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="cb_AircraftPartsSpoilers">
<property name="text">
<string>Spoilers</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_AircraftPartsLights">
<property name="text">
@@ -463,6 +574,20 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pb_AircraftPartsLightsOn">
<property name="text">
<string>all on</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pb_AircraftPartsLightsOff">
<property name="text">
<string>all off</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="cb_AircraftPartsLightsNav">
<property name="text">
@@ -480,15 +605,8 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pb_AircraftPartsLightsOn">
<property name="text">
<string>all on</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pb_AircraftPartsLightsOff">
<item row="5" column="2">
<widget class="QPushButton" name="pb_AircraftPartsEnginesOff">
<property name="text">
<string>all off</string>
</property>
@@ -501,20 +619,6 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="cb_AircraftPartsIsOnGround">
<property name="text">
<string>on ground</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="pb_AircraftPartsEnginesOff">
<property name="text">
<string>all off</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pb_AircraftPartsUiToJson">
<property name="text">
@@ -522,6 +626,13 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="cb_AircraftPartsIsOnGround">
<property name="text">
<string>on ground</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="3">
<widget class="QFrame" name="fr_Engines">
<property name="minimumSize">
@@ -630,8 +741,21 @@
</property>
<item>
<widget class="QCheckBox" name="cb_AircraftPartsIncremental">
<property name="toolTip">
<string>incremental</string>
</property>
<property name="text">
<string>Incremental</string>
<string>Incr.</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pb_CurrentParts">
<property name="toolTip">
<string>set current parts values</string>
</property>
<property name="text">
<string>current</string>
</property>
</widget>
</item>

View File

@@ -151,6 +151,26 @@ namespace BlackMisc
return worker;
}
QStringList IInterpolator::getLatestLogFiles()
{
QStringList files({ "", ""});
const QString logDir = CDirectoryUtils::getLogDirectory();
QDir logs(logDir);
if (!logs.exists()) { return files; }
logs.setNameFilters(QStringList() << "*interpolation.html" << "*parts.html");
const QStringList interpolations = logs.entryList(QStringList({"*interpolation.html"}), QDir::NoFilter, QDir::Time);
if (!interpolations.isEmpty())
{
files[0] = CFileUtils::appendFilePaths(logDir, interpolations.first());
}
const QStringList parts = logs.entryList(QStringList({"*parts.html"}), QDir::NoFilter, QDir::Time);
if (!parts.isEmpty())
{
files[1] = CFileUtils::appendFilePaths(logDir, parts.first());
}
return files;
}
CStatusMessageList IInterpolator::writeLogFile(const QList<InterpolationLog> &interpolation, const QList<PartsLog> &parts)
{
if (parts.isEmpty() && interpolation.isEmpty()) { return CStatusMessage(static_cast<IInterpolator *>(nullptr)).warning("No data for log"); }

View File

@@ -124,6 +124,7 @@ namespace BlackMisc
void setInterpolatorSetup(const CInterpolationAndRenderingSetup &setup);
//! Write a log in background
//! \threadsafe
BlackMisc::CWorker *writeLogInBackground();
//! Clear log file
@@ -134,18 +135,19 @@ namespace BlackMisc
//! \remark public for FS9 to get setup in Fs9Client
CInterpolationAndRenderingSetup getInterpolatorSetup() const;
/*!
* Takes input between 0 and 1 and returns output between 0 and 1 smoothed with an S-shaped curve.
*
* Useful for making interpolation seem smoother, efficiently as it just uses simple arithmetic.
* \see https://en.wikipedia.org/wiki/Smoothstep
* \see http://sol.gfxile.net/interpolation/
*/
//! Takes input between 0 and 1 and returns output between 0 and 1 smoothed with an S-shaped curve.
//!
//! Useful for making interpolation seem smoother, efficiently as it just uses simple arithmetic.
//! \see https://en.wikipedia.org/wiki/Smoothstep
//! \see http://sol.gfxile.net/interpolation/
static double smootherStep(double x)
{
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}
//! Latest log files: 0 Interpolation 1 Parts
static QStringList getLatestLogFiles();
protected:
//! Log for interpolation
struct InterpolationLog