mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
refs #219, load flight plan
* fixed issue with parsing, only default locale is used. Now user's local possible * allow to load FP for other callsigns as well (voice capabilities) * Improved handling of CTime, inclusive bug fixes and time formatting * Max. lengths for FP fields as const value (so we can change it if required) * Load FP from GUI component * Samples for PQ classes * Adjusted depending classes (e.g. client)
This commit is contained in:
@@ -15,9 +15,11 @@ namespace BlackMiscTest
|
||||
*/
|
||||
int CSamplesPhysicalQuantities::samples()
|
||||
{
|
||||
QVariant parsedPq = CPqString::parseToVariant("100 km/h");
|
||||
parsedPq = CPqString::parseToVariant("-33ft");
|
||||
parsedPq = CPqString::parseToVariant("666");
|
||||
CSpeed parsedPq1 = CPqString::parseToVariant("100 km/h").value<CSpeed>();
|
||||
CLength parsedPq2 = CPqString::parseToVariant("-33ft").value<CLength>();
|
||||
QVariant parsedPq3 = CPqString::parseToVariant("666");
|
||||
qDebug() << "parsed" << parsedPq1 << parsedPq2 << parsedPq3;
|
||||
|
||||
CSpeed speedParsed = CPqString::parse<CSpeed>("111.33ft/s");
|
||||
CFrequency frequencyParsed = CPqString::parse<CFrequency>("122.8MHz");
|
||||
qDebug() << "parsed" << speedParsed << speedParsed.valueRoundedWithUnit(2, true) << frequencyParsed << frequencyParsed.valueRoundedWithUnit(2, true);
|
||||
|
||||
@@ -252,26 +252,29 @@ void Client::sendFlightPlanCmd(QTextStream &args)
|
||||
QString flightRulesString;
|
||||
QString route;
|
||||
args >> equipmentIcao >> originAirportIcao >> destinationAirportIcao >> alternateAirportIcao >> takeoffTimePlanned >> takeoffTimeActual
|
||||
>> enrouteTime >> fuelTime >> cruiseAltitude >> cruiseTrueAirspeed >> flightRulesString >> route;
|
||||
>> enrouteTime >> fuelTime >> cruiseAltitude >> cruiseTrueAirspeed >> flightRulesString >> route;
|
||||
|
||||
BlackMisc::Aviation::CFlightPlan::FlightRules flightRules;
|
||||
if (flightRulesString == "IFR") { flightRules = BlackMisc::Aviation::CFlightPlan::IFR; }
|
||||
else if (flightRulesString == "SVFR") { flightRules = BlackMisc::Aviation::CFlightPlan::SVFR; }
|
||||
else { flightRules = BlackMisc::Aviation::CFlightPlan::VFR; }
|
||||
|
||||
BlackMisc::Aviation::CFlightPlan fp(equipmentIcao, originAirportIcao, destinationAirportIcao, alternateAirportIcao,
|
||||
QDateTime::fromString(takeoffTimePlanned, "hhmm"), QDateTime::fromString(takeoffTimeActual, "hhmm"),
|
||||
BlackMisc::PhysicalQuantities::CTime(enrouteTime, BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()),
|
||||
BlackMisc::PhysicalQuantities::CTime(fuelTime, BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()),
|
||||
BlackMisc::Aviation::CAltitude(cruiseAltitude, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()),
|
||||
BlackMisc::PhysicalQuantities::CSpeed(cruiseTrueAirspeed, BlackMisc::PhysicalQuantities::CSpeedUnit::kts()),
|
||||
flightRules, route, args.readAll());
|
||||
BlackMisc::Aviation::CFlightPlan
|
||||
fp(equipmentIcao, originAirportIcao, destinationAirportIcao, alternateAirportIcao,
|
||||
QDateTime::fromString(takeoffTimePlanned, "hhmm"), QDateTime::fromString(takeoffTimeActual, "hhmm"),
|
||||
BlackMisc::PhysicalQuantities::CTime(enrouteTime, BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()),
|
||||
BlackMisc::PhysicalQuantities::CTime(fuelTime, BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()),
|
||||
BlackMisc::Aviation::CAltitude(cruiseAltitude, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()),
|
||||
BlackMisc::PhysicalQuantities::CSpeed(cruiseTrueAirspeed, BlackMisc::PhysicalQuantities::CSpeedUnit::kts()),
|
||||
flightRules, route, args.readAll());
|
||||
emit sendFlightPlan(fp);
|
||||
}
|
||||
|
||||
void Client::sendFlightPlanQueryCmd(QTextStream &)
|
||||
void Client::sendFlightPlanQueryCmd(QTextStream &args)
|
||||
{
|
||||
emit sendFlightPlanQuery();
|
||||
QString callsign;
|
||||
args >> callsign;
|
||||
emit sendFlightPlanQuery(callsign);
|
||||
}
|
||||
|
||||
void Client::sendServerQueryCmd(QTextStream &args)
|
||||
@@ -331,13 +334,13 @@ void Client::setOwnAircraftCmd(QTextStream &args)
|
||||
QString xpdrMode;
|
||||
args >> lat >> lon >> alt >> hdg >> pitch >> bank >> gs >> com1 >> com2 >> xpdrCode >> xpdrMode;
|
||||
BlackMisc::Aviation::CAircraft aircraft("", BlackMisc::Network::CUser(), BlackMisc::Aviation::CAircraftSituation(
|
||||
BlackMisc::Geo::CCoordinateGeodetic(lat, lon, 0),
|
||||
BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()),
|
||||
BlackMisc::Aviation::CHeading(hdg, BlackMisc::Aviation::CHeading::True, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(pitch, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(bank, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CSpeed(gs, BlackMisc::PhysicalQuantities::CSpeedUnit::kts())
|
||||
));
|
||||
BlackMisc::Geo::CCoordinateGeodetic(lat, lon, 0),
|
||||
BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()),
|
||||
BlackMisc::Aviation::CHeading(hdg, BlackMisc::Aviation::CHeading::True, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(pitch, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(bank, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CSpeed(gs, BlackMisc::PhysicalQuantities::CSpeedUnit::kts())
|
||||
));
|
||||
aircraft.setCom1System(BlackMisc::Aviation::CComSystem("COM1", BlackMisc::PhysicalQuantities::CFrequency(com1, BlackMisc::PhysicalQuantities::CFrequencyUnit::MHz())));
|
||||
aircraft.setCom2System(BlackMisc::Aviation::CComSystem("COM2", BlackMisc::PhysicalQuantities::CFrequency(com2, BlackMisc::PhysicalQuantities::CFrequencyUnit::MHz())));
|
||||
aircraft.setTransponder(BlackMisc::Aviation::CTransponder("Transponder", xpdrCode, xpdrMode));
|
||||
@@ -351,7 +354,7 @@ void Client::setOwnAircraftPositionCmd(QTextStream &args)
|
||||
double alt;
|
||||
args >> lat >> lon >> alt;
|
||||
emit setOwnAircraftPosition(BlackMisc::Geo::CCoordinateGeodetic(lat, lon, 0),
|
||||
BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()));
|
||||
BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()));
|
||||
}
|
||||
|
||||
void Client::setOwnAircraftSituationCmd(QTextStream &args)
|
||||
@@ -365,13 +368,13 @@ void Client::setOwnAircraftSituationCmd(QTextStream &args)
|
||||
double gs;
|
||||
args >> lat >> lon >> alt >> hdg >> pitch >> bank >> gs;
|
||||
emit setOwnAircraftSituation(BlackMisc::Aviation::CAircraftSituation(
|
||||
BlackMisc::Geo::CCoordinateGeodetic(lat, lon, 0),
|
||||
BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()),
|
||||
BlackMisc::Aviation::CHeading(hdg, BlackMisc::Aviation::CHeading::True, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(pitch, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(bank, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CSpeed(gs, BlackMisc::PhysicalQuantities::CSpeedUnit::kts())
|
||||
));
|
||||
BlackMisc::Geo::CCoordinateGeodetic(lat, lon, 0),
|
||||
BlackMisc::Aviation::CAltitude(alt, BlackMisc::Aviation::CAltitude::MeanSeaLevel, BlackMisc::PhysicalQuantities::CLengthUnit::ft()),
|
||||
BlackMisc::Aviation::CHeading(hdg, BlackMisc::Aviation::CHeading::True, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(pitch, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CAngle(bank, BlackMisc::PhysicalQuantities::CAngleUnit::deg()),
|
||||
BlackMisc::PhysicalQuantities::CSpeed(gs, BlackMisc::PhysicalQuantities::CSpeedUnit::kts())
|
||||
));
|
||||
}
|
||||
|
||||
void Client::setOwnAircraftAvionicsCmd(QTextStream &args)
|
||||
@@ -513,23 +516,24 @@ void Client::metarReplyReceived(const QString &data)
|
||||
std::cout << "METAR " << data.toStdString() << std::endl;
|
||||
}
|
||||
|
||||
void Client::flightPlanReplyReceived(const BlackMisc::Aviation::CFlightPlan &flightPlan)
|
||||
void Client::flightPlanReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CFlightPlan &flightPlan)
|
||||
{
|
||||
std::string rules;
|
||||
switch (flightPlan.getFlightRules())
|
||||
{
|
||||
default:
|
||||
case BlackMisc::Aviation::CFlightPlan::IFR: rules = "IFR"; break;
|
||||
case BlackMisc::Aviation::CFlightPlan::VFR: rules = "VFR"; break;
|
||||
case BlackMisc::Aviation::CFlightPlan::SVFR: rules = "SVFR"; break;
|
||||
default:
|
||||
case BlackMisc::Aviation::CFlightPlan::IFR: rules = "IFR"; break;
|
||||
case BlackMisc::Aviation::CFlightPlan::VFR: rules = "VFR"; break;
|
||||
case BlackMisc::Aviation::CFlightPlan::SVFR: rules = "SVFR"; break;
|
||||
}
|
||||
|
||||
std::cout << "FLIGHTPLAN " << flightPlan.getEquipmentIcao().toStdString() << " " << flightPlan.getOriginAirportIcao() << " "
|
||||
<< flightPlan.getDestinationAirportIcao() << " " << flightPlan.getAlternateAirportIcao() << " "
|
||||
<< flightPlan.getTakeoffTimePlannedHourMin().toStdString() << " " << flightPlan.getTakeoffTimeActualHourMin().toStdString() << " "
|
||||
<< flightPlan.getEnrouteTime() << " " << flightPlan.getFuelTime() << " "
|
||||
<< flightPlan.getCruiseAltitude() << " " << flightPlan.getCruiseTrueAirspeed() << " " << rules << " "
|
||||
<< flightPlan.getRoute().toStdString() << " " << flightPlan.getRemarks().toStdString() << "\n";
|
||||
std::cout << "FLIGHTPLAN " << callsign
|
||||
<< flightPlan.getEquipmentIcao().toStdString() << " " << flightPlan.getOriginAirportIcao() << " "
|
||||
<< flightPlan.getDestinationAirportIcao() << " " << flightPlan.getAlternateAirportIcao() << " "
|
||||
<< flightPlan.getTakeoffTimePlannedHourMin().toStdString() << " " << flightPlan.getTakeoffTimeActualHourMin().toStdString() << " "
|
||||
<< flightPlan.getEnrouteTime() << " " << flightPlan.getFuelTime() << " "
|
||||
<< flightPlan.getCruiseAltitude() << " " << flightPlan.getCruiseTrueAirspeed() << " " << rules << " "
|
||||
<< flightPlan.getRoute().toStdString() << " " << flightPlan.getRemarks().toStdString() << "\n";
|
||||
}
|
||||
|
||||
void Client::pilotDisconnected(const BlackMisc::Aviation::CCallsign &callsign)
|
||||
@@ -565,5 +569,5 @@ void Client::customPacketReceived(const BlackMisc::Aviation::CCallsign &callsign
|
||||
void Client::statusMessage(const BlackMisc::CStatusMessage &message)
|
||||
{
|
||||
std::cout << "STATUS " << message.getSeverityAsString().toStdString() << " " << message.getTypeAsString().toStdString() << " "
|
||||
<< message.getMessage().toStdString() << "\n";
|
||||
<< message.getMessage().toStdString() << "\n";
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ signals: //to send to INetwork
|
||||
void sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void sendFlightPlan(const BlackMisc::Aviation::CFlightPlan &fp);
|
||||
void sendFlightPlanQuery();
|
||||
void sendFlightPlanQuery(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void sendRealNameQuery(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void sendIcaoCodesQuery(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
@@ -103,7 +103,7 @@ public slots: //to receive from INetwork
|
||||
void capabilitiesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, quint32 flags);
|
||||
void kicked(const QString &msg);
|
||||
void metarReplyReceived(const QString &data);
|
||||
void flightPlanReplyReceived(const BlackMisc::Aviation::CFlightPlan &flightPlan);
|
||||
void flightPlanReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CFlightPlan &flightPlan);
|
||||
void pilotDisconnected(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void icaoCodesReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftIcao &icaoData);
|
||||
void pongReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CTime &elapsedTime);
|
||||
|
||||
@@ -251,7 +251,7 @@ namespace BlackCore
|
||||
* \pre Network must be connected when calling this function.
|
||||
* \sa flightPlanReplyReceived
|
||||
*/
|
||||
virtual void sendFlightPlanQuery() = 0;
|
||||
virtual void sendFlightPlanQuery(const BlackMisc::Aviation::CCallsign &callsign) = 0;
|
||||
|
||||
//! @}
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -320,7 +320,7 @@ namespace BlackCore
|
||||
* \pre Network must be connected when calling this function.
|
||||
* \sa metarReplyReceived
|
||||
*/
|
||||
virtual void sendMetarQuery(const QString &airportICAO) = 0;
|
||||
virtual void sendMetarQuery(const BlackMisc::Aviation::CAirportIcao &airportIcao) = 0;
|
||||
|
||||
/*!
|
||||
* Send a message querying the weather data for the airport with a specific ICAO code.
|
||||
@@ -329,7 +329,7 @@ namespace BlackCore
|
||||
* \sa windDataReplyReceived
|
||||
* \sa cloudDataReplyReceived
|
||||
*/
|
||||
virtual void sendWeatherDataQuery(const QString &airportICAO) = 0;
|
||||
virtual void sendWeatherDataQuery(const BlackMisc::Aviation::CAirportIcao &airportIcao) = 0;
|
||||
|
||||
signals:
|
||||
//! @}
|
||||
@@ -377,7 +377,7 @@ namespace BlackCore
|
||||
* We received a reply to one of our flight plan queries, containing our up-to-date flight plan.
|
||||
* \sa sendFlightPlanQuery
|
||||
*/
|
||||
void flightPlanReplyReceived(const BlackMisc::Aviation::CFlightPlan &flightPlan);
|
||||
void flightPlanReplyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CFlightPlan &flightPlan);
|
||||
|
||||
//! @}
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -390,7 +390,7 @@ namespace BlackCore
|
||||
void CNetworkVatlib::presetIcaoCodes(const BlackMisc::Aviation::CAircraftIcao &icao)
|
||||
{
|
||||
Q_ASSERT_X(isDisconnected(), "CNetworkVatlib", "Can't change ICAO codes while still connected");
|
||||
m_icaoCodes = icao;
|
||||
m_icaoCode = icao;
|
||||
}
|
||||
|
||||
void CNetworkVatlib::presetLoginMode(LoginMode mode)
|
||||
@@ -617,20 +617,28 @@ namespace BlackCore
|
||||
{
|
||||
Cvatlib_Network::FlightPlan vatlibFP;
|
||||
QString route = QString(flightPlan.getRoute()).replace(" ", ".");
|
||||
QString remarks = QString(flightPlan.getRemarks()).replace(":", ";");
|
||||
remarks.truncate(100);
|
||||
QString remarks = QString(flightPlan.getRemarks()).replace(":", ";").trimmed();
|
||||
QString alt = flightPlan.getCruiseAltitude().isFlightLevel() ?
|
||||
flightPlan.getCruiseAltitude().toQString() :
|
||||
flightPlan.getCruiseAltitude().valueRoundedWithUnit(0);
|
||||
alt = alt.remove('.').remove(','); // remove any separators
|
||||
|
||||
QByteArray acTypeTemp, altAptTemp, cruiseAltTemp, depAptTemp, destAptTemp, routeTemp, remarksTemp;
|
||||
vatlibFP.acType = acTypeTemp = toFSD(flightPlan.getEquipmentIcao());
|
||||
vatlibFP.altApt = altAptTemp = toFSD(flightPlan.getAlternateAirportIcao().asString());
|
||||
vatlibFP.cruiseAlt = cruiseAltTemp = toFSD(QByteArray::number(flightPlan.getCruiseAltitude().value(CLengthUnit::ft()), 'f', 0));
|
||||
vatlibFP.cruiseAlt = cruiseAltTemp = toFSD(alt);
|
||||
vatlibFP.depApt = depAptTemp = toFSD(flightPlan.getOriginAirportIcao().asString());
|
||||
vatlibFP.depTimeActual = flightPlan.getTakeoffTimeActual().toUTC().toString("hhmm").toInt();
|
||||
vatlibFP.depTimePlanned = flightPlan.getTakeoffTimePlanned().toUTC().toString("hhmm").toInt();
|
||||
vatlibFP.destApt = destAptTemp = toFSD(flightPlan.getDestinationAirportIcao().asString());
|
||||
vatlibFP.enrouteHrs = flightPlan.getEnrouteTime().valueRounded(CTimeUnit::h(), 0);
|
||||
vatlibFP.enrouteMins = int(flightPlan.getEnrouteTime().valueRounded(CTimeUnit::hrmin(), 0)) % 60;
|
||||
vatlibFP.fuelHrs = flightPlan.getFuelTime().valueRounded(CTimeUnit::h(), 0);
|
||||
vatlibFP.fuelMins = int(flightPlan.getFuelTime().valueRounded(CTimeUnit::hrmin(), 0)) % 60;
|
||||
|
||||
QList<int> timeParts = flightPlan.getEnrouteTime().getHrsMinSecParts();
|
||||
vatlibFP.enrouteHrs = timeParts[CTime::Hours];
|
||||
vatlibFP.enrouteMins = timeParts[CTime::Minutes];
|
||||
|
||||
timeParts = flightPlan.getFuelTime().getHrsMinSecParts();
|
||||
vatlibFP.fuelHrs = timeParts[CTime::Hours];
|
||||
vatlibFP.fuelMins = timeParts[CTime::Minutes];
|
||||
vatlibFP.remarks = remarksTemp = toFSD(remarks);
|
||||
vatlibFP.route = routeTemp = toFSD(route);
|
||||
vatlibFP.trueCruiseSpeed = flightPlan.getCruiseTrueAirspeed().valueRounded(CSpeedUnit::kts());
|
||||
@@ -646,13 +654,13 @@ namespace BlackCore
|
||||
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||
}
|
||||
|
||||
void CNetworkVatlib::sendFlightPlanQuery()
|
||||
void CNetworkVatlib::sendFlightPlanQuery(const BlackMisc::Aviation::CCallsign &callsign)
|
||||
{
|
||||
Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected");
|
||||
|
||||
try
|
||||
{
|
||||
m_net->SendInfoQuery(Cvatlib_Network::infoQuery_FP, toFSD(m_callsign));
|
||||
m_net->SendInfoQuery(Cvatlib_Network::infoQuery_FP, toFSD(callsign));
|
||||
}
|
||||
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||
}
|
||||
@@ -713,21 +721,21 @@ namespace BlackCore
|
||||
{
|
||||
try
|
||||
{
|
||||
const QByteArray acTypeICAObytes = toFSD(m_icaoCodes.getAircraftDesignator());
|
||||
const QByteArray airlineICAObytes = toFSD(m_icaoCodes.getAirlineDesignator());
|
||||
const QByteArray liverybytes = toFSD(m_icaoCodes.getLivery());
|
||||
const QByteArray acTypeICAObytes = toFSD(m_icaoCode.getAircraftDesignator());
|
||||
const QByteArray airlineICAObytes = toFSD(m_icaoCode.getAirlineDesignator());
|
||||
const QByteArray liverybytes = toFSD(m_icaoCode.getLivery());
|
||||
std::vector<const char *> keysValues;
|
||||
if (!m_icaoCodes.getAircraftDesignator().isEmpty())
|
||||
if (!m_icaoCode.getAircraftDesignator().isEmpty())
|
||||
{
|
||||
keysValues.push_back(m_net->acinfo_Equipment);
|
||||
keysValues.push_back(acTypeICAObytes);
|
||||
}
|
||||
if (m_icaoCodes.hasAirlineDesignator())
|
||||
if (m_icaoCode.hasAirlineDesignator())
|
||||
{
|
||||
keysValues.push_back(m_net->acinfo_Airline);
|
||||
keysValues.push_back(airlineICAObytes);
|
||||
}
|
||||
if (m_icaoCodes.hasLivery())
|
||||
if (m_icaoCode.hasLivery())
|
||||
{
|
||||
keysValues.push_back(m_net->acinfo_Livery);
|
||||
keysValues.push_back(liverybytes);
|
||||
@@ -749,24 +757,24 @@ namespace BlackCore
|
||||
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||
}
|
||||
|
||||
void CNetworkVatlib::sendMetarQuery(const QString &airportICAO)
|
||||
void CNetworkVatlib::sendMetarQuery(const BlackMisc::Aviation::CAirportIcao &airportIcao)
|
||||
{
|
||||
Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected");
|
||||
|
||||
try
|
||||
{
|
||||
m_net->RequestMetar(toFSD(airportICAO));
|
||||
m_net->RequestMetar(toFSD(airportIcao.asString()));
|
||||
}
|
||||
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||
}
|
||||
|
||||
void CNetworkVatlib::sendWeatherDataQuery(const QString &airportICAO)
|
||||
void CNetworkVatlib::sendWeatherDataQuery(const BlackMisc::Aviation::CAirportIcao &airportIcao)
|
||||
{
|
||||
Q_ASSERT_X(isConnected(), "CNetworkVatlib", "Can't send to server when disconnected");
|
||||
|
||||
try
|
||||
{
|
||||
m_net->RequestWeatherData(toFSD(airportICAO));
|
||||
m_net->RequestWeatherData(toFSD(airportIcao.asString()));
|
||||
}
|
||||
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||
}
|
||||
@@ -998,11 +1006,6 @@ namespace BlackCore
|
||||
|
||||
void CNetworkVatlib::onFlightPlanReceived(Cvatlib_Network *, const char *callsign, Cvatlib_Network::FlightPlan fp, void *cbvar)
|
||||
{
|
||||
if (cbvar_cast(cbvar)->m_callsign != cbvar_cast(cbvar)->fromFSD(callsign))
|
||||
{
|
||||
return; // ignore other pilots' flightplans
|
||||
}
|
||||
|
||||
BlackMisc::Aviation::CFlightPlan::FlightRules rules = BlackMisc::Aviation::CFlightPlan::VFR;
|
||||
switch (fp.fpRules)
|
||||
{
|
||||
@@ -1013,20 +1016,25 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
auto cruiseAltString = cbvar_cast(cbvar)->fromFSD(fp.cruiseAlt);
|
||||
if (! cruiseAltString.contains(QRegExp("[A-Z][a-z]")))
|
||||
static const QRegExp withUnit("\\D+");
|
||||
if (!cruiseAltString.isEmpty() && withUnit.indexIn(cruiseAltString) < 0)
|
||||
{
|
||||
cruiseAltString += "ft";
|
||||
}
|
||||
BlackMisc::Aviation::CAltitude cruiseAlt;
|
||||
cruiseAlt.parseFromString(cruiseAltString);
|
||||
|
||||
|
||||
QString depTimePlanned = QString("0000").append(QString::number(fp.depTimePlanned)).right(4);
|
||||
QString depTimeActual = QString("0000").append(QString::number(fp.depTimeActual)).right(4);
|
||||
|
||||
BlackMisc::Aviation::CFlightPlan flightPlan(
|
||||
cbvar_cast(cbvar)->fromFSD(fp.acType),
|
||||
cbvar_cast(cbvar)->fromFSD(fp.depApt),
|
||||
cbvar_cast(cbvar)->fromFSD(fp.destApt),
|
||||
cbvar_cast(cbvar)->fromFSD(fp.altApt),
|
||||
QDateTime::fromString(QString::number(fp.depTimePlanned), "hhmm"),
|
||||
QDateTime::fromString(QString::number(fp.depTimeActual), "hhmm"),
|
||||
QDateTime::fromString(depTimePlanned, "hhmm"),
|
||||
QDateTime::fromString(depTimeActual, "hhmm"),
|
||||
BlackMisc::PhysicalQuantities::CTime(fp.enrouteHrs * 60 + fp.enrouteMins, BlackMisc::PhysicalQuantities::CTimeUnit::min()),
|
||||
BlackMisc::PhysicalQuantities::CTime(fp.fuelHrs * 60 + fp.fuelMins, BlackMisc::PhysicalQuantities::CTimeUnit::min()),
|
||||
cruiseAlt,
|
||||
@@ -1036,7 +1044,7 @@ namespace BlackCore
|
||||
cbvar_cast(cbvar)->fromFSD(fp.remarks)
|
||||
);
|
||||
|
||||
emit cbvar_cast(cbvar)->flightPlanReplyReceived(flightPlan);
|
||||
emit cbvar_cast(cbvar)->flightPlanReplyReceived(callsign, flightPlan);
|
||||
}
|
||||
|
||||
void CNetworkVatlib::onTemperatureDataReceived(Cvatlib_Network *, Cvatlib_Network::TempLayer /** layers **/ [4], INT /** pressure **/, void * /** cbvar **/)
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*!
|
||||
\file
|
||||
*/
|
||||
|
||||
#ifndef BLACKCORE_NETWORK_VATLIB_H
|
||||
#define BLACKCORE_NETWORK_VATLIB_H
|
||||
|
||||
@@ -64,7 +60,7 @@ namespace BlackCore
|
||||
virtual void sendAtcQuery(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
virtual void sendAtisQuery(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
virtual void sendFlightPlan(const BlackMisc::Aviation::CFlightPlan &flightPlan) override;
|
||||
virtual void sendFlightPlanQuery() override;
|
||||
virtual void sendFlightPlanQuery(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
|
||||
// Aircraft slots
|
||||
virtual void sendCapabilitiesQuery(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
@@ -79,14 +75,11 @@ namespace BlackCore
|
||||
const BlackMisc::Aviation::CTransponder &xpdr) override;
|
||||
|
||||
// Weather slots
|
||||
virtual void sendMetarQuery(const QString &airportICAO) override;
|
||||
virtual void sendWeatherDataQuery(const QString &airportICAO) override;
|
||||
virtual void sendMetarQuery(const BlackMisc::Aviation::CAirportIcao &airportIcao) override;
|
||||
virtual void sendWeatherDataQuery(const BlackMisc::Aviation::CAirportIcao &airportIcao) override;
|
||||
|
||||
// some helper methods
|
||||
|
||||
//!
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Create the data load for FSIPI(R) packages / FsInn
|
||||
* \details FSIPI(R) queries
|
||||
@@ -171,7 +164,7 @@ namespace BlackCore
|
||||
Cvatlib_Network::connStatus m_status;
|
||||
BlackMisc::Network::CServer m_server;
|
||||
BlackMisc::Aviation::CCallsign m_callsign;
|
||||
BlackMisc::Aviation::CAircraftIcao m_icaoCodes;
|
||||
BlackMisc::Aviation::CAircraftIcao m_icaoCode;
|
||||
BlackMisc::Aviation::CAircraft m_ownAircraft; // not using callsign, user, or icao parts of this member because they can't be changed when connected
|
||||
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CInformationMessage> m_atisParts;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
@@ -11,7 +12,7 @@ namespace BlackGui
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(this->ui->pb_Send, &QPushButton::pressed, this, &CFlightPlanComponent::sendFlightPlan);
|
||||
connect(this->ui->pb_Load, &QPushButton::pressed, this, &CFlightPlanComponent::loadFlightPlan);
|
||||
connect(this->ui->pb_Load, &QPushButton::pressed, this, &CFlightPlanComponent::loadFlightPlanFromNetwork);
|
||||
connect(this->ui->pb_Reset, &QPushButton::pressed, this, &CFlightPlanComponent::resetFlightPlan);
|
||||
connect(this->ui->pb_ValidateFlightPlan, &QPushButton::pressed, this, &CFlightPlanComponent::validateFlightPlan);
|
||||
|
||||
@@ -56,7 +57,7 @@ namespace BlackGui
|
||||
this->ui->le_PilotsName->setText(aircraftData.getPilot().getRealName());
|
||||
}
|
||||
|
||||
void CFlightPlanComponent::prefillWithFlightPlanData(const BlackMisc::Aviation::CFlightPlan &flightPlan)
|
||||
void CFlightPlanComponent::fillWithFlightPlanData(const BlackMisc::Aviation::CFlightPlan &flightPlan)
|
||||
{
|
||||
this->ui->le_AlternateAirport->setText(flightPlan.getAlternateAirportIcao().asString());
|
||||
this->ui->le_DestinationAirport->setText(flightPlan.getAlternateAirportIcao().asString());
|
||||
@@ -66,8 +67,13 @@ namespace BlackGui
|
||||
this->ui->le_TakeOffTimePlanned->setText(flightPlan.getTakeoffTimePlannedHourMin());
|
||||
this->ui->le_FuelOnBoard->setText(flightPlan.getFuelTimeHourMin());
|
||||
this->ui->le_EstimatedTimeEnroute->setText(flightPlan.getEnrouteTimeHourMin());
|
||||
this->ui->le_CrusingAltitude->setText(flightPlan.getCruiseAltitude().toQString());
|
||||
this->ui->le_CruiseTrueAirspeed->setText(flightPlan.getCruiseTrueAirspeed().valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CSpeedUnit::kts(), 0));
|
||||
|
||||
CAltitude cruiseAlt = flightPlan.getCruiseAltitude();
|
||||
if (cruiseAlt.isFlightLevel())
|
||||
this->ui->le_CrusingAltitude->setText(cruiseAlt.toQString());
|
||||
else
|
||||
this->ui->le_CrusingAltitude->setText(cruiseAlt.valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CLengthUnit::ft(), 0));
|
||||
}
|
||||
|
||||
CFlightPlan CFlightPlanComponent::getFlightPlan() const
|
||||
@@ -97,16 +103,26 @@ namespace BlackGui
|
||||
v = ui->pte_Route->toPlainText().trimmed();
|
||||
if (v.isEmpty())
|
||||
{
|
||||
QString m = QString("Missing %1").arg(this->ui->lbl_Route->text());
|
||||
QString m = QString("Missing flight plan route");
|
||||
messages.push_back(CStatusMessage::getValidationError(m));
|
||||
}
|
||||
else if (v.length() > CFlightPlan::MaxRouteLength)
|
||||
{
|
||||
QString m = QString("Flight plan route length exceeded (%1 chars max.)").arg(CFlightPlan::MaxRouteLength);
|
||||
messages.push_back(CStatusMessage::getValidationError(m));
|
||||
}
|
||||
else
|
||||
flightPlan.setRoute(v);
|
||||
|
||||
v = ui->pte_Remarks->toPlainText().trimmed();
|
||||
if (v.length() > 100)
|
||||
if (v.isEmpty())
|
||||
{
|
||||
QString m = QString("Length exceeded (100 chars max.) %1").arg(this->ui->lbl_Remarks->text());
|
||||
QString m = QString("No remarks, voice capabilities are mandatory");
|
||||
messages.push_back(CStatusMessage::getValidationError(m));
|
||||
}
|
||||
else if (v.length() > CFlightPlan::MaxRemarksLength)
|
||||
{
|
||||
QString m = QString("Flight plan remarks length exceeded (%1 chars max.)").arg(CFlightPlan::MaxRemarksLength);
|
||||
messages.push_back(CStatusMessage::getValidationError(m));
|
||||
}
|
||||
else
|
||||
@@ -139,8 +155,15 @@ namespace BlackGui
|
||||
else
|
||||
flightPlan.setTakeoffTimePlanned(v);
|
||||
|
||||
static const QRegExp withUnit("\\D+");
|
||||
v = ui->le_CrusingAltitude->text().trimmed();
|
||||
CAltitude cruisingAltitude(v);
|
||||
if (!v.isEmpty() && withUnit.indexIn(v) < 0)
|
||||
{
|
||||
v += "ft";
|
||||
this->ui->le_CrusingAltitude->setText(v);
|
||||
}
|
||||
|
||||
CAltitude cruisingAltitude(v, CPqString::SeparatorsLocale);
|
||||
if (v.isEmpty() || cruisingAltitude.isNull())
|
||||
{
|
||||
QString m = QString("Wrong %1").arg(this->ui->lbl_CrusingAltitude->text());
|
||||
@@ -171,7 +194,7 @@ namespace BlackGui
|
||||
|
||||
v = this->ui->le_CruiseTrueAirspeed->text();
|
||||
BlackMisc::PhysicalQuantities::CSpeed cruiseTAS;
|
||||
cruiseTAS.parseFromString(v);
|
||||
cruiseTAS.parseFromString(v, CPqString::SeparatorsLocale);
|
||||
if (cruiseTAS.isNull())
|
||||
{
|
||||
QString m = QString("Wrong TAS, %1").arg(this->ui->lbl_CruiseTrueAirspeed->text());
|
||||
@@ -204,14 +227,14 @@ namespace BlackGui
|
||||
CStatusMessage m;
|
||||
if (this->getIContextNetwork()->isConnected())
|
||||
{
|
||||
flightPlan.setWhenLastSent(QDateTime::currentDateTimeUtc());
|
||||
flightPlan.setWhenLastSentOrLoaded(QDateTime::currentDateTimeUtc());
|
||||
this->getIContextNetwork()->sendFlightPlan(flightPlan);
|
||||
this->ui->le_LastSent->setText(flightPlan.whenLastSent().toString());
|
||||
this->ui->le_LastSent->setText(flightPlan.whenLastSentOrLoaded().toString());
|
||||
m = CStatusMessage::getInfoMessage("Sent flight plan", CStatusMessage::TypeTrafficNetwork);
|
||||
}
|
||||
else
|
||||
{
|
||||
flightPlan.setWhenLastSent(QDateTime());
|
||||
flightPlan.setWhenLastSentOrLoaded(QDateTime()); // empty
|
||||
this->ui->le_LastSent->clear();
|
||||
m = CStatusMessage::getErrorMessage("No errors, but not connected, cannot send flight plan", CStatusMessage::TypeTrafficNetwork);
|
||||
}
|
||||
@@ -258,9 +281,30 @@ namespace BlackGui
|
||||
this->ui->le_TakeOffTimePlanned->setText(QDateTime::currentDateTimeUtc().addSecs(30 * 60).toString("hh:mm"));
|
||||
}
|
||||
|
||||
void CFlightPlanComponent::loadFlightPlan()
|
||||
void CFlightPlanComponent::loadFlightPlanFromNetwork()
|
||||
{
|
||||
if (!this->getIContextNetwork())
|
||||
{
|
||||
this->sendStatusMessage(CStatusMessage::getInfoMessage("Cannot load flight plan, network not available", CStatusMessage::TypeTrafficNetwork));
|
||||
return;
|
||||
}
|
||||
if (!this->getIContextNetwork()->isConnected())
|
||||
{
|
||||
this->sendStatusMessage(CStatusMessage::getWarningMessage("Cannot load flight plan, network not connected", CStatusMessage::TypeTrafficNetwork));
|
||||
return;
|
||||
}
|
||||
|
||||
CAircraft ownAircraft = this->getIContextOwnAircraft()->getOwnAircraft();
|
||||
CFlightPlan loadedPlan = this->getIContextNetwork()->loadFlightPlanFromNetwork(ownAircraft.getCallsign());
|
||||
if (loadedPlan.wasSentOrLoaded())
|
||||
{
|
||||
this->fillWithFlightPlanData(loadedPlan);
|
||||
this->sendStatusMessage(CStatusMessage::getInfoMessage("Updated with loaded flight plan", CStatusMessage::TypeTrafficNetwork));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->sendStatusMessage(CStatusMessage::getWarningMessage("No flight plan data", CStatusMessage::TypeTrafficNetwork));
|
||||
}
|
||||
}
|
||||
|
||||
void CFlightPlanComponent::buildRemarkString()
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace BlackGui
|
||||
void prefillWithAircraftData(const BlackMisc::Aviation::CAircraft &aircraftData);
|
||||
|
||||
//! Prefill with aircraft dara
|
||||
void prefillWithFlightPlanData(const BlackMisc::Aviation::CFlightPlan &flightPlan);
|
||||
void fillWithFlightPlanData(const BlackMisc::Aviation::CFlightPlan &flightPlan);
|
||||
|
||||
//! Get this flight plan
|
||||
BlackMisc::Aviation::CFlightPlan getFlightPlan() const;
|
||||
@@ -55,7 +55,7 @@ namespace BlackGui
|
||||
void resetFlightPlan();
|
||||
|
||||
//! Load Flightplan
|
||||
void loadFlightPlan();
|
||||
void loadFlightPlanFromNetwork();
|
||||
|
||||
//! Validate Flightplan
|
||||
void validateFlightPlan();
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace BlackMisc
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CAltitude::CAltitude(const QString &altitudeAsString) : BlackMisc::PhysicalQuantities::CLength(0, BlackMisc::PhysicalQuantities::CLengthUnit::m()), m_datum(MeanSeaLevel)
|
||||
CAltitude::CAltitude(const QString &altitudeAsString, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode) : BlackMisc::PhysicalQuantities::CLength(0, BlackMisc::PhysicalQuantities::CLengthUnit::m()), m_datum(MeanSeaLevel)
|
||||
{
|
||||
this->parseFromString(altitudeAsString);
|
||||
this->parseFromString(altitudeAsString, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Own implementation for streaming
|
||||
*/
|
||||
QString CAltitude::convertToQString(bool /* i18n */) const
|
||||
QString CAltitude::convertToQString(bool i18n) const
|
||||
{
|
||||
if (this->m_datum == FlightLevel)
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace BlackMisc
|
||||
}
|
||||
else
|
||||
{
|
||||
QString s = this->CLength::convertToQString();
|
||||
QString s = this->CLength::valueRoundedWithUnit(CLengthUnit::ft(), i18n);
|
||||
return s.append(this->isMeanSeaLevel() ? " MSL" : " AGL");
|
||||
}
|
||||
}
|
||||
@@ -156,6 +156,14 @@ namespace BlackMisc
|
||||
* Parse value
|
||||
*/
|
||||
void CAltitude::parseFromString(const QString &value)
|
||||
{
|
||||
this->parseFromString(value, BlackMisc::PhysicalQuantities::CPqString::SeparatorsCLocale);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse value
|
||||
*/
|
||||
void CAltitude::parseFromString(const QString &value, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode)
|
||||
{
|
||||
QString v = value.trimmed();
|
||||
|
||||
@@ -184,7 +192,7 @@ namespace BlackMisc
|
||||
rd = AboveGround;
|
||||
}
|
||||
|
||||
CLength l = BlackMisc::PhysicalQuantities::CPqString::parse<CLength>(v);
|
||||
CLength l = BlackMisc::PhysicalQuantities::CPqString::parse<CLength>(v, mode);
|
||||
*this = CAltitude(l, rd);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace BlackMisc
|
||||
CAltitude(double value, ReferenceDatum datum, const BlackMisc::PhysicalQuantities::CLengthUnit &unit) : BlackMisc::PhysicalQuantities::CLength(value, unit), m_datum(datum) {}
|
||||
|
||||
//! Altitude as string
|
||||
CAltitude(const QString &altitudeAsString);
|
||||
CAltitude(const QString &altitudeAsString, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode = BlackMisc::PhysicalQuantities::CPqString::SeparatorsLocale);
|
||||
|
||||
//! Constructor by CLength
|
||||
CAltitude(BlackMisc::PhysicalQuantities::CLength altitude, ReferenceDatum datum) : BlackMisc::PhysicalQuantities::CLength(altitude), m_datum(datum) {}
|
||||
@@ -102,9 +102,12 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::fromJson
|
||||
void fromJson(const QJsonObject &json) override;
|
||||
|
||||
//! \copydoc CValueObject::parseFromString
|
||||
//! \copydoc CValueObject::parseFromString(const QString &value)
|
||||
void parseFromString(const QString &value) override;
|
||||
|
||||
//! \copydoc CValueObject::parseFromString(const QString &value, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode)
|
||||
void parseFromString(const QString &value, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode) override;
|
||||
|
||||
//! Register metadata
|
||||
static void registerMetadata();
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ namespace BlackMisc
|
||||
SVFR //!< Special VFR (reserved for ATC use)
|
||||
};
|
||||
|
||||
static const int MaxRemarksLength = 150; //!< Max remarks length
|
||||
static const int MaxRouteLength = 150; //!< Max route length
|
||||
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
@@ -50,8 +53,12 @@ namespace BlackMisc
|
||||
const CAltitude &cruiseAltitude, const PhysicalQuantities::CSpeed &cruiseTrueAirspeed, FlightRules flightRules, const QString &route, const QString &remarks)
|
||||
: m_equipmentIcao(equipmentIcao), m_originAirportIcao(originAirportIcao), m_destinationAirportIcao(destinationAirportIcao), m_alternateAirportIcao(alternateAirportIcao),
|
||||
m_takeoffTimePlanned(takeoffTimePlanned), m_takeoffTimeActual(takeoffTimeActual), m_enrouteTime(enrouteTime), m_fuelTime(fuelTime),
|
||||
m_cruiseAltitude(cruiseAltitude), m_cruiseTrueAirspeed(cruiseTrueAirspeed), m_flightRules(flightRules), m_route(route), m_remarks(remarks.left(100))
|
||||
{}
|
||||
m_cruiseAltitude(cruiseAltitude), m_cruiseTrueAirspeed(cruiseTrueAirspeed), m_flightRules(flightRules),
|
||||
m_route(route.trimmed().left(MaxRouteLength).toUpper()), m_remarks(remarks.trimmed().left(MaxRemarksLength).toUpper())
|
||||
{
|
||||
m_enrouteTime.switchUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin());
|
||||
m_fuelTime.switchUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin());
|
||||
}
|
||||
|
||||
//! Set ICAO aircraft equipment code string (e.g. "T/A320/F")
|
||||
void setEquipmentIcao(const QString &equipmentIcao) { m_equipmentIcao = equipmentIcao; }
|
||||
@@ -87,10 +94,10 @@ namespace BlackMisc
|
||||
void setTakeoffTimeActual(QString time) { m_takeoffTimeActual = QDateTime::currentDateTimeUtc(); m_takeoffTimeActual.setTime(QTime::fromString(time, "hh:mm"));}
|
||||
|
||||
//! Set planned enroute flight time
|
||||
void setEnrouteTime(const PhysicalQuantities::CTime &enrouteTime) { m_enrouteTime = enrouteTime; }
|
||||
void setEnrouteTime(const PhysicalQuantities::CTime &enrouteTime) { m_enrouteTime = enrouteTime; m_enrouteTime.switchUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin());}
|
||||
|
||||
//! Set amount of fuel load in time
|
||||
void setFuelTime(const PhysicalQuantities::CTime &fuelTime) { m_fuelTime = fuelTime; }
|
||||
void setFuelTime(const PhysicalQuantities::CTime &fuelTime) { m_fuelTime = fuelTime; m_fuelTime.switchUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin());}
|
||||
|
||||
//! Set amount of fuel load in time hh:mm
|
||||
void setFuelTime(const QString &fuelTime) { m_fuelTime = PhysicalQuantities::CTime(fuelTime); }
|
||||
@@ -105,13 +112,13 @@ namespace BlackMisc
|
||||
void setFlightRule(FlightRules flightRules) { m_flightRules = flightRules; }
|
||||
|
||||
//! Set route string
|
||||
void setRoute(const QString &route) { m_route = route; }
|
||||
void setRoute(const QString &route) { m_route = route.trimmed().left(MaxRouteLength).toUpper(); }
|
||||
|
||||
//! Set remarks string (max 100 characters)
|
||||
void setRemarks(const QString &remarks) { m_remarks = remarks.left(100); }
|
||||
void setRemarks(const QString &remarks) { m_remarks = remarks.trimmed().left(MaxRemarksLength).toUpper(); }
|
||||
|
||||
//! When last sent
|
||||
void setWhenLastSent(const QDateTime &dateTime) { m_lastSent = dateTime; }
|
||||
void setWhenLastSentOrLoaded(const QDateTime &dateTime) { m_lastSentOrLoaded = dateTime; }
|
||||
|
||||
//! Get ICAO aircraft equipment code string
|
||||
const QString &getEquipmentIcao() const { return m_equipmentIcao; }
|
||||
@@ -147,7 +154,7 @@ namespace BlackMisc
|
||||
const PhysicalQuantities::CTime &getFuelTime() const { return m_fuelTime; }
|
||||
|
||||
//! Get amount of fuel load in time
|
||||
QString getFuelTimeHourMin() const { return m_enrouteTime.valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()); }
|
||||
QString getFuelTimeHourMin() const { return m_fuelTime.valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()); }
|
||||
|
||||
//! Cruising altitudes
|
||||
const BlackMisc::Aviation::CAltitude &getCruiseAltitude() const { return m_cruiseAltitude; }
|
||||
@@ -162,10 +169,16 @@ namespace BlackMisc
|
||||
const QString &getRoute() const { return m_route; }
|
||||
|
||||
//! When last sent
|
||||
const QDateTime &whenLastSent() const { return m_lastSent; }
|
||||
const QDateTime &whenLastSentOrLoaded() const { return m_lastSentOrLoaded; }
|
||||
|
||||
//! Flight plan already sent
|
||||
bool wasSent() const { return m_lastSent.isValid() && !m_lastSent.isNull(); }
|
||||
bool wasSentOrLoaded() const { return m_lastSentOrLoaded.isValid() && !m_lastSentOrLoaded.isNull(); }
|
||||
|
||||
//! \brief Received before n ms
|
||||
qint64 timeDiffSentOrLoadedMs() const
|
||||
{
|
||||
return this->m_lastSentOrLoaded.msecsTo(QDateTime::currentDateTimeUtc());
|
||||
}
|
||||
|
||||
//! Get remarks string
|
||||
const QString &getRemarks() const { return m_remarks; }
|
||||
@@ -219,13 +232,13 @@ namespace BlackMisc
|
||||
FlightRules m_flightRules;
|
||||
QString m_route;
|
||||
QString m_remarks;
|
||||
QDateTime m_lastSent;
|
||||
QDateTime m_lastSentOrLoaded;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CFlightPlan)
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CFlightPlan, (o.m_equipmentIcao, o.m_originAirportIcao, o.m_destinationAirportIcao, o.m_alternateAirportIcao,
|
||||
o.m_takeoffTimePlanned, o.m_takeoffTimeActual, o.m_enrouteTime, o.m_fuelTime, o.m_cruiseAltitude, tie(o.m_cruiseTrueAirspeed, o.m_flightRules, o.m_route, o.m_remarks, o.m_lastSent)))
|
||||
o.m_takeoffTimePlanned, o.m_takeoffTimeActual, o.m_enrouteTime, o.m_fuelTime, o.m_cruiseAltitude, tie(o.m_cruiseTrueAirspeed, o.m_flightRules, o.m_route, o.m_remarks, o.m_lastSentOrLoaded)))
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -234,10 +234,16 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::fromJson
|
||||
virtual void fromJson(const QJsonObject &json) override;
|
||||
|
||||
//! Parse to string, with specified separator
|
||||
virtual void parseFromString(const QString &value, CPqString::SeparatorMode mode)
|
||||
{
|
||||
this->parseFromString(value, mode);
|
||||
}
|
||||
|
||||
//! \copydoc CValueObject::parseFromString
|
||||
virtual void parseFromString(const QString &value) override
|
||||
{
|
||||
*this = CPqString::parse<PQ>(value);
|
||||
*this = CPqString::parse<PQ>(value, CPqString::SeparatorsCLocale);
|
||||
}
|
||||
|
||||
//! Register metadata of unit and quantity
|
||||
|
||||
@@ -93,17 +93,36 @@ namespace BlackMisc
|
||||
/*
|
||||
* Parse
|
||||
*/
|
||||
QVariant CPqString::parseToVariant(const QString &value)
|
||||
QVariant CPqString::parseToVariant(const QString &value, SeparatorMode mode)
|
||||
{
|
||||
static QRegExp rx("([0-9]+)\\s*(\\D*)$");
|
||||
QVariant v;
|
||||
if (value.isEmpty()) return v;
|
||||
QRegExp rx("^([-+]?[0-9]*\\.?[0-9]+)\\s*(\\D*)$");
|
||||
if (rx.indexIn(value) < 0) return v;
|
||||
QString number = rx.cap(1).trimmed();
|
||||
|
||||
if (rx.indexIn(value) < 0) return v; // not a valid number
|
||||
QString unit = rx.cap(2).trimmed();
|
||||
QString number = QString(value).replace(unit, "");
|
||||
unit = unit.trimmed(); // trim after replace, not before
|
||||
|
||||
if (unit.isEmpty() || number.isEmpty()) return v;
|
||||
bool success;
|
||||
double numberD = number.toDouble(&success);
|
||||
double numberD;
|
||||
switch (mode)
|
||||
{
|
||||
case SeparatorsLocale:
|
||||
numberD = QLocale::system().toDouble(number, &success);
|
||||
break;
|
||||
case SeparatorsCLocale:
|
||||
numberD = number.toDouble(&success);
|
||||
break;
|
||||
case SeparatorsBestGuess:
|
||||
numberD = number.toDouble(&success);
|
||||
if (!success) numberD = QLocale::system().toDouble(number, &success);
|
||||
break;
|
||||
default:
|
||||
qFatal("Wrong mode");
|
||||
break;
|
||||
}
|
||||
if (!success) return v;
|
||||
|
||||
if (CMeasurementUnit::isValidUnitSymbol<CAccelerationUnit>(unit))
|
||||
|
||||
@@ -42,13 +42,25 @@ namespace BlackMisc
|
||||
virtual bool isA(int metaTypeId) const override;
|
||||
|
||||
public:
|
||||
//! Number separators / group separators
|
||||
enum SeparatorMode
|
||||
{
|
||||
SeparatorsCLocale, //!< 100,000.00
|
||||
SeparatorsLocale, //!< depending on QLocale, e.g. 100.000,00 in Germany
|
||||
SeparatorsBestGuess //!< try to figure out
|
||||
};
|
||||
|
||||
//! Group and digit separator
|
||||
enum SeparatorIndex
|
||||
{
|
||||
Group,
|
||||
Digit
|
||||
};
|
||||
|
||||
//! Default constructor
|
||||
CPqString() {}
|
||||
|
||||
/*!
|
||||
* Constructor
|
||||
* \param value such as 10km/h
|
||||
*/
|
||||
//! Constructor, for values such as 10km/h
|
||||
CPqString(const QString &value) : m_string(value) {}
|
||||
|
||||
//! \copydoc CValueObject::toQVariant
|
||||
@@ -73,15 +85,15 @@ namespace BlackMisc
|
||||
static void registerMetadata();
|
||||
|
||||
//! Parse a string value like "100m", "10.3Mhz"
|
||||
static QVariant parseToVariant(const QString &value);
|
||||
static QVariant parseToVariant(const QString &value, SeparatorMode mode = SeparatorsCLocale);
|
||||
|
||||
//! Parse into concrete type
|
||||
template <class PQ> static PQ parse(const QString &value)
|
||||
template <class PQ> static PQ parse(const QString &value, SeparatorMode mode = SeparatorsCLocale)
|
||||
{
|
||||
PQ invalid;
|
||||
invalid.setNull();
|
||||
if (value.isEmpty()) return invalid;
|
||||
QVariant qv = CPqString::parseToVariant(value);
|
||||
QVariant qv = CPqString::parseToVariant(value, mode);
|
||||
if (!qv.isNull() && qv.canConvert<PQ>())
|
||||
{
|
||||
return qv.value<PQ>();
|
||||
|
||||
@@ -4,12 +4,26 @@ namespace BlackMisc
|
||||
{
|
||||
namespace PhysicalQuantities
|
||||
{
|
||||
CTime::CTime(int hours, int minutes, int seconds) : CPhysicalQuantity(0, CTimeUnit::nullUnit())
|
||||
{
|
||||
double value = hours + minutes / 100.0 + seconds / 10000.0;
|
||||
if (minutes == 0 && seconds == 0)
|
||||
{
|
||||
(*this) = CTime(hours, CTimeUnit::h());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (seconds == 0)
|
||||
(*this) = CTime(value, CTimeUnit::hrmin());
|
||||
else
|
||||
(*this) = CTime(value, CTimeUnit::hms());
|
||||
}
|
||||
}
|
||||
|
||||
CTime::CTime(const QTime &time) : CPhysicalQuantity(0, CTimeUnit::nullUnit())
|
||||
{
|
||||
int seconds = QTime(0, 0, 0).secsTo(time);
|
||||
CTime converted(seconds, CTimeUnit::s());
|
||||
converted.switchUnit(CTimeUnit::hms());
|
||||
*this = converted;
|
||||
CTime converted(time.hour(), time.minute(), time.second());
|
||||
(*this) = converted;
|
||||
}
|
||||
|
||||
void CTime::parseFromString(const QString &time)
|
||||
@@ -22,12 +36,7 @@ namespace BlackMisc
|
||||
t = QTime::fromString(ts, "hh:mm");
|
||||
else if (ts.length() == 8)
|
||||
t = QTime::fromString(ts, "hh:mm:ss");
|
||||
CTime parsed(t);
|
||||
if (ts.length() == 5)
|
||||
parsed.switchUnit(CTimeUnit::hrmin());
|
||||
else if (ts.length() == 8)
|
||||
parsed.switchUnit(CTimeUnit::hms());
|
||||
*this = parsed;
|
||||
(*this) = CTime(t);
|
||||
}
|
||||
else
|
||||
CPhysicalQuantity::parseFromString(ts);
|
||||
@@ -37,9 +46,19 @@ namespace BlackMisc
|
||||
{
|
||||
CTime copy(*this);
|
||||
copy.setUnit(CTimeUnit::hms());
|
||||
QString s = copy.toQString(false);
|
||||
QTime t = QTime::fromString(s, "hh:mm:ss");
|
||||
QString s = copy.toQString(false).replace('h', ':').replace('m', ':').replace('s', "");
|
||||
QTime t = s.length() == 8 ?
|
||||
QTime::fromString(s, "hh:mm:ss") :
|
||||
QTime::fromString(s, "hh:mm");
|
||||
return t;
|
||||
}
|
||||
|
||||
QList<int> CTime::getHrsMinSecParts() const
|
||||
{
|
||||
QTime t = this->toQTime();
|
||||
QList<int> parts;
|
||||
parts << t.hour() << t.minute() << t.second();
|
||||
return parts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,24 @@ namespace BlackMisc
|
||||
class CTime : public CPhysicalQuantity<CTimeUnit, CTime>
|
||||
{
|
||||
public:
|
||||
|
||||
//! Parts
|
||||
enum Parts
|
||||
{
|
||||
Hours = 0,
|
||||
Minutes,
|
||||
Seconds
|
||||
};
|
||||
|
||||
//! Default constructor
|
||||
CTime() : CPhysicalQuantity(0, CTimeUnit::defaultUnit()) {}
|
||||
|
||||
//! Init by double value
|
||||
CTime(double value, const CTimeUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
//! By hours, minutes, seconds
|
||||
CTime(int hours, int minutes, int seconds = 0);
|
||||
|
||||
//! By Qt time
|
||||
CTime(const QTime &time);
|
||||
|
||||
@@ -43,6 +55,9 @@ namespace BlackMisc
|
||||
//! To Qt time
|
||||
QTime toQTime() const;
|
||||
|
||||
//! Parts hh, mm, ss
|
||||
QList<int> getHrsMinSecParts() const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace BlackMisc
|
||||
double se = CMath::trunc((value - hr - mi / 100.0) * 1000000) / 100.0;
|
||||
const char *fmt = value < 0 ? "-%L1h%L2m%L3s" : "%L1h%L2m%L3s";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(hr), 0, 'f', 0).arg(fabs(mi), 2, 'f', 0, '0').arg(fabs(se), 2, 'f', digits, '0');
|
||||
s = s.arg(fabs(hr), 2, 'f', 0, '0').arg(fabs(mi), 2, 'f', 0, '0').arg(fabs(se), 2, 'f', digits, '0');
|
||||
}
|
||||
else if ((*this) == CTimeUnit::hrmin())
|
||||
{
|
||||
@@ -72,7 +72,7 @@ namespace BlackMisc
|
||||
double mi = CMath::trunc((value - hr) * 100.0);
|
||||
const char *fmt = value < 0 ? "-%L1h%L2m" : "%L1h%L2m";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(hr), 0, 'f', 0).arg(fabs(mi), 2, 'f', digits, '0');
|
||||
s = s.arg(fabs(hr), 2, 'f', 0, '0').arg(fabs(mi), 2, 'f', digits, '0');
|
||||
}
|
||||
else if ((*this) == CTimeUnit::minsec())
|
||||
{
|
||||
@@ -82,7 +82,7 @@ namespace BlackMisc
|
||||
double se = CMath::trunc((value - mi) * 100.0);
|
||||
const char *fmt = value < 0 ? "-%L2m%L3s" : "%L2m%L3s";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(mi), 0, 'f', 0).arg(fabs(se), 2, 'f', digits, '0');
|
||||
s = s.arg(fabs(mi), 2, 'f', 0, '0').arg(fabs(se), 2, 'f', digits, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user