From 7e1a3d4ef2905263ade897b81882f7f026e101c2 Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Fri, 16 Dec 2016 20:51:13 +0100 Subject: [PATCH] Aircraft parts history component This frame component allows to display the current aircraft parts and the received history for a given callsign. refs #835 --- .../components/aircraftpartshistory.cpp | 200 ++++++++++++++++++ .../components/aircraftpartshistory.h | 81 +++++++ .../components/aircraftpartshistory.ui | 117 ++++++++++ src/blackgui/components/mappingcomponent.ui | 35 +++ 4 files changed, 433 insertions(+) create mode 100644 src/blackgui/components/aircraftpartshistory.cpp create mode 100644 src/blackgui/components/aircraftpartshistory.h create mode 100644 src/blackgui/components/aircraftpartshistory.ui diff --git a/src/blackgui/components/aircraftpartshistory.cpp b/src/blackgui/components/aircraftpartshistory.cpp new file mode 100644 index 000000000..d7dcdf7e6 --- /dev/null +++ b/src/blackgui/components/aircraftpartshistory.cpp @@ -0,0 +1,200 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "aircraftpartshistory.h" +#include "ui_aircraftpartshistory.h" + +#include "blackmisc/propertyindexlist.h" +#include "blackmisc/htmlutils.h" +#include "blackcore/context/contextnetwork.h" +#include "blackcore/context/contextsimulator.h" +#include "blackgui/guiapplication.h" +#include "blackgui/uppercasevalidator.h" +#include +#include + +using namespace BlackMisc; +using namespace BlackMisc::Aviation; +using namespace BlackCore; +using namespace BlackCore::Context; + +namespace BlackGui +{ + namespace Components + { + CAircraftPartsHistory::CAircraftPartsHistory(QWidget *parent) : + QFrame(parent), + ui(new Ui::CAircraftPartsHistory) + { + ui->setupUi(this); + ui->le_Callsign->setValidator(new CUpperCaseValidator(this)); + ui->le_Callsign->setCompleter(new QCompleter(ui->le_Callsign)); + this->m_timerCallsignUpdate.setInterval(20 * 1000); + this->m_timerUpdateHistory.setInterval(2 * 1000); + this->initGui(); + this->m_text.setDefaultStyleSheet(CStatusMessageList::htmlStyleSheet()); + connect(ui->le_Callsign, &QLineEdit::textEdited, this, &CAircraftPartsHistory::callsignModified); + connect(ui->le_Callsign, &QLineEdit::returnPressed, this, &CAircraftPartsHistory::callsignEntered); + connect(ui->cb_PartsHistoryEnabled, &QCheckBox::toggled, this, &CAircraftPartsHistory::toggleHistoryEnabled); + + if (this->hasContexts()) + { + connect(sGui->getIContextNetwork(), &IContextNetwork::changedLogOrDebugSettings, this, &CAircraftPartsHistory::valuesChanged); + connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &CAircraftPartsHistory::connectionStatusChanged); + } + connect(&this->m_timerCallsignUpdate, &QTimer::timeout, this, &CAircraftPartsHistory::updateCallsignCompleter); + connect(&this->m_timerUpdateHistory, &QTimer::timeout, this, &CAircraftPartsHistory::updatePartsHistory); + } + + CAircraftPartsHistory::~CAircraftPartsHistory() + { } + + void CAircraftPartsHistory::initGui() + { + const bool needCallsigns = this->partsHistoryEnabled(); + if (needCallsigns && !m_timerCallsignUpdate.isActive() && !m_timerUpdateHistory.isActive()) + { + this->m_timerCallsignUpdate.start(); + this->m_timerUpdateHistory.start(); + this->updateCallsignCompleter(); + } + else if (!needCallsigns) + { + this->m_timerCallsignUpdate.stop(); + this->m_timerUpdateHistory.stop(); + } + + // avoid signal roundtrip + bool c = sGui->getIContextNetwork()->isAircraftPartsHistoryEnabled(); + ui->cb_PartsHistoryEnabled->setChecked(c); + } + + bool CAircraftPartsHistory::hasContexts() const + { + return sGui && sGui->getIContextSimulator() && sGui->getIContextNetwork(); + } + + bool CAircraftPartsHistory::partsHistoryEnabled() const + { + return this->hasContexts(); + } + + void CAircraftPartsHistory::updateCallsignCompleter() + { + if (!this->hasContexts() || !sGui->getIContextNetwork()->isConnected()) { return; } + + const QStringList callsigns = sGui->getIContextNetwork()->getAircraftInRangeCallsigns().toStringList(false); + QCompleter *completer = ui->le_Callsign->completer(); + Q_ASSERT_X(completer, Q_FUNC_INFO, "missing completer"); + if (!completer->model()) + { + completer->setModel(new QStringListModel(callsigns, completer)); + } + else + { + qobject_cast(completer->model())->setStringList(callsigns); + } + } + + void CAircraftPartsHistory::updatePartsHistory() + { + if (!this->hasContexts()) { return; } + if (isBeingModified) { return; } + static const CPropertyIndexList properties({ CStatusMessage::IndexUtcTimestampFormattedHms, CStatusMessage::IndexMessage }); + const CCallsign cs(ui->le_Callsign->text().trimmed().toUpper()); + if (cs.isEmpty()) { return; } + const auto currentAircraftParts = sGui->getIContextNetwork()->getRemoteAircraftParts(cs, -1).frontOrDefault(); + const auto aircraftPartsHistory = sGui->getIContextNetwork()->getAircraftPartsHistory(cs); + + + QString html; + if (currentAircraftParts == CAircraftParts() && aircraftPartsHistory.isEmpty()) + { + html = cs.toQString() + QString(" does not support aircraft parts or nothing received yet."); + } + else + { + QString s; + s += "lights on:"; + s += "
"; + s += "    "; + s += currentAircraftParts.getLights().toQString(); + s += "
"; + s += "gear down: "; + s += BlackMisc::boolToYesNo(currentAircraftParts.isGearDown()); + s += "
"; + s += "flaps pct: "; + s += QString::number(currentAircraftParts.getFlapsPercent()); + s += "
"; + s += "spoilers out: "; + s += BlackMisc::boolToYesNo(currentAircraftParts.isSpoilersOut()); + s += "
"; + s += "engines on: "; + s += "
"; + s += "    "; + s += currentAircraftParts.getEngines().toQString(); + s += "
"; + s += " on ground: "; + s += BlackMisc::boolToYesNo(currentAircraftParts.isOnGround()); + html += s; + if (ui->cb_PartsHistoryEnabled->isChecked()) + { + html +="
"; + html += aircraftPartsHistory.toHtml(properties); + } + } + + this->m_text.setHtml(html); + ui->te_Messages->setDocument(&this->m_text); + + if (ui->cb_AutoScrollEnabled->isChecked()) + { + QTextCursor c = ui->te_Messages->textCursor(); + c.movePosition(QTextCursor::End); + ui->te_Messages->setTextCursor(c); + } + } + + void CAircraftPartsHistory::callsignEntered() + { + isBeingModified = false; + updatePartsHistory(); + m_timerUpdateHistory.start(); + } + + void CAircraftPartsHistory::callsignModified() + { + isBeingModified = true; + } + + void CAircraftPartsHistory::valuesChanged() + { + this->initGui(); + } + + void CAircraftPartsHistory::toggleHistoryEnabled(bool enabled) + { + if (!sGui || !sGui->getIContextNetwork() || !sGui->getIContextSimulator()) { return; } + const QObject *sender = QObject::sender(); + if (sender == ui->cb_PartsHistoryEnabled) + { + sGui->getIContextNetwork()->enableAircraftPartsHistory(enabled); + } + } + + void CAircraftPartsHistory::connectionStatusChanged(INetwork::ConnectionStatus from, INetwork::ConnectionStatus to) + { + Q_UNUSED(from); + if (to == INetwork::Connected || to == INetwork::Disconnected) + { + this->initGui(); + } + } + } // ns +} // ns diff --git a/src/blackgui/components/aircraftpartshistory.h b/src/blackgui/components/aircraftpartshistory.h new file mode 100644 index 000000000..8d157e9ff --- /dev/null +++ b/src/blackgui/components/aircraftpartshistory.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_COMPONENT_AIRCRAFTPARTSHISTORY_H +#define BLACKGUI_COMPONENT_AIRCRAFTPARTSHISTORY_H + +#include "blackcore/network.h" +#include +#include +#include +#include + +namespace Ui { class CAircraftPartsHistory; } +namespace BlackGui +{ + namespace Components + { + /*! + * History frame for received aircraft parts + */ + class CAircraftPartsHistory : public QFrame + { + Q_OBJECT + + public: + //! Constructor + explicit CAircraftPartsHistory(QWidget *parent = nullptr); + + //! Destructor + ~CAircraftPartsHistory(); + + private: + QScopedPointer ui; + QTimer m_timerCallsignUpdate { this }; + QTimer m_timerUpdateHistory { this }; + QTextDocument m_text { this }; + bool isBeingModified = false; + + //! Init + void initGui(); + + //! Contexts available + bool hasContexts() const; + + //! Is parts history enabled? + bool partsHistoryEnabled() const; + + private: + //! Update the completer + void updateCallsignCompleter(); + + //! Update parts history + void updatePartsHistory(); + + //! Callsign was entered + void callsignEntered(); + + //! Callsign was modified + void callsignModified(); + + //! When values changed elsewhere + void valuesChanged(); + + //! Toggle between enabling and disabling of history + void toggleHistoryEnabled(bool enabled); + + //! Connection status changed + void connectionStatusChanged(BlackCore::INetwork::ConnectionStatus from, BlackCore::INetwork::ConnectionStatus to); + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/components/aircraftpartshistory.ui b/src/blackgui/components/aircraftpartshistory.ui new file mode 100644 index 000000000..1df010c65 --- /dev/null +++ b/src/blackgui/components/aircraftpartshistory.ui @@ -0,0 +1,117 @@ + + + CAircraftPartsHistory + + + + 0 + 0 + 276 + 260 + + + + Frame + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 2 + + + 0 + + + 2 + + + + + Callsign: + + + + + + + enable logging of reverse lookup messages + + + Parts History + + + + + + + Enable: + + + + + + + callsign + + + + + + + Autoscroll + + + true + + + + + + + + + + Messages + + + true + + + Result will go here + + + + + + + + diff --git a/src/blackgui/components/mappingcomponent.ui b/src/blackgui/components/mappingcomponent.ui index 5b5693758..df60ba61f 100644 --- a/src/blackgui/components/mappingcomponent.ui +++ b/src/blackgui/components/mappingcomponent.ui @@ -130,6 +130,35 @@ + + + Aircraft parts log + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + @@ -266,6 +295,12 @@
blackgui/components/modelmatcherlogcomponent.h
1 + + BlackGui::Components::CAircraftPartsHistory + QFrame +
blackgui/components/aircraftpartshistory.h
+ 1 +
BlackGui::Components::CAircraftModelStringCompleter QFrame