refs #364, refs #368 Updated some value classes: user, client, icao, callsign, aircraft

* parsing homebase from user
* updating to Simulation/AircraftModel
* known ICAO function
* renaming, style changes
* convenience functions
This commit is contained in:
Klaus Basan
2015-01-18 20:52:09 +01:00
parent 4ab1577ac0
commit 2d6e906176
11 changed files with 182 additions and 77 deletions

View File

@@ -20,11 +20,13 @@ namespace BlackMisc
namespace Aviation
{
CAircraft::CAircraft(const CCallsign &callsign, const Network::CUser &user, const CAircraftSituation &situation)
: m_callsign(callsign), m_pilot(user), m_situation(situation), m_distanceToPlane(0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit())
: m_callsign(callsign), m_pilot(user), m_situation(situation)
{
// sync callsigns
if (!this->m_pilot.hasValidCallsign() && !callsign.isEmpty())
{
this->m_pilot.setCallsign(callsign);
}
}
/*
@@ -201,6 +203,5 @@ namespace BlackMisc
}
}
} // namespace
} // namespace

View File

@@ -28,9 +28,7 @@ namespace BlackMisc
{
namespace Aviation
{
/*!
* Value object encapsulating information of an aircraft
*/
//! Value object encapsulating information of an aircraft
class CAircraft : public CValueObjectStdTuple<CAircraft>, public Geo::ICoordinateGeodetic
{
public:
@@ -48,7 +46,7 @@ namespace BlackMisc
};
//! Default constructor.
CAircraft() : m_distanceToPlane(0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()) {}
CAircraft() {}
//! Constructor.
CAircraft(const CCallsign &callsign, const BlackMisc::Network::CUser &user, const CAircraftSituation &situation);
@@ -63,7 +61,7 @@ namespace BlackMisc
QString getCallsignAsString() const { return m_callsign.asString(); }
//! Set callsign
void setCallsign(const CCallsign &callsign) { this->m_callsign = callsign; this->m_pilot.setCallsign(callsign); }
virtual void setCallsign(const CCallsign &callsign) { this->m_callsign = callsign; this->m_pilot.setCallsign(callsign); }
//! Get situation.
const CAircraftSituation &getSituation() const { return m_situation; }
@@ -80,14 +78,14 @@ namespace BlackMisc
//! Get user's real id
QString getPilotId() { return m_pilot.getId(); }
//! Set user
void setPilot(const BlackMisc::Network::CUser &user) { m_pilot = user; this->m_pilot.setCallsign(this->m_callsign);}
//! Set pilot (user)
virtual void setPilot(const BlackMisc::Network::CUser &user) { m_pilot = user; this->m_pilot.setCallsign(this->m_callsign);}
//! Get ICAO info
const CAircraftIcao &getIcaoInfo() const { return m_icao; }
//! Set ICAO info
void setIcaoInfo(const CAircraftIcao &icao) { m_icao = icao; }
virtual void setIcaoInfo(const CAircraftIcao &icao) { m_icao = icao; }
//! Get the distance to own plane
const BlackMisc::PhysicalQuantities::CLength &getDistanceToPlane() const { return m_distanceToPlane; }
@@ -104,9 +102,15 @@ namespace BlackMisc
//! Has valid id?
bool hasValidId() const { return this->m_pilot.hasValidId(); }
//! Valid designator?
bool hasValidAircraftDesignator() const { return this->m_icao.hasAircraftDesignator(); }
//! Valid designators?
bool hasValidAircraftAndAirlineDesignator() const { return this->m_icao.hasAircraftAndAirlineDesignator(); }
//! Valid callsign
bool hasValidCallsign() const { return CCallsign::isValidCallsign(this->getCallsign().asString()); }
//! Distance to aircraft
PhysicalQuantities::CLength calculcateDistanceToPosition(const Geo::CCoordinateGeodetic &position) const;
@@ -241,15 +245,15 @@ namespace BlackMisc
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAircraft)
CCallsign m_callsign;
CCallsign m_callsign;
BlackMisc::Network::CUser m_pilot;
CAircraftSituation m_situation;
BlackMisc::Aviation::CComSystem m_com1system;
BlackMisc::Aviation::CComSystem m_com2system;
BlackMisc::Aviation::CTransponder m_transponder;
BlackMisc::Aviation::CSelcal m_selcal;
CAircraftIcao m_icao;
BlackMisc::PhysicalQuantities::CLength m_distanceToPlane;
CAircraftSituation m_situation;
CComSystem m_com1system;
CComSystem m_com2system;
CTransponder m_transponder;
CSelcal m_selcal;
CAircraftIcao m_icao;
BlackMisc::PhysicalQuantities::CLength m_distanceToPlane {0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()};
};
} // namespace
} // namespace

