diff --git a/src/blackgui/menus/menuaction.h b/src/blackgui/menus/menuaction.h index 811b5d897..5aec923f0 100644 --- a/src/blackgui/menus/menuaction.h +++ b/src/blackgui/menus/menuaction.h @@ -171,6 +171,9 @@ namespace BlackGui //! Client model set related static const QString &pathClientModelSet() { static const QString p("Client.Model set"); return p; } + //! Network data + static const QString &pathClientNetwork() { static const QString p("ClientNetwork/Network"); return p; } + // ---- standard view paths -------- //! Database diff --git a/src/blackgui/views/flightplandialog.cpp b/src/blackgui/views/flightplandialog.cpp new file mode 100644 index 000000000..7806bd765 --- /dev/null +++ b/src/blackgui/views/flightplandialog.cpp @@ -0,0 +1,62 @@ +/* Copyright (C) 2019 + * 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. 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 "flightplandialog.h" +#include "ui_flightplandialog.h" + +#include "blackgui/guiapplication.h" +#include "blackcore/context/contextnetwork.h" +#include "blackmisc/aviation/flightplan.h" + +using namespace BlackMisc::Aviation; +using namespace BlackCore::Context; +using namespace BlackGui::Components; + +namespace BlackGui +{ + namespace Views + { + CFlightPlanDialog::CFlightPlanDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CFlightPlanDialog) + { + ui->setupUi(this); + this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); + + connect(ui->pb_LoadFlightPlan, &QPushButton::clicked, this, &CFlightPlanDialog::loadFp); + connect(ui->comp_CallsignCompleter, &CCallsignCompleter::validCallsignEnteredDigest, this, &CFlightPlanDialog::loadFp); + } + + CFlightPlanDialog::~CFlightPlanDialog() + { } + + void CFlightPlanDialog::showFlightPlan(const CCallsign &callsign) + { + if (callsign.isEmpty()) { return; } + if (!sGui || sGui->isShuttingDown() || !sGui->getIContextNetwork()) { return; } + const CFlightPlan fp = sGui->getIContextNetwork()->loadFlightPlanFromNetwork(callsign); + ui->te_FlightPlan->setText(fp.asHTML(true)); + ui->comp_CallsignCompleter->setCallsign(callsign); + this->setDialogTitle(callsign); + this->exec(); + } + + void CFlightPlanDialog::setDialogTitle(const CCallsign &callsign) + { + if (callsign.isEmpty()) { this->setWindowTitle("Flight plan"); return; } + this->setWindowTitle("Flight plan for " + callsign.asString()); + } + + void CFlightPlanDialog::loadFp() + { + const CCallsign cs = ui->comp_CallsignCompleter->getCallsign(false); + this->showFlightPlan(cs); + } + + } // ns +} // ns diff --git a/src/blackgui/views/flightplandialog.h b/src/blackgui/views/flightplandialog.h new file mode 100644 index 000000000..e79d20f60 --- /dev/null +++ b/src/blackgui/views/flightplandialog.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2019 + * 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. 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_VIEWS_FLIGHTPLANDIALOG_H +#define BLACKGUI_VIEWS_FLIGHTPLANDIALOG_H + +#include "blackmisc/aviation/callsign.h" + +#include +#include + +namespace Ui { class CFlightPlanDialog; } +namespace BlackGui +{ + namespace Views + { + //! Flight plan as dialog, also meant for other callsigns + class CFlightPlanDialog : public QDialog + { + Q_OBJECT + + public: + //! Ctor + explicit CFlightPlanDialog(QWidget *parent = nullptr); + + //! Destructor + virtual ~CFlightPlanDialog() override; + + //! Show a particular callsign flight plan + void showFlightPlan(const BlackMisc::Aviation::CCallsign &callsign); + + private: + //! Title + void setDialogTitle(const BlackMisc::Aviation::CCallsign &callsign); + + //! Load FP + void loadFp(); + + QScopedPointer ui; + }; + + } // ns +} // ns + +#endif // guard diff --git a/src/blackgui/views/flightplandialog.ui b/src/blackgui/views/flightplandialog.ui new file mode 100644 index 000000000..48f3bdcaf --- /dev/null +++ b/src/blackgui/views/flightplandialog.ui @@ -0,0 +1,104 @@ + + + CFlightPlanDialog + + + + 0 + 0 + 270 + 266 + + + + Flight plan + + + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + load + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + BlackGui::Components::CCallsignCompleter + QFrame +
blackgui/components/callsigncompleter.h
+ 1 +
+
+ + + + bb_FlightPlanButtons + accepted() + CFlightPlanDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + bb_FlightPlanButtons + rejected() + CFlightPlanDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/blackgui/views/simulatedaircraftview.cpp b/src/blackgui/views/simulatedaircraftview.cpp index 9ea24495d..1c2bf78a9 100644 --- a/src/blackgui/views/simulatedaircraftview.cpp +++ b/src/blackgui/views/simulatedaircraftview.cpp @@ -6,8 +6,8 @@ * or distributed except according to the terms contained in the LICENSE file. */ -#include "blackconfig/buildconfig.h" -#include "blackgui/views/simulatedaircraftview.h" +#include "simulatedaircraftview.h" +#include "flightplandialog.h" #include "blackgui/models/simulatedaircraftlistmodel.h" #include "blackgui/menus/menuaction.h" #include "blackgui/guiapplication.h" @@ -16,6 +16,7 @@ #include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/aviation/callsign.h" #include "blackmisc/icons.h" +#include "blackconfig/buildconfig.h" #include #include @@ -46,13 +47,14 @@ namespace BlackGui this->setSortIndicator(); } - void CSimulatedAircraftView::configureMenu(bool menuRecalculate, bool menuHighlightAndFollow, bool menuEnableAircraft, bool menuFastPositionUpdates, bool menuGndFlag) + void CSimulatedAircraftView::configureMenu(bool menuRecalculate, bool menuHighlightAndFollow, bool menuEnableAircraft, bool menuFastPositionUpdates, bool menuGndFlag, bool menuFlightPlan) { m_withRecalculate = menuRecalculate; m_withMenuEnableAircraft = menuEnableAircraft; m_withMenuFastPosition = menuFastPositionUpdates; m_withMenuHighlightAndFollow = menuHighlightAndFollow; m_withMenuEnableGndFlag = menuGndFlag; + m_withMenuFlightPlan = menuFlightPlan; } void CSimulatedAircraftView::configureMenuFastPositionUpdates(bool menuFastPositionUpdates) @@ -99,6 +101,10 @@ namespace BlackGui menuActions.addMenuCom(); menuActions.addAction(CIcons::appTextMessages16(), "Show text messages", CMenuAction::pathClientCom(), { this, &CSimulatedAircraftView::requestTextMessage }); + if (m_withMenuFlightPlan && networkContext() && networkContext()->isConnected()) + { + menuActions.addAction(CIcons::appFlightPlan16(), "Flight plan", CMenuAction::pathClientNetwork(), { this, &CSimulatedAircraftView::showFlightPlanDialog }); + } if (m_withMenuEnableAircraft) { menuActions.addAction(CIcons::appAircraft16(), aircraft.isEnabled() ? "Disable aircraft" : "Enabled aircraft", CMenuAction::pathClientSimulationDisplay(), { this, &CSimulatedAircraftView::toggleEnabledAircraft }); @@ -116,7 +122,8 @@ namespace BlackGui { menuActions.addAction(CIcons::globe16(), aircraft.fastPositionUpdates() ? "Normal updates" : "Fast position updates (send)", CMenuAction::pathClientSimulationTransfer(), { this, &CSimulatedAircraftView::toggleFastPositionUpdates }); } - const bool any = m_withMenuEnableAircraft || m_withMenuFastPosition || m_withMenuHighlightAndFollow || m_withMenuEnableGndFlag; + + const bool any = m_withMenuEnableAircraft || m_withMenuFastPosition || m_withMenuHighlightAndFollow || m_withMenuEnableGndFlag || m_withMenuFlightPlan; if (any && (sApp && sApp->isDeveloperFlagSet())) { menuActions.addAction(CIcons::appSimulator16(), "Show position log.", CMenuAction::pathClientSimulationDisplay(), { this, &CSimulatedAircraftView::showPositionLogInSimulator }); @@ -293,6 +300,19 @@ namespace BlackGui nwContext->updateAircraftSupportingGndFLag(aircraft.getCallsign(), aircraft.isSupportingGndFlag()); } + void CSimulatedAircraftView::showFlightPlanDialog() + { + if (!m_withMenuFlightPlan) { return; } + if (!networkContext() || !networkContext()->isConnected()) { return; } + + const CSimulatedAircraft aircraft = this->selectedObject(); + if (!aircraft.hasCallsign()) { return; } + + const CCallsign cs = aircraft.getCallsign(); + if (!m_fpDialog) { m_fpDialog = new CFlightPlanDialog(this); } + m_fpDialog->showFlightPlan(cs); + } + IContextSimulator *CSimulatedAircraftView::simulatorContext() { if (!sGui || sGui->isShuttingDown() || !sGui->getIContextSimulator()) { return nullptr; } diff --git a/src/blackgui/views/simulatedaircraftview.h b/src/blackgui/views/simulatedaircraftview.h index c9f0bb2fe..6844ebe20 100644 --- a/src/blackgui/views/simulatedaircraftview.h +++ b/src/blackgui/views/simulatedaircraftview.h @@ -36,6 +36,8 @@ namespace BlackGui namespace Menus { class CMenuActions; } namespace Views { + class CFlightPlanDialog; + //! Aircraft view class BLACKGUI_EXPORT CSimulatedAircraftView : public CViewWithCallsignObjects @@ -50,7 +52,7 @@ namespace BlackGui void setAircraftMode(Models::CSimulatedAircraftListModel::AircraftMode mode); //! Configure the menu - void configureMenu(bool menuRecalculate, bool menuHighlightAndFollow, bool menuEnableAircraft, bool menuFastPositionUpdates, bool menuGndFlag); + void configureMenu(bool menuRecalculate, bool menuHighlightAndFollow, bool menuEnableAircraft, bool menuFastPositionUpdates, bool menuGndFlag, bool menuFlightPlan); //! Configure fast position updates menu void configureMenuFastPositionUpdates(bool menuFastPositionUpdates); @@ -127,6 +129,9 @@ namespace BlackGui //! Update the gnd.flag support void updateAircraftSupportingGndFLag(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); + //! FP dialog + void showFlightPlanDialog(); + //! Simulator context static BlackCore::Context::IContextSimulator *simulatorContext(); @@ -138,6 +143,9 @@ namespace BlackGui bool m_withMenuEnableAircraft = true; bool m_withMenuEnableGndFlag = true; bool m_withMenuFastPosition = true; + bool m_withMenuFlightPlan = true; + + CFlightPlanDialog *m_fpDialog = nullptr; }; } // ns } // ns diff --git a/src/blackmisc/aviation/flightplan.cpp b/src/blackmisc/aviation/flightplan.cpp index 83024e57e..245b42028 100644 --- a/src/blackmisc/aviation/flightplan.cpp +++ b/src/blackmisc/aviation/flightplan.cpp @@ -359,20 +359,36 @@ namespace BlackMisc } QString CFlightPlan::convertToQString(bool i18n) const + { + return this->buildString(i18n, " "); + } + + QString CFlightPlan::asHTML(bool i18n) const + { + return this->buildString(i18n, "
"); + } + + QString CFlightPlan::buildString(bool i18n, const QString &separator) const { const QString s = m_callsign.toQString(i18n) - % u' ' % m_equipmentSuffix - % u' ' % m_originAirportIcao.toQString(i18n) - % u' ' % m_destinationAirportIcao.toQString(i18n) - % u' ' % m_alternateAirportIcao.toQString(i18n) - % u' ' % m_takeoffTimePlanned.toString("ddhhmm") - % u' ' % m_takeoffTimeActual.toString("ddhhmm") - % u' ' % m_enrouteTime.toQString(i18n) - % u' ' % m_fuelTime.toQString(i18n) - % u' ' % m_cruiseAltitude.toQString(i18n) - % u' ' % m_cruiseTrueAirspeed.toQString(i18n) - % u' ' % m_route - % u' ' % this->getRemarks(); + % u" aircraft: " % m_equipmentSuffix + % separator + % u"origin: " % m_originAirportIcao.toQString(i18n) + % u" destination: " % m_destinationAirportIcao.toQString(i18n) + % u" alternate: " % m_alternateAirportIcao.toQString(i18n) + % separator + % u"takeoff planed: " % m_takeoffTimePlanned.toString("ddhhmm") + % u" actual: " % m_takeoffTimeActual.toString("ddhhmm") + % separator + % u"enroute time: " % m_enrouteTime.toQString(i18n) + % u" fuel time:" % m_fuelTime.toQString(i18n) + % separator + % u"altitude: " % m_cruiseAltitude.toQString(i18n) + % u" speed: " % m_cruiseTrueAirspeed.toQString(i18n) + % separator + % u"route: " % m_route + % separator + % u"remarks: " % this->getRemarks(); return s; } @@ -615,7 +631,7 @@ namespace BlackMisc catch (const CJsonException &ex) { const CStatusMessage m = ex.toStatusMessage(&fp, QString("Parsing flight plan from failed.")); - Q_UNUSED(m); + Q_UNUSED(m) } return fp; } diff --git a/src/blackmisc/aviation/flightplan.h b/src/blackmisc/aviation/flightplan.h index babc76b4c..2890bfe6b 100644 --- a/src/blackmisc/aviation/flightplan.h +++ b/src/blackmisc/aviation/flightplan.h @@ -185,7 +185,6 @@ namespace BlackMisc static constexpr int MaxRouteLength = 512; //!< Max.route length static constexpr int MaxRouteAndRemarksLength = 624; //!< Max.length for Route and Remarks - //! Default constructor CFlightPlan(); @@ -385,6 +384,9 @@ namespace BlackMisc //! \copydoc BlackMisc::Mixin::String::toQString() QString convertToQString(bool i18n = false) const; + //! As HTML + QString asHTML(bool i18n = false) const; + //! From vPilot data static CFlightPlan fromVPilotFormat(const QString &vPilotData); @@ -456,24 +458,27 @@ namespace BlackMisc static const QStringList &prefixCodes(); private: - CCallsign m_callsign; //!< aircraft callsign - CAircraftIcaoCode m_aircraftIcao; //!< Aircraft ICAO code - QString m_prefix; //!< e.g. "T/A320/F" -> the "T" - QString m_equipmentSuffix; //!< e.g. "T/A320/F" -> the "F" - CAirportIcaoCode m_originAirportIcao; - CAirportIcaoCode m_destinationAirportIcao; - CAirportIcaoCode m_alternateAirportIcao; - QDateTime m_takeoffTimePlanned; - QDateTime m_takeoffTimeActual; + CCallsign m_callsign; //!< aircraft callsign + CAircraftIcaoCode m_aircraftIcao; //!< Aircraft ICAO code + QString m_prefix; //!< e.g. "T/A320/F" -> the "T" + QString m_equipmentSuffix; //!< e.g. "T/A320/F" -> the "F" + CAirportIcaoCode m_originAirportIcao; + CAirportIcaoCode m_destinationAirportIcao; + CAirportIcaoCode m_alternateAirportIcao; + QDateTime m_takeoffTimePlanned; + QDateTime m_takeoffTimeActual; PhysicalQuantities::CTime m_enrouteTime; PhysicalQuantities::CTime m_fuelTime; CAltitude m_cruiseAltitude; - QString m_cruiseAltitudeString; + QString m_cruiseAltitudeString; PhysicalQuantities::CSpeed m_cruiseTrueAirspeed; - FlightRules m_flightRules; - QString m_route; + FlightRules m_flightRules; + QString m_route; CFlightPlanRemarks m_remarks; + //! As string + QString buildString(bool i18n = false, const QString &separator = " ") const; + BLACK_METACLASS( CFlightPlan, // callsign will be current flight