From e2f8f097e04ed00526f5943bd0a4667aa450247c Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 19 Jul 2016 04:29:11 +0200 Subject: [PATCH] refs #712, completers and load from disk for flight plan --- .../components/flightplancomponent.cpp | 143 ++++- src/blackgui/components/flightplancomponent.h | 22 +- .../components/flightplancomponent.ui | 558 ++++++++++-------- src/blackmisc/aviation/flightplan.cpp | 2 - src/blackmisc/blackmisc.qrc | 13 + 5 files changed, 465 insertions(+), 273 deletions(-) diff --git a/src/blackgui/components/flightplancomponent.cpp b/src/blackgui/components/flightplancomponent.cpp index 876ebf2bf..ac4e65916 100644 --- a/src/blackgui/components/flightplancomponent.cpp +++ b/src/blackgui/components/flightplancomponent.cpp @@ -9,6 +9,8 @@ #include "blackcore/context/contextnetwork.h" #include "blackcore/context/contextownaircraft.h" +#include "blackcore/webdataservices.h" +#include "blackgui/uppercasevalidator.h" #include "blackgui/components/flightplancomponent.h" #include "blackgui/components/selcalcodeselector.h" #include "blackgui/guiapplication.h" @@ -18,6 +20,7 @@ #include "blackmisc/aviation/callsign.h" #include "blackmisc/logcategory.h" #include "blackmisc/logmessage.h" +#include "blackconfig/buildconfig.h" #include "blackmisc/network/user.h" #include "blackmisc/pq/pqstring.h" #include "blackmisc/pq/speed.h" @@ -36,6 +39,7 @@ #include #include #include +#include #include using namespace BlackMisc; @@ -43,6 +47,8 @@ using namespace BlackMisc::Aviation; using namespace BlackMisc::Simulation; using namespace BlackMisc::PhysicalQuantities; using namespace BlackGui; +using namespace BlackCore; +using namespace BlackConfig; namespace BlackGui { @@ -52,11 +58,19 @@ namespace BlackGui QTabWidget(parent), ui(new Ui::CFlightPlanComponent) { + Q_ASSERT_X(sGui, Q_FUNC_INFO, "missing sGui"); + + // UI ui->setupUi(this); // fix style this->tabBar()->setExpanding(false); + // validators + CUpperCaseValidator *ucv = new CUpperCaseValidator(this); + ui->le_Callsign->setValidator(ucv); + ui->le_AircraftType->setValidator(ucv); + // connect connect(this->ui->pb_Send, &QPushButton::pressed, this, &CFlightPlanComponent::ps_sendFlightPlan); connect(this->ui->pb_Load, &QPushButton::pressed, this, &CFlightPlanComponent::ps_loadFlightPlanFromNetwork); @@ -69,12 +83,15 @@ namespace BlackGui connect(this->ui->cb_PilotRating, &QComboBox::currentTextChanged, this, &CFlightPlanComponent::ps_currentTextChangedToBuildRemarks); connect(this->ui->cb_RequiredNavigationPerformance, &QComboBox::currentTextChanged, this, &CFlightPlanComponent::ps_currentTextChangedToBuildRemarks); + connect(this->ui->pb_LoadDisk, &QPushButton::clicked, this, &CFlightPlanComponent::ps_loadFromDisk); + connect(this->ui->pb_SaveDisk, &QPushButton::clicked, this, &CFlightPlanComponent::ps_saveToDisk); + bool c = connect(this->ui->le_AircraftRegistration, SIGNAL(textChanged(QString)), this, SLOT(ps_buildRemarksString())); - Q_ASSERT(c); + Q_ASSERT_X(c, Q_FUNC_INFO, "failed connect"); c = connect(this->ui->cb_NoSidsStarts, SIGNAL(toggled(bool)), this, SLOT(ps_buildRemarksString())); - Q_ASSERT(c); + Q_ASSERT_X(c, Q_FUNC_INFO, "failed connect"); c = connect(this->ui->le_AirlineOperator, SIGNAL(textChanged(QString)), this, SLOT(ps_buildRemarksString())); - Q_ASSERT(c); + Q_ASSERT_X(c, Q_FUNC_INFO, "failed connect"); Q_UNUSED(c); connect(this->ui->pte_AdditionalRemarks, &QPlainTextEdit::textChanged, this, &CFlightPlanComponent::ps_buildRemarksString); @@ -83,6 +100,10 @@ namespace BlackGui connect(this->ui->pb_CopyOver, &QPushButton::pressed, this, &CFlightPlanComponent::ps_copyRemarks); connect(this->ui->pb_RemarksGenerator, &QPushButton::clicked, this, &CFlightPlanComponent::ps_currentTabGenerator); + // web services + connect(sGui->getWebDataServices(), &CWebDataServices::allSwiftDbDataRead, this, &CFlightPlanComponent::ps_swiftDataRead); + + // init GUI this->ps_resetFlightPlan(); this->ps_buildRemarksString(); } @@ -117,8 +138,8 @@ namespace BlackGui void CFlightPlanComponent::fillWithFlightPlanData(const BlackMisc::Aviation::CFlightPlan &flightPlan) { this->ui->le_AlternateAirport->setText(flightPlan.getAlternateAirportIcao().asString()); - this->ui->le_DestinationAirport->setText(flightPlan.getAlternateAirportIcao().asString()); - this->ui->le_OriginAirport->setText(flightPlan.getAlternateAirportIcao().asString()); + this->ui->le_DestinationAirport->setText(flightPlan.getDestinationAirportIcao().asString()); + this->ui->le_OriginAirport->setText(flightPlan.getOriginAirportIcao().asString()); this->ui->pte_Route->setPlainText(flightPlan.getRoute()); this->ui->pte_Remarks->setPlainText(flightPlan.getRemarks()); this->ui->le_TakeOffTimePlanned->setText(flightPlan.getTakeoffTimePlannedHourMin()); @@ -126,7 +147,7 @@ namespace BlackGui this->ui->le_EstimatedTimeEnroute->setText(flightPlan.getEnrouteTimeHourMin()); this->ui->le_CruiseTrueAirspeed->setText(flightPlan.getCruiseTrueAirspeed().valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CSpeedUnit::kts(), 0)); - CAltitude cruiseAlt = flightPlan.getCruiseAltitude(); + const CAltitude cruiseAlt = flightPlan.getCruiseAltitude(); if (cruiseAlt.isFlightLevel()) { this->ui->le_CrusingAltitude->setText(cruiseAlt.toQString()); @@ -244,7 +265,7 @@ namespace BlackGui if (v.isEmpty() || v.endsWith(defaultIcao(), Qt::CaseInsensitive)) { messages.push_back(CLogMessage().validationWarning("Missing %1") << this->ui->lbl_AlternateAirport->text()); - flightPlan.setAlternateAirportIcao(defaultIcao()); + flightPlan.setAlternateAirportIcao(QString("")); } else { @@ -255,7 +276,7 @@ namespace BlackGui if (v.isEmpty() || v.endsWith(defaultIcao(), Qt::CaseInsensitive)) { messages.push_back(CLogMessage().validationWarning("Missing %1") << this->ui->lbl_DestinationAirport->text()); - flightPlan.setDestinationAirportIcao(defaultIcao()); + flightPlan.setDestinationAirportIcao(QString("")); } else { @@ -333,14 +354,79 @@ namespace BlackGui this->ui->le_CruiseTrueAirspeed->setText("100 kts"); this->ui->pte_Remarks->clear(); this->ui->pte_Route->clear(); - this->ui->le_AlternateAirport->setText(defaultIcao()); - this->ui->le_DestinationAirport->setText(defaultIcao()); - this->ui->le_OriginAirport->setText(defaultIcao()); + this->ui->le_AlternateAirport->clear(); + this->ui->le_DestinationAirport->clear(); + this->ui->le_OriginAirport->clear(); this->ui->le_FuelOnBoard->setText(defaultTime()); this->ui->le_EstimatedTimeEnroute->setText(defaultTime()); this->ui->le_TakeOffTimePlanned->setText(QDateTime::currentDateTimeUtc().addSecs(30 * 60).toString("hh:mm")); } + void CFlightPlanComponent::ps_loadFromDisk() + { + CStatusMessage m; + const QString fileName = QFileDialog::getOpenFileName(nullptr, + tr("Load flight plan"), getDefaultFilename(true), + tr("swift (*.json *.txt)")); + do + { + if (fileName.isEmpty()) + { + m = CStatusMessage(this, CStatusMessage::SeverityDebug, "Load canceled", true); + break; + } + + const QString json(CFileUtils::readFileToString(fileName)); + if (json.isEmpty()) + { + m = CStatusMessage(this, CStatusMessage::SeverityWarning, "Reading " + fileName + " yields no data", true); + break; + } + + CFlightPlan fp; + fp.convertFromJson(json); + this->fillWithFlightPlanData(fp); + } + while (false); + if (m.isFailure()) + { + CLogMessage::preformatted(m); + } + } + + void CFlightPlanComponent::ps_saveToDisk() + { + CStatusMessage m; + const QString fileName = QFileDialog::getSaveFileName(nullptr, + tr("Save flight plan"), getDefaultFilename(false), + tr("swift (*.json *.txt)")); + do + { + if (fileName.isEmpty()) + { + m = CStatusMessage(this, CStatusMessage::SeverityDebug, "Save canceled", true); + break; + } + CFlightPlan fp; + this->validateAndInitializeFlightPlan(fp); + const QString json(fp.toJsonString()); + bool ok = CFileUtils::writeStringToFile(json, fileName); + if (ok) + { + m = CStatusMessage(this, CStatusMessage::SeverityInfo, "Written " + fileName, true); + } + else + { + m = CStatusMessage(this, CStatusMessage::SeverityError, "Writing " + fileName + " failed", true); + } + } + while (false); + if (m.isFailure()) + { + CLogMessage::preformatted(m); + } + } + void CFlightPlanComponent::ps_setSelcalInOwnAircraft() { if (!sGui->getIContextOwnAircraft()) return; @@ -438,11 +524,46 @@ namespace BlackGui this->setCurrentWidget(this->ui->tb_RemarksGenerator); } + void CFlightPlanComponent::ps_swiftDataRead() + { + this->initCompleters(); + } + CIdentifier CFlightPlanComponent::flightPlanIdentifier() { if (m_identifier.getName().isEmpty()) { m_identifier = CIdentifier(QStringLiteral("FLIGHTPLANCOMPONENT")); } return m_identifier; } + void CFlightPlanComponent::initCompleters() + { + if (!sGui || !sGui->getWebDataServices()) { return; } + QStringList aircraft = sGui->getWebDataServices()->getAircraftIcaoCodes().allIcaoCodes(); + ui->le_AircraftType->setCompleter(new QCompleter(aircraft, this)); + } + + QString CFlightPlanComponent::getDefaultFilename(bool load) + { + // some logic to find a useful default name + QString dir = CBuildConfig::getDocumentationDirectory(); + + if (load) + { + return CFileUtils::appendFilePaths(dir, CFileUtils::jsonWildcardAppendix()); + } + + // Save file path + QString name("Flight plan"); + if (!ui->le_DestinationAirport->text().isEmpty() && !ui->le_OriginAirport->text().isEmpty()) + { + name.append(" ").append(ui->le_OriginAirport->text()).append("-").append(ui->le_DestinationAirport->text()); + } + + if (!name.endsWith(CFileUtils::jsonAppendix(), Qt::CaseInsensitive)) + { + name += CFileUtils::jsonAppendix(); + } + return CFileUtils::appendFilePaths(dir, name); + } } // namespace } // namespace diff --git a/src/blackgui/components/flightplancomponent.h b/src/blackgui/components/flightplancomponent.h index db0d71c00..9d2e1f63b 100644 --- a/src/blackgui/components/flightplancomponent.h +++ b/src/blackgui/components/flightplancomponent.h @@ -22,6 +22,7 @@ #include #include #include +#include class QWidget; @@ -32,10 +33,8 @@ namespace BlackGui { namespace Components { - //! Flight plan widget - class BLACKGUI_EXPORT CFlightPlanComponent : - public QTabWidget + class BLACKGUI_EXPORT CFlightPlanComponent : public QTabWidget { Q_OBJECT @@ -80,6 +79,11 @@ namespace BlackGui //! Identifier BlackMisc::CIdentifier flightPlanIdentifier(); + //! Set completers + void initCompleters(); + + QString getDefaultFilename(bool load); + private slots: //! Call \sa ps_buildRemarksString from combo box signal void ps_currentTextChangedToBuildRemarks(const QString &text) { this->ps_buildRemarksString(); Q_UNUSED(text); } @@ -90,6 +94,12 @@ namespace BlackGui //! Reset Flightplan void ps_resetFlightPlan(); + //! Load from disk + void ps_loadFromDisk(); + + //! Save to disk + void ps_saveToDisk(); + //! Set SELCAL in own aircrafr void ps_setSelcalInOwnAircraft(); @@ -108,7 +118,9 @@ namespace BlackGui //! Show generator tab page void ps_currentTabGenerator(); + //! GUI init complete + void ps_swiftDataRead(); }; - } -} + } // ns +} // ns #endif // guard diff --git a/src/blackgui/components/flightplancomponent.ui b/src/blackgui/components/flightplancomponent.ui index 18b76bd1e..87850e720 100644 --- a/src/blackgui/components/flightplancomponent.ui +++ b/src/blackgui/components/flightplancomponent.ui @@ -6,16 +6,10 @@ 0 0 - 400 - 400 + 600 + 500 - - - 0 - 0 - - TabWidget @@ -69,9 +63,9 @@ 0 - -77 - 373 - 447 + 0 + 592 + 469 @@ -113,198 +107,17 @@ 6 - - - - 6. Departure time - - - true - - - - - - - Load plan - - - - - - - 4. True airspeed - - - true - - - - - - - Reset plan - - - - - - - 10. Estimated time enroute - - - true - - - - - - - - - 11. Remarks - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - QPushButton { - background-color: transparent; - border: none; - text-align: left; - text-decoration: underline; -} - - - Qt::ImhNone - - - Generator - - - - - - - - - true - - - - - - - 13. Alternate airport - - - true - - - - - - - Send plan - - - - - - - 40 - - - - - - - >AAAA + + + + Save to disk - ICAO + Save - - - - - - - - - - - - - - - 40 - - - true - - - - - - - 1. Type - - - - - - - 99:99 - - - 00:00 - - - 5 - - - - - - - - 0 - 0 - - - - - 16777215 - 75 - - - - - - - - 8. Route - - - - - - - - - - >AAAA - - - ICAO - - - 4 + + + :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png @@ -315,13 +128,16 @@ - - - - 0 kts + + + + >AAAA - 40 + 4 + + + ICAO, e.g. EDDF @@ -335,6 +151,29 @@ + + + + 40 + + + e.g. 100 kts + + + + + + + 2. Callsign + + + false + + + true + + + @@ -392,16 +231,6 @@ - - - - 5. Departure airport - - - true - - - @@ -409,13 +238,10 @@ - - + + - 2. Callsign - - - false + 5. Departure airport true @@ -432,16 +258,6 @@ - - - - 7. Cruising altitude - - - true - - - @@ -450,6 +266,9 @@ 00:00 + + hh:mm e.g. 02:30 + @@ -459,20 +278,10 @@ - - - - >AAAA - + + - ICAO - - - - - - - 9.Destination airport + 7. Cruising altitude true @@ -498,16 +307,33 @@ - - - - 99:99 - + + - 00:00 + 9.Destination airport - - 5 + + true + + + + + + + 6. Departure time + + + true + + + + + + + 10. Estimated time enroute + + + true @@ -527,6 +353,226 @@ + + + + 99:99 + + + 00:00 + + + 5 + + + hh:mm e.g. 02:30 + + + + + + + >AAAA + + + ICAO, e.g. EDDF + + + + + + + Reset + + + + + + + Load flight plan from network + + + Load + + + + :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png + + + + + + + 4. True airspeed + + + true + + + + + + + + + 11. Remarks + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + QPushButton { + background-color: transparent; + border: none; + text-align: left; + text-decoration: underline; +} + + + Qt::ImhNone + + + Generator + + + + + + + + + true + + + + + + + + + + 13. Alternate airport + + + true + + + + + + + 40 + + + e.g. FL70 + + + + + + + >AAAA + + + ICAO, e.g. EDDF + + + + + + + 1. Type + + + + + + + 40 + + + true + + + e.g. DLH1331 + + + + + + + Send flight plan to network + + + Send + + + + :/diagona/icons/diagona/icons/network-cloud.png:/diagona/icons/diagona/icons/network-cloud.png + + + + + + + 8. Route + + + + + + + 99:99 + + + 00:00 + + + 5 + + + + + + + + 0 + 0 + + + + + 16777215 + 75 + + + + + + + + ICAO, e.g. A321 + + + + + + + Load from disk + + + Load + + + + :/pastel/icons/pastel/16/disk.png:/pastel/icons/pastel/16/disk.png + + + @@ -571,8 +617,8 @@ 0 0 - 302 - 468 + 578 + 472 @@ -985,6 +1031,8 @@ cb_NavigationEquipment cb_NoSidsStarts - + + + diff --git a/src/blackmisc/aviation/flightplan.cpp b/src/blackmisc/aviation/flightplan.cpp index 3d2419553..967a394ba 100644 --- a/src/blackmisc/aviation/flightplan.cpp +++ b/src/blackmisc/aviation/flightplan.cpp @@ -15,7 +15,6 @@ namespace BlackMisc { namespace Aviation { - QString CFlightPlan::convertToQString(bool i18n) const { QString s; @@ -45,6 +44,5 @@ namespace BlackMisc { return BlackMisc::CIconList::iconByIndex(CIcons::StandardIconAppFlightPlan16); } - } // namespace } // namespace diff --git a/src/blackmisc/blackmisc.qrc b/src/blackmisc/blackmisc.qrc index 3b911b269..e16e941b4 100644 --- a/src/blackmisc/blackmisc.qrc +++ b/src/blackmisc/blackmisc.qrc @@ -372,6 +372,19 @@ icons/diagona/icons/table-insert.png icons/diagona/icons/table-insert-column.png icons/diagona/icons/table-insert-row.png + icons/diagona/icons/network.png + icons/diagona/icons/network-wireless.png + icons/diagona/icons/network-status.png + icons/diagona/icons/network-status-offline.png + icons/diagona/icons/network-status-busy.png + icons/diagona/icons/network-status-away.png + icons/diagona/icons/network-ip.png + icons/diagona/icons/network-ip-local.png + icons/diagona/icons/network-hub.png + icons/diagona/icons/network-firewall.png + icons/diagona/icons/network-ethernet.png + icons/diagona/icons/network-clouds.png + icons/diagona/icons/network-cloud.png icons/own/app.jpg