View File

@@ -19,11 +19,9 @@ namespace BlackMisc
{
namespace Aviation
{
/*
* Convert to string
*/
QString CAircraftIcao::convertToQString(bool /** i18n **/) const
QString CAircraftIcao::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
QString s(this->m_aircraftDesignator);
if (this->hasAircraftCombinedType()) s.append(" ").append(this->m_aircraftCombinedType);
if (this->hasAirlineDesignator()) s.append(" ").append(this->m_airlineDesignator);
@@ -32,12 +30,19 @@ namespace BlackMisc
return s;
}
/*
* As string
*/
bool CAircraftIcao::hasAircraftDesignator() const
{
return !this->m_aircraftDesignator.isEmpty();
}
bool CAircraftIcao::hasKnownAircraftDesignator() const
{
return (this->getAircraftDesignator() != "ZZZZ");
}
QString CAircraftIcao::asString() const
{
if (this->m_aircraftDesignator.isEmpty()) return "";
if (this->m_aircraftDesignator.isEmpty()) { return ""; }
QString s(this->m_aircraftDesignator);
if (!this->m_airlineDesignator.isEmpty())
{
@@ -72,9 +77,6 @@ namespace BlackMisc
return true;
}
/*
* Property by index
*/
CVariant CAircraftIcao::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return this->toCVariant(); }
@@ -96,9 +98,6 @@ namespace BlackMisc
}
}
/*
* Property by index
*/
void CAircraftIcao::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
{
if (index.isMyself())
@@ -128,19 +127,13 @@ namespace BlackMisc
}
}
/*
* Valid designator?
*/
bool CAircraftIcao::isValidDesignator(const QString &designator)
{
static QRegularExpression regexp("^[A-Z]+[A-Z0-9]*$");
if (designator.length() < 2 || designator.length() > 5) return false;
if (designator.length() < 2 || designator.length() > 5) { return false; }
return (regexp.match(designator).hasMatch());
}
/*
* Valid combined type
*/
bool CAircraftIcao::isValidCombinedType(const QString &combinedType)
{
static QRegularExpression regexp("^[A-Z][0-9][A-Z]$");
@@ -148,9 +141,6 @@ namespace BlackMisc
return (regexp.match(combinedType).hasMatch());
}
/*
* Valid airline designator
*/
bool CAircraftIcao::isValidAirlineDesignator(const QString &airline)
{
static QRegularExpression regexp("^[A-Z]+[A-Z0-9]*$");

View File

@@ -69,7 +69,10 @@ namespace BlackMisc
void setAircraftDesignator(const QString &icaoDesignator) { this->m_aircraftDesignator = icaoDesignator.trimmed().toUpper(); }
//! Aircraft designator?
bool hasAircraftDesignator() const { return !this->m_aircraftDesignator.isEmpty(); }
bool hasAircraftDesignator() const;
//! Has designator and designator is not "ZZZZ"
bool hasKnownAircraftDesignator() const;
//! Get airline, e.g. "DLH"
const QString &getAirlineDesignator() const { return this->m_airlineDesignator; }

View File

@@ -29,7 +29,8 @@ namespace BlackMisc
QString CCallsign::unifyCallsign(const QString &callsign)
{
QString unified = callsign.toUpper();
unified = unified.remove(QRegExp("[^a-zA-Z\\d\\s]"));
// allow A-Z, 0-9, _, but no spaces
unified = unified.remove(QRegExp("[^A-Z\\d_]"));
return unified;
}
@@ -48,7 +49,7 @@ namespace BlackMisc
if ("DEL" == t) { return CIconList::iconByIndex(CIcons::NetworkRoleDelivery); }
if ("CTR" == t) { return CIconList::iconByIndex(CIcons::NetworkRoleCenter); }
if ("SUP" == t) { return CIconList::iconByIndex(CIcons::NetworkRoleSup); }
if ("OBS" == t) { return CIconList::iconByIndex(CIcons::NetworkRoleApproach); }
if ("OBS" == t) { return CIconList::iconByIndex(CIcons::NetworkRoleObs); }
if ("ATIS" == t) { return CIconList::iconByIndex(CIcons::AviationAtis); }
return CIconList::iconByIndex(CIcons::NetworkRoleUnknown);
}
@@ -63,11 +64,17 @@ namespace BlackMisc
*/
bool CCallsign::isAtcCallsign() const
{
if (this->hasSuffix())
{
return atcCallsignSuffixes().contains(this->getSuffix(), Qt::CaseInsensitive);
}
return false;
if (!this->hasSuffix()) { return false; }
return atcCallsignSuffixes().contains(this->getSuffix(), Qt::CaseInsensitive);
}
/*
* ATC callsign?
*/
bool CCallsign::isAtcAlikeCallsign() const
{
if (!this->hasSuffix()) { return false; }
return atcAlikeCallsignSuffixes().contains(this->getSuffix(), Qt::CaseInsensitive);
}
/*
@@ -127,6 +134,8 @@ namespace BlackMisc
return CVariant(this->getStringAsSet());
case IndexTelephonyDesignator:
return CVariant(this->getTelephonyDesignator());
case IndexSuffix:
return CVariant(this->getSuffix());
default:
return CValueObject::propertyByIndex(index);
}
@@ -164,8 +173,10 @@ namespace BlackMisc
*/
bool CCallsign::isValidCallsign(const QString &callsign)
{
static QRegularExpression regexp("^[A-Z]+[A-Z0-9]*$");
if (callsign.length() < 2 || callsign.length() > 10) return false;
//! \todo sometimes callsigns such as 12345, really correct?
// static QRegularExpression regexp("^[A-Z]+[A-Z0-9]*$");
static QRegularExpression regexp("^[A-Z0-9]*$");
if (callsign.length() < 2 || callsign.length() > 10) { return false; }
return (regexp.match(callsign).hasMatch());
}
@@ -174,7 +185,13 @@ namespace BlackMisc
*/
const QStringList &CCallsign::atcCallsignSuffixes()
{
static const QStringList a( { "ATIS", "APP", "GND", "TWR", "DEL", "CTR", "SUP", "FSS" });
static const QStringList a( { "APP", "GND", "TWR", "DEL", "CTR" });
return a;
}
const QStringList &CCallsign::atcAlikeCallsignSuffixes()
{
static const QStringList a( { "ATIS", "APP", "GND", "OBS", "TWR", "DEL", "CTR", "SUP", "FSS" });
return a;
}

