diff --git a/src/blackgui/components/flightplancomponent.cpp b/src/blackgui/components/flightplancomponent.cpp index ff873791f..c6d8628aa 100644 --- a/src/blackgui/components/flightplancomponent.cpp +++ b/src/blackgui/components/flightplancomponent.cpp @@ -8,8 +8,9 @@ #include "flightplancomponent.h" #include "altitudedialog.h" -#include "selcalcodeselector.h" #include "stringlistdialog.h" +#include "simbriefdownloaddialog.h" +#include "selcalcodeselector.h" #include "blackgui/uppercasevalidator.h" #include "blackgui/eventfilter.h" #include "blackgui/guiapplication.h" @@ -120,8 +121,9 @@ namespace BlackGui connect(ui->pb_Load, &QPushButton::pressed, this, &CFlightPlanComponent::loadFlightPlanFromNetwork, Qt::QueuedConnection); connect(ui->pb_Reset, &QPushButton::pressed, this, &CFlightPlanComponent::resetFlightPlan, Qt::QueuedConnection); connect(ui->pb_ValidateFlightPlan, &QPushButton::pressed, this, &CFlightPlanComponent::validateFlightPlan, Qt::QueuedConnection); - connect(ui->tb_SyncWithSimulator, &QPushButton::released, this, &CFlightPlanComponent::syncWithSimulator, Qt::QueuedConnection); - connect(ui->pb_Prefill, &QPushButton::pressed, this, &CFlightPlanComponent::anticipateValues, Qt::QueuedConnection); + connect(ui->tb_SyncWithSimulator, &QPushButton::released, this, &CFlightPlanComponent::syncWithSimulator, Qt::QueuedConnection); + connect(ui->pb_Prefill, &QPushButton::pressed, this, &CFlightPlanComponent::anticipateValues, Qt::QueuedConnection); + connect(ui->pb_SimBrief, &QPushButton::pressed, this, &CFlightPlanComponent::loadFromSimBrief, Qt::QueuedConnection); connect(ui->cb_VoiceCapabilities, &QComboBox::currentTextChanged, this, &CFlightPlanComponent::currentTextChangedToBuildRemarks, Qt::QueuedConnection); connect(ui->cb_VoiceCapabilities, &QComboBox::currentTextChanged, this, &CFlightPlanComponent::syncVoiceComboBoxes, Qt::QueuedConnection); @@ -929,6 +931,52 @@ namespace BlackGui } } + void CFlightPlanComponent::loadFromSimBrief() + { + if (!sGui || sGui->isShuttingDown()) { return; } + if (!m_simBriefDialog) + { + m_simBriefDialog = new CSimBriefDownloadDialog(this); + } + const int rv = m_simBriefDialog->exec(); + if (rv != QDialog::Accepted) { return; } + + const CUrl url = m_simBriefDialog->getSimBriefData().getUrlAndUsername(); + sApp->getFromNetwork(url.toNetworkRequest(), { this, &CFlightPlanComponent::handleSimBriefResponse }); + } + + void CFlightPlanComponent::handleSimBriefResponse(QNetworkReply *nwReplyPtr) + { + // wrap pointer, make sure any exit cleans up reply + // required to use delete later as object is created in a different thread + QScopedPointer nwReply(nwReplyPtr); + if (!sGui || sGui->isShuttingDown()) { return; } + + const QUrl url(nwReply->url()); + const QString urlString(url.toString()); + + if (nwReply->error() == QNetworkReply::NoError) + { + // const qint64 lastModified = CNetworkUtils::lastModifiedMsSinceEpoch(nwReply.data()); + const QString simBriefFP(nwReplyPtr->readAll()); + nwReplyPtr->close(); + if (simBriefFP.isEmpty()) + { + this->showOverlayHTMLMessage("No SimBrief data from " % urlString); + } + else + { + CFlightPlan fp = CFlightPlan::fromSimBriefFormat(simBriefFP); + this->fillWithFlightPlanData(fp); + } + } // no error + else + { + // network error, try next URL + nwReply->abort(); + } + } + bool CFlightPlanComponent::consolidateRemarks(QStringList &remarks, const QString &newRemarks) { if (newRemarks.isEmpty()) { return false; } diff --git a/src/blackgui/components/flightplancomponent.h b/src/blackgui/components/flightplancomponent.h index 7b6df8aa5..5d25eb7bc 100644 --- a/src/blackgui/components/flightplancomponent.h +++ b/src/blackgui/components/flightplancomponent.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace Ui { class CFlightPlanComponent; } namespace BlackGui @@ -62,6 +63,7 @@ namespace BlackGui class CStringListDialog; class CAltitudeDialog; + class CSimBriefDownloadDialog; //! Flight plan widget class BLACKGUI_EXPORT CFlightPlanComponent : public COverlayMessagesTabWidget @@ -90,9 +92,10 @@ namespace BlackGui private: static constexpr int OverlayTimeoutMs = 5000; QScopedPointer ui; - CAltitudeDialog *m_altitudeDialog = nullptr; - CStringListDialog *m_fpRemarksDialog = nullptr; - BlackMisc::Aviation::CFlightPlan m_sentFlightPlan; //!< My flight plan + CAltitudeDialog *m_altitudeDialog = nullptr; + CStringListDialog *m_fpRemarksDialog = nullptr; + CSimBriefDownloadDialog *m_simBriefDialog = nullptr; + BlackMisc::Aviation::CFlightPlan m_sentFlightPlan; //!< my flight plan BlackMisc::Simulation::CAircraftModel m_model; //!< currently used model BlackMisc::CIdentifier m_identifier { "FlightPlanComponent", this }; //!< Flightplan identifier BlackMisc::CSetting m_directories { this }; //!< the swift directories @@ -221,6 +224,12 @@ namespace BlackGui //! Update the remarks histories void updateRemarksHistories(); + //! Load from SimBrief + void loadFromSimBrief(); + + //! Response from SimBrief + void handleSimBriefResponse(QNetworkReply *nwReplyPtr); + //! Consolidate the new remarks list, latest on front static bool consolidateRemarks(QStringList &remarks, const QString &newRemarks); }; diff --git a/src/blackgui/components/flightplancomponent.ui b/src/blackgui/components/flightplancomponent.ui index 034ba0994..f99234114 100644 --- a/src/blackgui/components/flightplancomponent.ui +++ b/src/blackgui/components/flightplancomponent.ui @@ -6,8 +6,8 @@ 0 0 - 404 - 373 + 425 + 512 @@ -43,8 +43,8 @@ 0 0 - 383 - 480 + 404 + 493 @@ -86,6 +86,166 @@ 4 + + + + + IFR + + + + + VFR + + + + + SVFR + + + + + DVFR + + + + + + + + 4 + + + ICAO, e.g. EDDF + + + + + + + &Reset + + + + :/pastel/icons/pastel/16/arrow-refresh.png:/pastel/icons/pastel/16/arrow-refresh.png + + + + + + + 1. Type + + + + + + + 5. Departure airport + + + true + + + + + + + 2. Callsign + + + false + + + true + + + + + + + ICAO, e.g. A321 + + + + + + + 99:99 + + + 00:00 + + + 5 + + + hh:mm e.g. 02:30 + + + + + + + 6. Departure time + + + true + + + + + + + 99:99 + + + 00:00 + + + hh:mm e.g. 02:30 + + + + + + + pilot's name + + + 14. Pilot / homebase + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + goto generator page + + + goto gen. + + + @@ -131,72 +291,13 @@ - - - - Load from disk - - - Load - - - - :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png - - - - - - - Aircraft type - - - 3. Aircraft - - - false - - + + + true - - - - - - 99:99 - - - 00:00 - - - 5 - - - - - - - 99:99 - - - 00:00 - - hh:mm e.g. 02:30 - - - - - - - True airspeed - - - 4. TAS - - - true + homebase (read only) @@ -231,26 +332,170 @@ - - + + + + 7. Cruising altitude + + + true + + + + + + + Load flight plan from network + + + Download + + + + :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png + + + + + + + Save to disk + + + Save + + + + :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png + + + + + + + 13. Alternate airport + + + true + + + + + + + Estimated time enroute + + + 10. Est.time enroute + + + true + + + + + true - P/ICAO/S + sent time will go here (read only) - - - - goto generator page + + + + + 16777215 + 75 + - - goto gen. + + true + + + enter remarks here or use "generator" + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + True airspeed + + + 4. TAS + + + true + + + + + + + 4 + + + ICAO, e.g. EDDF + + + + + + + Send flight plan to network + + + Send + + + + :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png + + + + + + + + + + + + altitude formats + + + altitude formats + + + ... + + + + :/pastel/icons/pastel/16/help.png:/pastel/icons/pastel/16/help.png + + + + + @@ -312,220 +557,22 @@ - - + + - Load flight plan from network + Aircraft type - Download + 3. Aircraft - - - :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png - - - - - - - &Validate - - - - :/diagona/icons/diagona/icons/abacus.png:/diagona/icons/diagona/icons/abacus.png - - - - - - - - 16777215 - 75 - - - - true - - - enter remarks here or use "generator" - - - - - - - Save to disk - - - Save - - - - :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png - - - - - - - strict &check - - - - - - - Send flight plan to network - - - Send - - - - :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png - - - - - - - true - - - sent time will go here (read only) - - - - - - - &Prefill - - - - :/diagona/icons/diagona/icons/compass--pencil.png:/diagona/icons/diagona/icons/compass--pencil.png - - - - - - - 12. Fuel on board + + false true - - - - - - - - - altitude formats - - - altitude formats - - - ... - - - - :/pastel/icons/pastel/16/help.png:/pastel/icons/pastel/16/help.png - - - - - - - - - &Reset - - - - :/pastel/icons/pastel/16/arrow-refresh.png:/pastel/icons/pastel/16/arrow-refresh.png - - - - - - - 4 - - - ICAO, e.g. EDDF - - - - - - - 9. Destination airport - - - true - - - - - - - pilot's name - - - 14. Pilot / homebase - - - true - - - - - - - Estimated time enroute - - - 10. Est.time enroute - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - 4 - - - ICAO, e.g. EDDF - - - @@ -533,111 +580,20 @@ - - - - 7. Cruising altitude - - - true - - - - - - - true - - - pilot's name (read only) - - - - - - - true - - - homebase (read only) - - - - - - - 13. Alternate airport - - - true - - - - - - - 99:99 - - - 00:00 - - - 5 - - - hh:mm e.g. 02:30 - - - - - - - - 16777215 - 75 - - - - true - - - - - + + - copy from generator page + Load from disk - from gen. + Load + + + + :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png - - - - 8. Route - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - @@ -657,6 +613,52 @@ + + + + 8. Route + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + 16777215 + 75 + + + + true + + + + + + + 99:99 + + + 00:00 + + + 5 + + + + + + + true + + + P/ICAO/S + + + @@ -667,6 +669,60 @@ + + + + Anticipate (guess) some values + + + &Prefill + + + + :/diagona/icons/diagona/icons/compass--pencil.png:/diagona/icons/diagona/icons/compass--pencil.png + + + + + + + copy from generator page + + + from gen. + + + + + + + 12. Fuel on board + + + true + + + + + + + 9. Destination airport + + + true + + + + + + + true + + + pilot's name (read only) + + + @@ -677,77 +733,6 @@ - - - - 5. Departure airport - - - true - - - - - - - 6. Departure time - - - true - - - - - - - 1. Type - - - - - - - 2. Callsign - - - false - - - true - - - - - - - - IFR - - - - - VFR - - - - - SVFR - - - - - DVFR - - - - - - - - ICAO, e.g. A321 - - - @@ -755,6 +740,31 @@ + + + + strict &check + + + + + + + SimBrief + + + + + + + &Validate + + + + :/diagona/icons/diagona/icons/abacus.png:/diagona/icons/diagona/icons/abacus.png + + + @@ -790,8 +800,8 @@ 0 0 - 383 - 436 + 415 + 482 @@ -1242,6 +1252,7 @@ p, li { white-space: pre-wrap; } le_EstimatedTimeEnroute le_FuelOnBoard le_AlternateAirport + pb_Remarks cb_VoiceCapabilitiesFirstPage pb_RemarksGenerator pb_GetFromGenerator @@ -1249,14 +1260,12 @@ p, li { white-space: pre-wrap; } le_PilotsName le_PilotsHomeBase le_LastSent - pb_Send - pb_Load - pb_ValidateFlightPlan - cb_StrictCheck - pb_SaveDisk - pb_LoadDisk pb_Prefill pb_Reset + pb_Send + pb_Load + pb_SaveDisk + pb_LoadDisk sa_RemarksGenerator le_AirlineOperator le_AircraftRegistration @@ -1267,9 +1276,10 @@ p, li { white-space: pre-wrap; } cb_VoiceCapabilities cb_PilotRating pte_RemarksGenerated + pb_AddRemarks pte_AdditionalRemarks - pb_CopyOver tbr_EquipmentCodes + pb_CopyOver diff --git a/src/blackmisc/aviation/flightplan.cpp b/src/blackmisc/aviation/flightplan.cpp index 27467a3f5..4893727a6 100644 --- a/src/blackmisc/aviation/flightplan.cpp +++ b/src/blackmisc/aviation/flightplan.cpp @@ -488,7 +488,21 @@ namespace BlackMisc const QString flightNumber = general.firstChildElement("flight_number").text(); fp.setCallsign(CCallsign(airline + flightNumber, CCallsign::Aircraft)); const QString cruiseAlt = general.firstChildElement("initial_altitude").text(); - fp.setCruiseAltitudeString(cruiseAlt); + const int cruiseAltFt = cruiseAlt.toInt(&ok); + if (ok) + { + CAltitude ca(cruiseAltFt, CAltitude::MeanSeaLevel, CLengthUnit::ft()); + if (cruiseAlt.endsWith("00") && cruiseAltFt > 5000) + { + ca.toFlightLevel(); + } + fp.setCruiseAltitude(ca); + if (cruiseAltFt >= 10000) { fp.setFlightRule(CFlightPlan::IFR); } // good guess + } + else + { + fp.setCruiseAltitudeString(cruiseAlt); + } const QString tas = general.firstChildElement("cruise_tas").text(); const int tasKts = tas.toInt(&ok); if (ok) { fp.setCruiseTrueAirspeed(CSpeed(tasKts, CSpeedUnit::kts())); } @@ -863,5 +877,6 @@ namespace BlackMisc { return CIcon::iconByIndex(CIcons::StandardIconAppFlightPlan16); } + } // namespace } // namespace diff --git a/src/blackmisc/aviation/flightplan.h b/src/blackmisc/aviation/flightplan.h index 9742ea923..18ccc8037 100644 --- a/src/blackmisc/aviation/flightplan.h +++ b/src/blackmisc/aviation/flightplan.h @@ -18,6 +18,7 @@ #include "callsign.h" #include "selcal.h" #include "blackmisc/network/voicecapabilities.h" +#include "blackmisc/network/url.h" #include "blackmisc/pq/speed.h" #include "blackmisc/pq/time.h" #include "blackmisc/pq/units.h"