diff --git a/src/gui/components/flightplancomponent.cpp b/src/gui/components/flightplancomponent.cpp index 670929d55..5f703e803 100644 --- a/src/gui/components/flightplancomponent.cpp +++ b/src/gui/components/flightplancomponent.cpp @@ -556,9 +556,10 @@ namespace swift::gui::components void CFlightPlanComponent::loadFromDisk() { CStatusMessageList msgs; - const QString fileName = QFileDialog::getOpenFileName( - this, tr("Load flight plan"), this->getDefaultFilename(true), - "Flight plans (*.json *.sfp *.xml);;swift (*.json *.txt);;SimBrief (*.xml);;SB4 (*.sfp)"); + const QString fileName = + QFileDialog::getOpenFileName(this, tr("Load flight plan"), this->getDefaultFilename(true), + "Flight plans (*.json *.sfp *.vfp *.xml);;swift (*.json *.txt);;SimBrief " + "(*.xml);;vPilot (*.vfp);;SB4 (*.sfp)"); if (fileName.isEmpty()) { return; } CFlightPlan fp = CFlightPlan::loadFromMultipleFormats(fileName, &msgs); if (!fp.hasCallsign()) { fp.setCallsign(ui->le_Callsign->text()); } // set callsign if it wasn't set diff --git a/src/misc/aviation/flightplan.cpp b/src/misc/aviation/flightplan.cpp index 35ee87d4f..e4f56504f 100644 --- a/src/misc/aviation/flightplan.cpp +++ b/src/misc/aviation/flightplan.cpp @@ -322,6 +322,57 @@ namespace swift::misc::aviation return s; } + CFlightPlan CFlightPlan::fromVPilotFormat(const QString &vPilotData) + { + if (vPilotData.isEmpty()) { return CFlightPlan(); } + QDomDocument doc; + doc.setContent(vPilotData); + const QDomElement fpDom = doc.firstChildElement(); + const QString type = fpDom.attribute("FlightType"); + + CFlightPlan fp; + fp.setFlightRule(CFlightPlan::stringToFlightRules(type)); + + const int airspeedKts = fpDom.attribute("CruiseSpeed").toInt(); + const CSpeed airspeed(airspeedKts, CSpeedUnit::kts()); + fp.setCruiseTrueAirspeed(airspeed); + + fp.setOriginAirportIcao(fpDom.attribute("DepartureAirport")); + fp.setDestinationAirportIcao(fpDom.attribute("DestinationAirport")); + fp.setAlternateAirportIcao(fpDom.attribute("AlternateAirport")); + fp.setRemarks(fpDom.attribute("Remarks")); + fp.setRoute(fpDom.attribute("Route")); + + const QString voice = fpDom.attribute("VoiceType"); + fp.setVoiceCapabilities(voice); + + // Ignoring equipment prefix, suffix and IsHeavy flag + + const int fuelMins = fpDom.attribute("FuelMinutes").toInt() + 60 * fpDom.attribute("FuelHours").toInt(); + const CTime fuelTime(fuelMins, CTimeUnit::min()); + + const int enrouteMins = + fpDom.attribute("EnrouteMinutes").toInt() + 60 * fpDom.attribute("EnrouteHours").toInt(); + const CTime enrouteTime(enrouteMins, CTimeUnit::min()); + + const QString altStr = fpDom.attribute("CruiseAltitude"); + CAltitude alt(altStr.length() < 4 ? "FL" + altStr : altStr + "ft"); + alt.toFlightLevel(); + + fp.setCruiseAltitude(alt); + fp.setFuelTime(fuelTime); + fp.setEnrouteTime(enrouteTime); + + const QString departureTime = fpDom.attribute("DepartureTime"); + if (departureTime.length() == 4) + { + CTime depTime; + if (depTime.parseFromString_hhmm(departureTime)) { fp.setTakeoffTimePlanned(depTime.toQDateTime()); } + } + + return fp; + } + CFlightPlan CFlightPlan::fromSB4Format(const QString &sbData) { if (sbData.isEmpty()) { return CFlightPlan(); } @@ -488,6 +539,10 @@ namespace swift::misc::aviation } if (data.contains("[SBFlightPlan]", Qt::CaseInsensitive)) { return CFlightPlan::fromSB4Format(data); } + if (data.contains("