View File

@@ -29,7 +29,8 @@ namespace BlackMisc
{
IndexCallsignString = BlackMisc::CPropertyIndex::GlobalIndexCCallsign,
IndexCallsignStringAsSet,
IndexTelephonyDesignator
IndexTelephonyDesignator,
IndexSuffix
};
//! Default constructor.
@@ -49,8 +50,13 @@ namespace BlackMisc
bool isEmpty() const { return this->m_callsignAsSet.isEmpty(); }
//! ATC callsign
//! \sa atcCallsignSuffixes()
bool isAtcCallsign() const;
//! ATC alike callsign
//! \sa atcAlikeCallsignSuffixes()
bool isAtcAlikeCallsign() const;
//! Get callsign.
const QString &asString() const { return this->m_callsign; }
@@ -87,9 +93,12 @@ namespace BlackMisc
//! Valid callsign?
static bool isValidCallsign(const QString &callsign);
//! List of ATC suffixes (e.g. TWR);
//! List of real ATC suffixes (e.g. TWR);
static const QStringList &atcCallsignSuffixes();
//! List of real ("TWR") and treated like ATC suffixes (e.g. OBS);
static const QStringList &atcAlikeCallsignSuffixes();
protected:
//! \copydoc CValueObject::convertToQString()
virtual QString convertToQString(bool i18n = false) const override;
@@ -110,10 +119,10 @@ namespace BlackMisc
} // namespace
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CCallsign, (
attr(o.m_callsign, flags<CaseInsensitiveComparison>()),
attr(o.m_callsignAsSet, flags<DisabledForComparison>()),
attr(o.m_telephonyDesignator, flags<DisabledForComparison>())
))
attr(o.m_callsign, flags<CaseInsensitiveComparison>()),
attr(o.m_callsignAsSet, flags<DisabledForComparison>()),
attr(o.m_telephonyDesignator, flags<DisabledForComparison>())
))
Q_DECLARE_METATYPE(BlackMisc::Aviation::CCallsign)
#endif // guard

View File

