#include "avatcstation.h" #include "aviocomsystem.h" #include "vvoiceroom.h" #include "blackmiscfreefunctions.h" using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Geo; using namespace BlackMisc::Network; using namespace BlackMisc::Voice; namespace BlackMisc { namespace Aviation { /* * Constructor */ CAtcStation::CAtcStation() : m_distanceToPlane(-1.0, CLengthUnit::NM()), m_isOnline(false), m_atis(CInformationMessage::ATIS), m_metar(CInformationMessage::METAR) { // void } /* * Constructor */ CAtcStation::CAtcStation(const QString &callsign) : m_callsign(callsign), m_distanceToPlane(-1.0, CLengthUnit::NM()), m_isOnline(false), m_atis(CInformationMessage::ATIS), m_metar(CInformationMessage::METAR) { // void } /* * Constructor */ CAtcStation::CAtcStation(const CCallsign &callsign, const CUser &controller, const CFrequency &frequency, const CCoordinateGeodetic &pos, const CLength &range, bool isOnline, const QDateTime &bookedFromUtc, const QDateTime &bookedUntilUtc, const CInformationMessage &atis, const CInformationMessage &metar) : m_callsign(callsign), m_controller(controller), m_frequency(frequency), m_position(pos), m_range(range), m_distanceToPlane(-1.0, CLengthUnit::NM()), m_isOnline(isOnline), m_bookedFromUtc(bookedFromUtc), m_bookedUntilUtc(bookedUntilUtc), m_atis(atis), m_metar(metar) { // void } /* * Convert to string */ QString CAtcStation::convertToQString(bool i18n) const { QString s = i18n ? QCoreApplication::translate("Aviation", "ATC station") : "ATC station"; s.append(' ').append(this->m_callsign.toQString(i18n)); // position s.append(' ').append(this->m_position.toQString(i18n)); // Online? s.append(' '); if (this->m_isOnline) { i18n ? s.append(QCoreApplication::translate("Aviation", "online")) : s.append("online"); } else { i18n ? s.append(QCoreApplication::translate("Aviation", "offline")) : s.append("offline"); } // controller name if (!this->m_controller.isValid()) { s.append(' '); s.append(this->m_controller.toQString(i18n)); } // frequency s.append(' '); s.append(this->m_frequency.toQString(i18n)); // ATIS if (this->hasAtis()) { s.append(' '); s.append(this->m_atis.toQString(i18n)); } // METAR if (this->hasMetar()) { s.append(' '); s.append(this->m_metar.toQString(i18n)); } // range s.append(' '); i18n ? s.append(s.append(QCoreApplication::translate("Aviation", "range"))) : s.append("range"); s.append(": "); s.append(this->m_range.toQString(i18n)); // distance to plane if (this->m_distanceToPlane.isPositiveWithEpsilonConsidered()) { i18n ? s.append(QCoreApplication::translate("Aviation", "distance")) : s.append("distance"); s.append(' '); s.append(this->m_distanceToPlane.toQString(i18n)); } // from / to if (!this->hasBookingTimes()) return s; // append from s.append(' '); i18n ? s.append(s.append(QCoreApplication::translate("Aviation", "from(UTC)"))) : s.append("from(UTC)"); s.append(": "); if (this->m_bookedFromUtc.isNull()) { s.append('-'); } else { s.append(this->m_bookedFromUtc.toString("yy-MM-dd HH:mm")); } // append to s.append(' '); i18n ? s.append(s.append(QCoreApplication::translate("Aviation", "until(UTC)"))) : s.append("to(UTC)"); s.append(": "); if (this->m_bookedFromUtc.isNull()) { s.append('-'); } else { s.append(this->m_bookedUntilUtc.toString("yy-MM-dd HH:mm")); } return s; // force strings for translation in resource files (void)QT_TRANSLATE_NOOP("Aviation", "ATC station"); (void)QT_TRANSLATE_NOOP("Aviation", "online"); (void)QT_TRANSLATE_NOOP("Aviation", "offline"); (void)QT_TRANSLATE_NOOP("Aviation", "from(UTC)"); (void)QT_TRANSLATE_NOOP("Aviation", "until(UTC)"); (void)QT_TRANSLATE_NOOP("Aviation", "range"); (void)QT_TRANSLATE_NOOP("Aviation", "distance"); (void)QT_TRANSLATE_NOOP("Network", "voiceroom"); } /* * Marshall to DBus */ void CAtcStation::marshallToDbus(QDBusArgument &argument) const { argument << this->m_callsign; argument << this->m_frequency; argument << this->m_controller; argument << this->m_position; argument << this->m_range; argument << this->m_distanceToPlane; argument << this->m_isOnline; argument << this->m_bookedFromUtc; argument << this->m_bookedUntilUtc; argument << this->m_atis; argument << this->m_metar; argument << this->m_voiceRoom; } /* * Unmarshall from DBus */ void CAtcStation::unmarshallFromDbus(const QDBusArgument &argument) { argument >> this->m_callsign; argument >> this->m_frequency; argument >> this->m_controller; argument >> this->m_position; argument >> this->m_range; argument >> this->m_distanceToPlane; argument >> this->m_isOnline; argument >> this->m_bookedFromUtc; argument >> this->m_bookedUntilUtc; argument >> this->m_atis; argument >> this->m_metar; argument >> this->m_voiceRoom; } /* * Register metadata */ void CAtcStation::registerMetadata() { qRegisterMetaType(); qDBusRegisterMetaType(); } /* * Equal? */ bool CAtcStation::operator ==(const CAtcStation &other) const { if (this == &other) return true; if (other.getCallsign() != this->getCallsign() || other.getRange() != this->getRange() || other.getFrequency() != this->getFrequency() || other.getPosition() != this->getPosition()) return false; if (other.getController() != this->getController()) return false; if (other.getAtis() != this->getAtis()) return false; if (other.getMetar() != this->getMetar()) return false; if (other.getVoiceRoom() != this->getVoiceRoom()) return false; return this->getBookedFromUtc() == other.getBookedFromUtc() && this->getBookedUntilUtc() == other.getBookedUntilUtc(); } /* * Unequal? */ bool CAtcStation::operator !=(const CAtcStation &other) const { return !((*this) == other); } /* * SyncronizeControllerData */ void CAtcStation::syncronizeControllerData(CAtcStation &otherStation) { if (this->m_controller == otherStation.getController()) return; CUser otherController = otherStation.getController(); this->m_controller.syncronizeData(otherController); otherStation.setController(otherController); } /* * Distance to planne */ const CLength &CAtcStation::calculcateDistanceToPlane(const CCoordinateGeodetic &position) { this->m_distanceToPlane = greatCircleDistance(this->m_position, position); return this->m_distanceToPlane; } /* * Booked now */ bool CAtcStation::isBookedNow() const { if (!this->hasValidBookingTimes()) return false; QDateTime now = QDateTime::currentDateTimeUtc(); if (this->m_bookedFromUtc > now) return false; if (now > this->m_bookedUntilUtc) return false; return true; } /*! * \brief When booked? * \return */ CTime CAtcStation::bookedWhen() const { if (!this->hasValidBookingTimes()) return CTime(-365.0, CTimeUnit::d()); QDateTime now = QDateTime::currentDateTimeUtc(); qint64 diffMs; if (this->m_bookedFromUtc > now) { // future diffMs = now.msecsTo(this->m_bookedFromUtc); return CTime(diffMs / 1000.0, CTimeUnit::s()); } else if (this->m_bookedUntilUtc > now) { // now return CTime(0.0, CTimeUnit::s()); } else { // past diffMs = m_bookedUntilUtc.msecsTo(now); return CTime(-diffMs / 1000.0, CTimeUnit::s()); } } /* * Hash */ uint CAtcStation::getValueHash() const { QList hashs; hashs << this->m_callsign.getValueHash(); hashs << this->m_frequency.getValueHash(); hashs << this->m_controller.getValueHash(); hashs << this->m_position.getValueHash(); hashs << this->m_range.getValueHash(); hashs << this->m_distanceToPlane.getValueHash(); hashs << this->m_metar.getValueHash(); hashs << this->m_atis.getValueHash(); hashs << this->m_voiceRoom.getValueHash(); hashs << qHash(this->m_isOnline ? 1 : 3); hashs << qHash(this->m_bookedFromUtc); hashs << qHash(this->m_bookedUntilUtc); return BlackMisc::calculateHash(hashs, "CAtcStation"); } /* * Property by index */ QVariant CAtcStation::propertyByIndex(int index) const { switch (index) { case IndexBookedFrom: return QVariant(this->m_bookedFromUtc); case IndexBookedUntil: return QVariant(this->m_bookedUntilUtc); case IndexCallsign: return this->m_callsign.toQVariant(); case IndexCallsignAsString: return QVariant(this->m_callsign.asString()); case IndexCallsignAsStringAsSet: return QVariant(this->m_callsign.getStringAsSet()); case IndexController: return this->m_controller.toQVariant(); case IndexControllerRealName: return QVariant(this->getControllerRealName()); case IndexControllerId: return QVariant(this->getControllerId()); case IndexFrequency: return this->m_frequency.toQVariant(); case IndexIsOnline: return QVariant(this->m_isOnline); case IndexLatitude: return this->latitude().toQVariant(); case IndexDistance: return this->m_distanceToPlane.toQVariant(); case IndexLongitude: return this->longitude().toQVariant(); case IndexPosition: return this->m_position.toQVariant(); case IndexRange: return this->m_range.toQVariant(); case IndexAtis: return this->m_atis.toQVariant(); case IndexAtisMessage: return QVariant(this->m_atis.getMessage()); case IndexMetar: return this->m_metar.toQVariant(); case IndexMetarMessage: return QVariant(this->m_metar.getMessage()); case IndexVoiceRoom: return QVariant(this->m_voiceRoom.toQVariant()); case IndexVoiceRoomUrl: return QVariant(this->m_voiceRoom.getVoiceRoomUrl()); default: break; } Q_ASSERT_X(false, "CAtcStation", "index unknown"); QString m = QString("no property, index ").append(QString::number(index)); return QVariant::fromValue(m); } /* * Set property as index */ void CAtcStation::setPropertyByIndex(const QVariant &variant, int index) { switch (index) { case IndexBookedFrom: this->setBookedFromUtc(variant.value()); break; case IndexBookedUntil: this->setBookedUntilUtc(variant.value()); break; case IndexCallsign: this->setCallsign(variant.value()); break; case IndexCallsignAsString: this->setCallsign(CCallsign(variant.value())); break; case IndexController: this->setController(variant.value()); break; case IndexControllerRealName: this->setControllerRealName(variant.value()); break; case IndexControllerId: this->setControllerId(variant.value()); break; case IndexFrequency: this->setFrequency(variant.value()); break; case IndexIsOnline: this->setOnline(variant.value()); break; case IndexPosition: this->setPosition(variant.value()); break; case IndexRange: this->setRange(variant.value()); break; case IndexDistance: this->setDistanceToPlane(variant.value()); break; case IndexAtis: this->setAtis(variant.value()); break; case IndexAtisMessage: this->setAtisMessage(variant.value()); break; case IndexMetar: this->setMetar(variant.value()); break; case IndexMetarMessage: this->setMetarMessage(variant.value()); break; case IndexVoiceRoom: this->setVoiceRoom(variant.value()); break; case IndexVoiceRoomUrl: this->setVoiceRoom(CVoiceRoom(variant.toString())); break; default: Q_ASSERT_X(false, "CAtcStation", "index unknown (setter)"); break; } } /* * metaTypeId */ int CAtcStation::getMetaTypeId() const { return qMetaTypeId(); } /* * is a */ bool CAtcStation::isA(int metaTypeId) const { if (metaTypeId == qMetaTypeId()) { return true; } return this->CValueObject::isA(metaTypeId); } /* * Compare */ int CAtcStation::compareImpl(const CValueObject &otherBase) const { const auto &other = static_cast(otherBase); return this->getCallsign().asString().compare(other.getCallsign().asString(), Qt::CaseInsensitive); } /* * Property as string by index */ QString CAtcStation::propertyByIndexAsString(int index, bool i18n) const { QVariant qv = this->propertyByIndex(index); // special treatment // this is required as it is possible an ATC station is not containing all // properties switch (index) { case IndexFrequency: if (!CComSystem::isValidCivilAviationFrequency(qv.value())) return ""; else return qv.value().valueRoundedWithUnit(3, i18n); break; case IndexDistance: { CLength distance = qv.value(); if (distance.isNegativeWithEpsilonConsidered()) return ""; return distance.toQString(i18n); } case IndexBookedFrom: case IndexBookedUntil: { QDateTime dt = qv.value(); if (dt.isNull() || !dt.isValid()) return ""; return dt.toString("yyyy-MM-dd HH:mm"); break; } default: break; } return BlackMisc::qVariantToString(qv, i18n); } } // namespace } // namespace