@@ -51,11 +51,11 @@ namespace BlackMisc
};
//! Default constructor
CComSystem() : m_channelSpacing(ChannelSpacing25KHz) {}
CComSystem() {}
//! Constructor
CComSystem(const QString &name, const BlackMisc::PhysicalQuantities::CFrequency &activeFrequency, const BlackMisc::PhysicalQuantities::CFrequency &standbyFrequency = CModulator::FrequencyNotSet()):
CValueObjectStdTuple(name, activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency), m_channelSpacing(ChannelSpacing25KHz)
CValueObjectStdTuple(name, activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency)
{ }
//! Set active frequency
@@ -172,7 +172,7 @@ namespace BlackMisc
virtual bool validValues() const override;
private:
ChannelSpacing m_channelSpacing; //!< channel spacing
ChannelSpacing m_channelSpacing = ChannelSpacing25KHz; //!< channel spacing
/*!
* Give me channel spacing in KHz

View File

@@ -67,9 +67,18 @@ namespace BlackMisc
bool CClient::hasCapability(CClient::Capabilities capability) const
{
if (this->m_capabilities.contains(capability))
{
return this->m_capabilities.value(capability).toBool();
}
else
{
return false;
}
}
void CClient::setUserCallsign(const Aviation::CCallsign &callsign)
{
this->m_user.setCallsign(callsign);
}
/*

View File

@@ -13,7 +13,7 @@
#define BLACKMISC_CLIENT_H
#include "nwuser.h"
#include "nwaircraftmodel.h"
#include "blackmisc/simulation/aircraftmodel.h"
#include "nwvoicecapabilities.h"
#include "propertyindex.h"
#include "propertyindexvariantmap.h"
@@ -64,7 +64,7 @@ namespace BlackMisc
const BlackMisc::Aviation::CCallsign &getCallsign() const { return this->m_user.getCallsign(); }
//! ATC client
bool isAtc() const { return getCallsign().isAtcCallsign(); }
bool isAtc() const { return getCallsign().isAtcAlikeCallsign(); }
//! Get capabilities
CPropertyIndexVariantMap getCapabilities() const { return this->m_capabilities; }
@@ -99,6 +99,9 @@ namespace BlackMisc
//! User
void setUser(const CUser &user) { this->m_user = user;}
//! User's callsign
void setUserCallsign(const BlackMisc::Aviation::CCallsign &callsign);
//! Server
const QString &getServer() const { return this->m_server; }
@@ -106,10 +109,13 @@ namespace BlackMisc
void setServer(const QString &server) { this->m_server = server;}
//! Model
const CAircraftModel &getAircraftModel() const { return this->m_model; }
const BlackMisc::Simulation::CAircraftModel &getAircraftModel() const { return this->m_model; }
//! \copydoc CAircraftModel::hasQueriedModelString
bool hasQueriedModelString() const { return this->m_model.hasQueriedModelString(); }
//! Set model
void setAircraftModel(const CAircraftModel &model) { this->m_model = model; }
void setAircraftModel(const BlackMisc::Simulation::CAircraftModel &model) { this->m_model = model; }
//! \copydoc CValueObject::toIcon()
virtual CIcon toIcon() const override { return this->m_user.toIcon(); }
@@ -127,7 +133,7 @@ namespace BlackMisc
private:
BLACK_ENABLE_TUPLE_CONVERSION(CClient)
CUser m_user;
CAircraftModel m_model;
BlackMisc::Simulation::CAircraftModel m_model;
CPropertyIndexVariantMap m_capabilities;
QString m_server;
CVoiceCapabilities m_voiceCapabilities;

View File

@@ -8,18 +8,35 @@
*/
#include "nwuser.h"
#include "blackmisc/avairporticao.h"
#include "blackmisc/icon.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/variant.h"
#include <tuple>
#include <QRegExp>
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Network
{
QString CUser::convertToQString(bool /** i18n **/) const
CUser::CUser(const QString &id, const QString &realname, const CCallsign &callsign)
: m_id(id.trimmed()), m_realname(realname), m_callsign(callsign)
{
this->setRealName(realname); // extracts homebase
}
CUser::CUser(const QString &id, const QString &realname, const QString &email, const QString &password, const CCallsign &callsign)
: m_id(id.trimmed()), m_realname(realname), m_email(email), m_password(password), m_callsign(callsign)
{
this->setRealName(realname); // extracts homebase
}
QString CUser::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
if (this->m_realname.isEmpty()) return "<no realname>";
QString s = this->m_realname;
if (this->hasValidId())
@@ -33,6 +50,33 @@ namespace BlackMisc
return s;
}
void CUser::setRealName(const QString &realname)
{
// try to strip homebase
// I understand the limitations, but we will have more correct hits as failures I assume
const QRegularExpression reg("(-\\s*|\\s)([A-Z]{4})$");
QString rn = realname.trimmed().simplified();
if (rn.isEmpty())
{
this->m_realname = "";
return;
}
if (!this->hasValidHomebase())
{
//! only apply stripping if home base is not explicitly given
QRegularExpressionMatch match = reg.match(rn);
if (match.hasMatch())
{
int pos = match.capturedStart(0);
QString icao = match.captured(0).trimmed().right(4);
rn = rn.left(pos).trimmed();
this->setHomebase(CAirportIcao(icao));
}
}
this->m_realname = rn;
}
CStatusMessageList CUser::validate() const
{
CStatusMessageList msgs;
@@ -48,27 +92,43 @@ namespace BlackMisc
*/
void CUser::syncronizeData(CUser &otherUser)
{
if (otherUser == (*this)) return;
if (otherUser == (*this)) { return; }
if (this->hasValidRealName())
{
otherUser.setRealName(this->getRealName());
}
else if (otherUser.hasValidRealName())
{
this->setRealName(otherUser.getRealName());
}
if (this->hasValidId())
{
otherUser.setId(this->getId());
}
else if (otherUser.hasValidId())
{
this->setId(otherUser.getId());
}
if (this->hasValidEmail())
{
otherUser.setEmail(this->getEmail());
}
else if (otherUser.hasValidEmail())
{
this->setEmail(otherUser.getEmail());
}
if (this->hasValidCallsign())
{
otherUser.setCallsign(this->getCallsign());
}
else if (otherUser.hasValidCallsign())
{
this->setCallsign(otherUser.getCallsign());
}
}
bool CUser::isValidVatsimId(const QString &id)
@@ -97,6 +157,8 @@ namespace BlackMisc
return CVariant(this->m_password);
case IndexRealName:
return CVariant(this->m_realname);
case IndexHomebase:
return this->m_homebase.propertyByIndex(index.copyFrontRemoved());
case IndexCallsign:
return this->m_callsign.propertyByIndex(index.copyFrontRemoved());
default:
@@ -129,6 +191,9 @@ namespace BlackMisc
case IndexRealName:
this->setRealName(variant.value<QString>());
break;
case IndexHomebase:
this->m_homebase.setPropertyByIndex(variant, index.copyFrontRemoved());
break;
case IndexCallsign:
this->m_callsign.setPropertyByIndex(variant, index.copyFrontRemoved());
break;

View File

@@ -38,7 +38,8 @@ namespace BlackMisc
IndexId,
IndexPassword,
IndexRealName,
IndexCallsign
IndexCallsign,
IndexHomebase
};
//! Default constructor.
@@ -48,20 +49,16 @@ namespace BlackMisc
CUser(const BlackMisc::Aviation::CCallsign &callsign) : m_callsign(callsign) {}
//! Constructor.
CUser(const QString &id, const QString &realname, const BlackMisc::Aviation::CCallsign &callsign)
: m_id(id), m_realname(realname), m_callsign(callsign)
{}
CUser(const QString &id, const QString &realname, const BlackMisc::Aviation::CCallsign &callsign);
//! Constructor.
CUser(const QString &id, const QString &realname, const QString &email = "", const QString &password = "", const BlackMisc::Aviation::CCallsign &callsign = BlackMisc::Aviation::CCallsign())
: m_id(id), m_realname(realname), m_email(email), m_password(password), m_callsign(callsign)
{}
CUser(const QString &id, const QString &realname, const QString &email = "", const QString &password = "", const BlackMisc::Aviation::CCallsign &callsign = BlackMisc::Aviation::CCallsign());
//! Get full name.
QString getRealName() const { return m_realname; }
//! setRealName
void setRealName(const QString &realname) { m_realname = realname.trimmed().simplified(); }
void setRealName(const QString &realname);
//! Get password
QString getPassword() const { return m_password; }
@@ -84,6 +81,9 @@ namespace BlackMisc
//! Has associated callsign?
bool hasValidCallsign() const { return !m_callsign.isEmpty(); }
//! Valid homebase
bool hasValidHomebase() const { return !m_homebase.isEmpty(); }
//! Validate, provide details about issues
BlackMisc::CStatusMessageList validate() const;
@@ -138,6 +138,7 @@ namespace BlackMisc
private:
BLACK_ENABLE_TUPLE_CONVERSION(CUser)
QString m_id;
QString m_realname;
QString m_email;