diff --git a/src/blackgui/models/aircrafticaolistmodel.cpp b/src/blackgui/models/aircrafticaolistmodel.cpp index 2295d3f2e..f71d5cd88 100644 --- a/src/blackgui/models/aircrafticaolistmodel.cpp +++ b/src/blackgui/models/aircrafticaolistmodel.cpp @@ -19,7 +19,7 @@ namespace BlackGui namespace Models { CAircraftIcaoCodeListModel::CAircraftIcaoCodeListModel(QObject *parent) : - CListModelBase("AircraftIcaoListModel", parent) + CListModelBase("AircraftIcaoListModel", parent) { this->m_columns.addColumn(CColumn::standardString("id", CAircraftIcaoCode::IndexDbIntegerKey, CDefaultFormatter::alignRightVCenter())); this->m_columns.addColumn(CColumn::standardValueObject("ICAO", CAircraftIcaoCode::IndexAircraftDesignator)); diff --git a/src/blackgui/models/aircrafticaolistmodel.h b/src/blackgui/models/aircrafticaolistmodel.h index ec2a661cb..f31595290 100644 --- a/src/blackgui/models/aircrafticaolistmodel.h +++ b/src/blackgui/models/aircrafticaolistmodel.h @@ -21,13 +21,11 @@ namespace BlackGui { namespace Models { - //! Airport list model - class BLACKGUI_EXPORT CAircraftIcaoCodeListModel : public CListModelBase + class BLACKGUI_EXPORT CAircraftIcaoCodeListModel : + public CListModelBase { - public: - //! Constructor explicit CAircraftIcaoCodeListModel(QObject *parent = nullptr); diff --git a/src/blackgui/models/aircraftmodellistmodel.cpp b/src/blackgui/models/aircraftmodellistmodel.cpp index 27cb4f2c8..b31ee9d1a 100644 --- a/src/blackgui/models/aircraftmodellistmodel.cpp +++ b/src/blackgui/models/aircraftmodellistmodel.cpp @@ -20,7 +20,8 @@ namespace BlackGui { namespace Models { - CAircraftModelListModel::CAircraftModelListModel(AircraftModelMode mode, QObject *parent) : CListModelBase("CAircraftModelListModel", parent) + CAircraftModelListModel::CAircraftModelListModel(AircraftModelMode mode, QObject *parent) : + CListModelBase("CAircraftModelListModel", parent) { this->setAircraftModelMode(mode); diff --git a/src/blackgui/models/aircraftmodellistmodel.h b/src/blackgui/models/aircraftmodellistmodel.h index a7f69bc20..b9fca68d9 100644 --- a/src/blackgui/models/aircraftmodellistmodel.h +++ b/src/blackgui/models/aircraftmodellistmodel.h @@ -22,7 +22,8 @@ namespace BlackGui namespace Models { //! Aircraft model list model - class BLACKGUI_EXPORT CAircraftModelListModel : public CListModelBase + class BLACKGUI_EXPORT CAircraftModelListModel : + public CListModelBase { public: //! How to display diff --git a/src/blackgui/models/airlineicaolistmodel.cpp b/src/blackgui/models/airlineicaolistmodel.cpp index ee79a3062..11562f073 100644 --- a/src/blackgui/models/airlineicaolistmodel.cpp +++ b/src/blackgui/models/airlineicaolistmodel.cpp @@ -20,7 +20,7 @@ namespace BlackGui namespace Models { CAirlineIcaoCodeListModel::CAirlineIcaoCodeListModel(QObject *parent) : - CListModelBase("AircraftIcaoListModel", parent) + CListModelBase("AircraftIcaoListModel", parent) { this->m_columns.addColumn(CColumn::standardString("id", CAirlineIcaoCode::IndexDbIntegerKey, CDefaultFormatter::alignRightVCenter())); this->m_columns.addColumn(CColumn::standardValueObject("ICAO", CAirlineIcaoCode::IndexAirlineDesignator)); diff --git a/src/blackgui/models/airlineicaolistmodel.h b/src/blackgui/models/airlineicaolistmodel.h index 1be03651f..536f33411 100644 --- a/src/blackgui/models/airlineicaolistmodel.h +++ b/src/blackgui/models/airlineicaolistmodel.h @@ -22,7 +22,7 @@ namespace BlackGui namespace Models { //! Airport list model - class BLACKGUI_EXPORT CAirlineIcaoCodeListModel : public CListModelBase + class BLACKGUI_EXPORT CAirlineIcaoCodeListModel : public CListModelBase { public: //! Constructor diff --git a/src/blackgui/models/airportlistmodel.cpp b/src/blackgui/models/airportlistmodel.cpp index d2e043210..4f93b3e95 100644 --- a/src/blackgui/models/airportlistmodel.cpp +++ b/src/blackgui/models/airportlistmodel.cpp @@ -21,7 +21,7 @@ namespace BlackGui namespace Models { CAirportListModel::CAirportListModel(QObject *parent) : - CListModelBase("AirportListModel", parent) + CListModelBase("AirportListModel", parent) { this->m_columns.addColumn(CColumn::standardValueObject("ICAO", CAirport::IndexIcao)); this->m_columns.addColumn(CColumn("distance", CAirport::IndexDistanceToOwnAircraft, new CAirspaceDistanceFormatter())); diff --git a/src/blackgui/models/airportlistmodel.h b/src/blackgui/models/airportlistmodel.h index 92bf6b7c9..b3f3072ed 100644 --- a/src/blackgui/models/airportlistmodel.h +++ b/src/blackgui/models/airportlistmodel.h @@ -22,7 +22,8 @@ namespace BlackGui namespace Models { //! Airport list model - class BLACKGUI_EXPORT CAirportListModel : public CListModelBase + class BLACKGUI_EXPORT CAirportListModel : + public CListModelBase { public: //! Constructor diff --git a/src/blackgui/models/countrylistmodel.cpp b/src/blackgui/models/countrylistmodel.cpp index 2fb9887bb..fb080cd63 100644 --- a/src/blackgui/models/countrylistmodel.cpp +++ b/src/blackgui/models/countrylistmodel.cpp @@ -18,7 +18,7 @@ namespace BlackGui namespace Models { CCountryListModel::CCountryListModel(QObject *parent) : - CListModelBase("CountryListModel", parent) + CListModelBase("CountryListModel", parent) { CColumn col("country", CCountry::IndexIcon); col.setSortPropertyIndex(CCountry::IndexIsoCode); diff --git a/src/blackgui/models/countrylistmodel.h b/src/blackgui/models/countrylistmodel.h index ca28ecf51..9638a970f 100644 --- a/src/blackgui/models/countrylistmodel.h +++ b/src/blackgui/models/countrylistmodel.h @@ -22,9 +22,9 @@ namespace BlackGui namespace Models { //! Country list model - class BLACKGUI_EXPORT CCountryListModel : public CListModelBase + class BLACKGUI_EXPORT CCountryListModel : + public CListModelBase { - public: //! Constructor explicit CCountryListModel(QObject *parent = nullptr); @@ -32,6 +32,6 @@ namespace BlackGui //! Destructor virtual ~CCountryListModel() {} }; - } -} + } // ns +} // ns #endif // guard diff --git a/src/blackgui/models/distributorlistmodel.h b/src/blackgui/models/distributorlistmodel.h index 56c5ce344..c1b3c5d96 100644 --- a/src/blackgui/models/distributorlistmodel.h +++ b/src/blackgui/models/distributorlistmodel.h @@ -22,7 +22,8 @@ namespace BlackGui namespace Models { //! Distributor list model - class BLACKGUI_EXPORT CDistributorListModel : public CListModelBase + class BLACKGUI_EXPORT CDistributorListModel : + public CListModelBase { public: diff --git a/src/blackgui/models/listmodelbase.cpp b/src/blackgui/models/listmodelbase.cpp index ce8097ece..ad38550bb 100644 --- a/src/blackgui/models/listmodelbase.cpp +++ b/src/blackgui/models/listmodelbase.cpp @@ -16,10 +16,13 @@ #include "blackmisc/variant.h" #include "blackmisc/json.h" #include "blackmisc/blackmiscfreefunctions.h" +#include "blackmisc/logmessage.h" +#include "blackmisc/comparefunctions.h" #include #include using namespace BlackMisc; +using namespace BlackMisc::Aviation; namespace BlackGui { @@ -160,23 +163,23 @@ namespace BlackGui this->setObjectName(translationContext); } - template - int CListModelBase::rowCount(const QModelIndex &parentIndex) const + template + int CListModelBase::rowCount(const QModelIndex &parentIndex) const { Q_UNUSED(parentIndex); return this->getContainerOrFilteredContainer().size(); } - template - bool CListModelBase::isValidIndex(const QModelIndex &index) const + template + bool CListModelBase::isValidIndex(const QModelIndex &index) const { if (!index.isValid()) { return false; } return (index.row() >= 0 && index.row() < this->rowCount(index) && index.column() >= 0 && index.column() < this->columnCount(index)); } - template - QVariant CListModelBase::data(const QModelIndex &index, int role) const + template + QVariant CListModelBase::data(const QModelIndex &index, int role) const { // check / init if (!this->isValidIndex(index)) { return QVariant(); } @@ -190,8 +193,8 @@ namespace BlackGui return formatter->data(role, obj.propertyByIndex(propertyIndex)).getQVariant(); } - template - bool CListModelBase::setData(const QModelIndex &index, const QVariant &value, int role) + template + bool CListModelBase::setData(const QModelIndex &index, const QVariant &value, int role) { Qt::ItemDataRole dataRole = static_cast(role); if (!(dataRole == Qt::UserRole || dataRole == Qt::EditRole)) @@ -234,8 +237,8 @@ namespace BlackGui return false; } - template - int CListModelBase::update(const ContainerType &container, bool sort) + template + int CListModelBase::update(const ContainerType &container, bool sort) { if (m_modelDestroyed) { return 0; } @@ -262,8 +265,8 @@ namespace BlackGui return newSize; } - template - void CListModelBase::update(const QModelIndex &index, const ObjectType &object) + template + void CListModelBase::update(const QModelIndex &index, const ObjectType &object) { if (m_modelDestroyed) { return; } if (index.row() >= this->m_container.size()) { return; } @@ -274,14 +277,14 @@ namespace BlackGui emit this->dataChanged(i1, i2); // which range has been changed } - template - void CListModelBase::update(int rowIndex, const ObjectType &object) + template + void CListModelBase::update(int rowIndex, const ObjectType &object) { this->update(this->index(rowIndex, 0), object); } - template - CWorker *CListModelBase::updateAsync(const ContainerType &container, bool sort) + template + CWorker *CListModelBase::updateAsync(const ContainerType &container, bool sort) { Q_UNUSED(sort); if (m_modelDestroyed) { return nullptr; } @@ -291,7 +294,7 @@ namespace BlackGui { return this->sortContainerByColumn(container, sortColumn, sortOrder); }); - worker->thenWithResult(this, [this](const ContainerType &sortedContainer) + worker->thenWithResult(this, [this](const ContainerType & sortedContainer) { if (this->m_modelDestroyed) { return; } this->ps_updateContainer(CVariant::from(sortedContainer), false); @@ -300,8 +303,8 @@ namespace BlackGui return worker; } - template - void CListModelBase::updateContainerMaybeAsync(const ContainerType &container, bool sort) + template + void CListModelBase::updateContainerMaybeAsync(const ContainerType &container, bool sort) { if (m_modelDestroyed) { return; } if (container.size() > asyncThreshold && sort) @@ -315,14 +318,14 @@ namespace BlackGui } } - template - bool CListModelBase::hasFilter() const + template + bool CListModelBase::hasFilter() const { return m_filter && m_filter->isValid() ? true : false; } - template - void CListModelBase::removeFilter() + template + void CListModelBase::removeFilter() { if (!this->hasFilter()) { return; } this->m_filter.reset(nullptr); @@ -332,8 +335,8 @@ namespace BlackGui this->emitRowCountChanged(); } - template - void CListModelBase::takeFilterOwnership(std::unique_ptr > &filter) + template + void CListModelBase::takeFilterOwnership(std::unique_ptr > &filter) { if (!filter) { @@ -354,8 +357,8 @@ namespace BlackGui } } - template - const ObjectType &CListModelBase::at(const QModelIndex &index) const + template + const ObjectType &CListModelBase::at(const QModelIndex &index) const { if (index.row() < 0 || index.row() >= this->rowCount()) { @@ -368,14 +371,14 @@ namespace BlackGui } } - template - const ContainerType &CListModelBase::getContainer() const + template + const ContainerType &CListModelBase::getContainer() const { return this->m_container; } - template - void CListModelBase::push_back(const ObjectType &object) + template + void CListModelBase::push_back(const ObjectType &object) { beginInsertRows(QModelIndex(), this->m_container.size(), this->m_container.size()); this->m_container.push_back(object); @@ -384,8 +387,8 @@ namespace BlackGui this->emitRowCountChanged(); } - template - void CListModelBase::insert(const ObjectType &object) + template + void CListModelBase::insert(const ObjectType &object) { beginInsertRows(QModelIndex(), 0, 0); this->m_container.insert(this->m_container.begin(), object); @@ -400,8 +403,8 @@ namespace BlackGui this->emitRowCountChanged(); } - template - void CListModelBase::remove(const ObjectType &object) + template + void CListModelBase::remove(const ObjectType &object) { int oldSize = this->m_container.size(); beginRemoveRows(QModelIndex(), 0, 0); @@ -420,8 +423,8 @@ namespace BlackGui } } - template - void CListModelBase::clear() + template + void CListModelBase::clear() { beginResetModel(); this->m_container.clear(); @@ -430,21 +433,21 @@ namespace BlackGui this->emitRowCountChanged(); } - template - bool CListModelBase::isEmpty() const + template + bool CListModelBase::isEmpty() const { return this->m_container.isEmpty(); } - template - int CListModelBase::performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) + template + int CListModelBase::performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) { ContainerType c(variant.to()); return this->update(c, sort); } - template - const ContainerType &CListModelBase::getContainerOrFilteredContainer() const + template + const ContainerType &CListModelBase::getContainerOrFilteredContainer() const { if (!this->hasFilter()) { @@ -453,8 +456,8 @@ namespace BlackGui return m_containerFiltered; } - template - void CListModelBase::updateFilteredContainer() + template + void CListModelBase::updateFilteredContainer() { if (this->hasFilter()) { @@ -466,21 +469,21 @@ namespace BlackGui } } - template - void CListModelBase::emitRowCountChanged() + template + void CListModelBase::emitRowCountChanged() { int n = this->getContainerOrFilteredContainer().size(); emit this->rowCountChanged(n, this->hasFilter()); } - template - void CListModelBase::sort() + template + void CListModelBase::sort() { this->sort(this->getSortColumn(), this->getSortOrder()); } - template - void CListModelBase::sort(int column, Qt::SortOrder order) + template + void CListModelBase::sort(int column, Qt::SortOrder order) { if (column == this->m_sortedColumn && order == this->m_sortOrder) { return; } @@ -496,8 +499,8 @@ namespace BlackGui this->updateContainerMaybeAsync(this->m_container, true); } - template - void CListModelBase::truncate(int maxNumber, bool forceSort) + template + void CListModelBase::truncate(int maxNumber, bool forceSort) { if (this->rowCount() <= maxNumber) { return; } if (forceSort) @@ -509,8 +512,8 @@ namespace BlackGui this->updateContainerMaybeAsync(container, false); } - template - ContainerType CListModelBase::sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const + template + ContainerType CListModelBase::sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const { if (m_modelDestroyed) { return container; } if (container.size() < 2 || !this->m_columns.isSortable(column)) @@ -527,19 +530,23 @@ namespace BlackGui } // sort the values + std::integral_constant marker {}; const auto p = [ = ](const ObjectType & a, const ObjectType & b) -> bool { - BlackMisc::CVariant aQv = a.propertyByIndex(propertyIndex); - BlackMisc::CVariant bQv = b.propertyByIndex(propertyIndex); - return (order == Qt::AscendingOrder) ? (aQv < bQv) : (bQv < aQv); + return Private::compareForModelSort(a, b, order, propertyIndex, marker); }; + //! \todo Time measurement will be removed + QTime t; + t.start(); const ContainerType sorted = container.sorted(p); + int te = t.elapsed(); + CLogMessage(this).info("Sorted %1 in %2") << typeid(ObjectType).name() << te; return sorted; } - template - QMimeData *CListModelBase::mimeData(const QModelIndexList &indexes) const + template + QMimeData *CListModelBase::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); if (indexes.isEmpty()) { return mimeData; } @@ -567,22 +574,22 @@ namespace BlackGui // see here for the reason of thess forward instantiations // http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; - template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; + template class CListModelBase; } // namespace } // namespace diff --git a/src/blackgui/models/listmodelbase.h b/src/blackgui/models/listmodelbase.h index bef1010cd..2bb0349ac 100644 --- a/src/blackgui/models/listmodelbase.h +++ b/src/blackgui/models/listmodelbase.h @@ -16,11 +16,11 @@ #include "blackgui/models/columns.h" #include "blackgui/models/modelfilter.h" #include "blackmisc/worker.h" -#include "blackmisc/propertyindex.h" #include #include #include #include +#include namespace BlackGui { @@ -128,9 +128,8 @@ namespace BlackGui }; //! List model - template class CListModelBase : public CListModelBaseNonTemplate + template class CListModelBase : public CListModelBaseNonTemplate { - public: //! Destructor virtual ~CListModelBase() {} @@ -249,6 +248,28 @@ namespace BlackGui ContainerType m_containerFiltered; //!< cache for filtered container data }; + namespace Private + { + //! Sort with compare function + template + bool compareForModelSort(const ObjectType &a, const ObjectType &b, Qt::SortOrder order, const BlackMisc::CPropertyIndex &index, std::true_type) + { + int c = a.comparePropertyByIndex(b, index); + if (c == 0) { return false; } + return (order == Qt::AscendingOrder) ? (c > 0) : (c < 0); + } + + //! Sort without compare function + template + bool compareForModelSort(const ObjectType &a, const ObjectType &b, Qt::SortOrder order, const BlackMisc::CPropertyIndex &index, std::false_type) + { + Q_UNUSED(index); + BlackMisc::CVariant aQv = a.propertyByIndex(index); + BlackMisc::CVariant bQv = b.propertyByIndex(index); + return (order == Qt::AscendingOrder) ? (aQv < bQv) : (bQv < aQv); + } + + } // namespace } // namespace } // namespace #endif // guard diff --git a/src/blackgui/models/liverylistmodel.h b/src/blackgui/models/liverylistmodel.h index a60ca200a..f748edc9b 100644 --- a/src/blackgui/models/liverylistmodel.h +++ b/src/blackgui/models/liverylistmodel.h @@ -22,7 +22,8 @@ namespace BlackGui namespace Models { //! Distributor list model - class BLACKGUI_EXPORT CLiveryListModel : public CListModelBase + class BLACKGUI_EXPORT CLiveryListModel : + public CListModelBase { public: diff --git a/src/blackgui/models/simulatedaircraftlistmodel.h b/src/blackgui/models/simulatedaircraftlistmodel.h index cb250c2b0..2b2fd0d9d 100644 --- a/src/blackgui/models/simulatedaircraftlistmodel.h +++ b/src/blackgui/models/simulatedaircraftlistmodel.h @@ -24,9 +24,9 @@ namespace BlackGui { //! Aircraft list model - class BLACKGUI_EXPORT CSimulatedAircraftListModel : public CListModelBase + class BLACKGUI_EXPORT CSimulatedAircraftListModel : + public CListModelBase { - public: //! Model modes enum AircraftMode diff --git a/src/blackgui/models/userlistmodel.cpp b/src/blackgui/models/userlistmodel.cpp index b50aaff1f..b980682da 100644 --- a/src/blackgui/models/userlistmodel.cpp +++ b/src/blackgui/models/userlistmodel.cpp @@ -23,7 +23,7 @@ namespace BlackGui * Constructor */ CUserListModel::CUserListModel(UserMode userMode, QObject *parent) : - CListModelBase("ModelUserList", parent), m_userMode(NotSet) + CListModelBase("ModelUserList", parent), m_userMode(NotSet) { this->setUserMode(userMode); diff --git a/src/blackgui/models/userlistmodel.h b/src/blackgui/models/userlistmodel.h index 7785fd9b2..aeeabddf0 100644 --- a/src/blackgui/models/userlistmodel.h +++ b/src/blackgui/models/userlistmodel.h @@ -24,9 +24,9 @@ namespace BlackGui /*! * User list model */ - class BLACKGUI_EXPORT CUserListModel : public CListModelBase + class BLACKGUI_EXPORT CUserListModel : + public CListModelBase { - public: //! What level of detail diff --git a/src/blackmisc/aviation/aircrafticaocode.cpp b/src/blackmisc/aviation/aircrafticaocode.cpp index fabc9eb28..b1305d08d 100644 --- a/src/blackmisc/aviation/aircrafticaocode.cpp +++ b/src/blackmisc/aviation/aircrafticaocode.cpp @@ -13,6 +13,7 @@ #include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/variant.h" #include "blackmisc/datastoreutility.h" +#include "blackmisc/comparefunctions.h" #include #include #include @@ -280,6 +281,36 @@ namespace BlackMisc } } + int CAircraftIcaoCode::comparePropertyByIndex(const CAircraftIcaoCode &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return m_designator.compare(compareValue.getDesignator(), Qt::CaseInsensitive); } + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(compareValue, index);} + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexAircraftDesignator: + return m_designator.compare(compareValue.getDesignator(), Qt::CaseInsensitive); + case IndexCombinedAircraftType: + return m_combinedType.compare(compareValue.getCombinedType(), Qt::CaseInsensitive); + case IndexModelDescription: + return m_modelDescription.compare(compareValue.getModelDescription(), Qt::CaseInsensitive); + case IndexManufacturer: + return m_manufacturer.compare(compareValue.getManufacturer(), Qt::CaseInsensitive); + case IndexWtc: + return m_wtc.compare(compareValue.getWtc(), Qt::CaseInsensitive); + case IndexIsLegacy: + return Compare::compare(m_legacy, compareValue.isLegacyAircraft()); + case IndexIsMilitary: + return Compare::compare(m_military, compareValue.isMilitary()); + case IndexRank: + return Compare::compare(m_rank, compareValue.getRank()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison"); + return 0; + } + bool CAircraftIcaoCode::isValidDesignator(const QString &designator) { if (designator.length() < 2 || designator.length() > 5) { return false; } diff --git a/src/blackmisc/aviation/aircrafticaocode.h b/src/blackmisc/aviation/aircrafticaocode.h index 558d6b149..5f5f5440d 100644 --- a/src/blackmisc/aviation/aircrafticaocode.h +++ b/src/blackmisc/aviation/aircrafticaocode.h @@ -168,6 +168,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CAircraftIcaoCode &compareValue, const CPropertyIndex &index) const; + //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/aviation/aircraftparts.cpp b/src/blackmisc/aviation/aircraftparts.cpp index e6166233d..0a883624b 100644 --- a/src/blackmisc/aviation/aircraftparts.cpp +++ b/src/blackmisc/aviation/aircraftparts.cpp @@ -8,12 +8,14 @@ */ #include "aircraftparts.h" +#include "blackmisc/comparefunctions.h" + +using namespace BlackMisc; namespace BlackMisc { namespace Aviation { - QString CAircraftParts::convertToQString(bool i18n) const { QString s; @@ -34,10 +36,7 @@ namespace BlackMisc CVariant CAircraftParts::propertyByIndex(const BlackMisc::CPropertyIndex &index) const { if (index.isMyself()) { return CVariant::from(*this); } - if (ITimestampBased::canHandleIndex(index)) - { - return ITimestampBased::propertyByIndex(index); - } + if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::propertyByIndex(index); } ColumnIndex i = index.frontCasted(); switch (i) @@ -60,11 +59,7 @@ namespace BlackMisc void CAircraftParts::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index) { if (index.isMyself()) { (*this) = variant.to(); return; } - if (ITimestampBased::canHandleIndex(index)) - { - ITimestampBased::setPropertyByIndex(variant, index); - return; - } + if (ITimestampBased::canHandleIndex(index)) { ITimestampBased::setPropertyByIndex(variant, index); return; } ColumnIndex i = index.frontCasted(); switch (i) @@ -90,6 +85,31 @@ namespace BlackMisc } } + int CAircraftParts::comparePropertyByIndex(const CAircraftParts &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return ITimestampBased::comparePropertyByIndex(compareValue, CPropertyIndex()); } + if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::comparePropertyByIndex(compareValue, index); } + + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexEngines: + return Compare::compare(this->getEnginesCount(), compareValue.getEnginesCount()); + case IndexFlapsPercentage: + return Compare::compare(this->m_flapsPercentage, compareValue.getFlapsPercent()); + case IndexGearDown: + return Compare::compare(this->m_gearDown, compareValue.isGearDown()); + case IndexLights: + break; + case IndexSpoilersOut: + return Compare::compare(this->m_spoilersOut, compareValue.isSpoilersOut()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison"); + return 0; + } + void CAircraftParts::setAllLightsOn() { m_lights.setAllOn(); diff --git a/src/blackmisc/aviation/aircraftparts.h b/src/blackmisc/aviation/aircraftparts.h index 8c86fe44e..9e080f71c 100644 --- a/src/blackmisc/aviation/aircraftparts.h +++ b/src/blackmisc/aviation/aircraftparts.h @@ -56,6 +56,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CAircraftParts &compareValue, const CPropertyIndex &index) const; + //! Get aircraft lights CAircraftLights getLights() const { return m_lights; } @@ -92,6 +95,9 @@ namespace BlackMisc //! Engine with number CAircraftEngine getEngine(int number) const; + //! Number of engines + int getEnginesCount() const { return m_engines.size(); } + //! Is engine with number 1..n on? bool isEngineOn(int number) const; diff --git a/src/blackmisc/aviation/airlineicaocode.cpp b/src/blackmisc/aviation/airlineicaocode.cpp index 43ab9123e..b345dd63c 100644 --- a/src/blackmisc/aviation/airlineicaocode.cpp +++ b/src/blackmisc/aviation/airlineicaocode.cpp @@ -11,6 +11,7 @@ #include "blackmisc/propertyindex.h" #include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/variant.h" +#include "blackmisc/comparefunctions.h" #include #include @@ -154,6 +155,32 @@ namespace BlackMisc } } + int CAirlineIcaoCode::comparePropertyByIndex(const CAirlineIcaoCode &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return m_designator.compare(compareValue.getDesignator(), Qt::CaseInsensitive); } + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(compareValue, index);} + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexAirlineDesignator: + return this->m_designator.compare(compareValue.getDesignator()); + case IndexAirlineCountry: + return this->m_country.comparePropertyByIndex(compareValue.getCountry(), index.copyFrontRemoved()); + case IndexAirlineName: + return this->m_name.compare(compareValue.getName(), Qt::CaseInsensitive); + case IndexTelephonyDesignator: + return this->m_telephonyDesignator.compare(compareValue.getTelephonyDesignator(), Qt::CaseInsensitive); + case IndexIsVirtualAirline: + return Compare::compare(this->isVirtualAirline(), compareValue.isVirtualAirline()); + case IndexIsOperating: + return Compare::compare(this->isOperating(), compareValue.isOperating()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "No compare function"); + return 0; + } + CStatusMessageList CAirlineIcaoCode::validate() const { static const CLogCategoryList cats(CLogCategoryList(this).join({ CLogCategory::validation() })); diff --git a/src/blackmisc/aviation/airlineicaocode.h b/src/blackmisc/aviation/airlineicaocode.h index b56abbde5..b240b3ac4 100644 --- a/src/blackmisc/aviation/airlineicaocode.h +++ b/src/blackmisc/aviation/airlineicaocode.h @@ -133,6 +133,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CAirlineIcaoCode &compareValue, const CPropertyIndex &index) const; + //! Validate data BlackMisc::CStatusMessageList validate() const; diff --git a/src/blackmisc/aviation/airport.cpp b/src/blackmisc/aviation/airport.cpp index 7c9b6d705..2a21848f9 100644 --- a/src/blackmisc/aviation/airport.cpp +++ b/src/blackmisc/aviation/airport.cpp @@ -100,5 +100,27 @@ namespace BlackMisc } } + int CAirport::comparePropertyByIndex(const CAirport &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return this->m_icao.comparePropertyByIndex(compareValue.getIcao(), index.copyFrontRemoved()); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexIcao: + return this->m_icao.comparePropertyByIndex(compareValue.getIcao(), index.copyFrontRemoved()); + case IndexDescriptiveName: + return this->m_descriptiveName.compare(compareValue.getDescriptiveName(), Qt::CaseInsensitive); + case IndexBearing: + return this->m_bearingToOwnAircraft.comparePropertyByIndex(compareValue.getBearingToOwnAircraft(), index.copyFrontRemoved()); + case IndexPosition: + case IndexDistanceToOwnAircraft: + return this->m_distanceToOwnAircraft.comparePropertyByIndex(compareValue.getDistanceToOwnAircraft(), index.copyFrontRemoved()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed"); + return 0; + } + } // namespace } // namespace diff --git a/src/blackmisc/aviation/airport.h b/src/blackmisc/aviation/airport.h index 830a086e9..cc032d6c3 100644 --- a/src/blackmisc/aviation/airport.h +++ b/src/blackmisc/aviation/airport.h @@ -102,6 +102,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CAirport &compareValue, const CPropertyIndex &index) const; + //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/aviation/airporticaocode.cpp b/src/blackmisc/aviation/airporticaocode.cpp index 0e30ed54c..ff20564f5 100644 --- a/src/blackmisc/aviation/airporticaocode.cpp +++ b/src/blackmisc/aviation/airporticaocode.cpp @@ -10,6 +10,12 @@ namespace BlackMisc return this->m_icaoCode; } + int CAirportIcaoCode::comparePropertyByIndex(const CAirportIcaoCode &compareValue, const CPropertyIndex &index) const + { + Q_UNUSED(index); + return this->m_icaoCode.compare(compareValue.getIcaoCode(), Qt::CaseInsensitive); + } + bool CAirportIcaoCode::equalsString(const QString &icaoCode) const { CAirportIcaoCode other(icaoCode); diff --git a/src/blackmisc/aviation/airporticaocode.h b/src/blackmisc/aviation/airporticaocode.h index 3c17567fa..c385658f1 100644 --- a/src/blackmisc/aviation/airporticaocode.h +++ b/src/blackmisc/aviation/airporticaocode.h @@ -54,6 +54,9 @@ namespace BlackMisc //! \copydoc CValueObject::convertToQString() QString convertToQString(bool i18n = false) const; + //! Compare for index + int comparePropertyByIndex(const CAirportIcaoCode &compareValue, const CPropertyIndex &index) const; + private: BLACK_ENABLE_TUPLE_CONVERSION(CAirportIcaoCode) QString m_icaoCode; diff --git a/src/blackmisc/aviation/callsign.cpp b/src/blackmisc/aviation/callsign.cpp index 32d2a5d56..b3a3a8de8 100644 --- a/src/blackmisc/aviation/callsign.cpp +++ b/src/blackmisc/aviation/callsign.cpp @@ -168,6 +168,25 @@ namespace BlackMisc } } + int CCallsign::comparePropertyByIndex(const CCallsign &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return this->m_callsign.compare(compareValue.m_callsign, Qt::CaseInsensitive); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexCallsignString: + return this->m_callsign.compare(compareValue.m_callsign, Qt::CaseInsensitive); + case IndexCallsignStringAsSet: + return this->m_callsignAsSet.compare(compareValue.m_callsignAsSet, Qt::CaseInsensitive); + case IndexTelephonyDesignator: + return this->m_telephonyDesignator.compare(compareValue.m_telephonyDesignator, Qt::CaseInsensitive); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed"); + return 0; + } + bool CCallsign::isValidCallsign(const QString &callsign) { // We allow all number callsigns diff --git a/src/blackmisc/aviation/callsign.h b/src/blackmisc/aviation/callsign.h index 98df9604c..2f6251251 100644 --- a/src/blackmisc/aviation/callsign.h +++ b/src/blackmisc/aviation/callsign.h @@ -117,6 +117,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CCallsign &compareValue, const CPropertyIndex &index) const; + //! Valid callsign? static bool isValidCallsign(const QString &callsign); diff --git a/src/blackmisc/aviation/livery.cpp b/src/blackmisc/aviation/livery.cpp index 139dbeb94..4403f8cb3 100644 --- a/src/blackmisc/aviation/livery.cpp +++ b/src/blackmisc/aviation/livery.cpp @@ -12,7 +12,7 @@ #include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/propertyindex.h" #include "blackmisc/variant.h" - +#include "blackmisc/comparefunctions.h" using namespace BlackMisc; using namespace BlackMisc::PhysicalQuantities; @@ -228,6 +228,30 @@ namespace BlackMisc } } + int CLivery::comparePropertyByIndex(const CLivery &compareValue, const CPropertyIndex &index) const + { + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexDescription: + return this->m_description.compare(compareValue.getDescription(), Qt::CaseInsensitive); + case IndexAirlineIcaoCode: + return this->m_airline.comparePropertyByIndex(compareValue.getAirlineIcaoCode(), index.copyFrontRemoved()); + case IndexColorFuselage: + return this->m_colorFuselage.comparePropertyByIndex(compareValue.getColorFuselage(), index.copyFrontRemoved()); + case IndexColorTail: + return this->m_colorTail.comparePropertyByIndex(compareValue.getColorTail(), index.copyFrontRemoved()); + case IndexCombinedCode: + return this->getCombinedCode().compare(compareValue.getCombinedCode()); + case IndexIsMilitary: + return Compare::compare(this->isMilitary(), compareValue.isMilitary()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "No compare function"); + return 0; + } + void CLivery::updateMissingParts(const CLivery &otherLivery) { if (!this->m_colorFuselage.isValid()) { this->setColorFuselage(otherLivery.getColorFuselage()); } diff --git a/src/blackmisc/aviation/livery.h b/src/blackmisc/aviation/livery.h index bee826f71..d26edd1d1 100644 --- a/src/blackmisc/aviation/livery.h +++ b/src/blackmisc/aviation/livery.h @@ -112,6 +112,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CLivery &compareValue, const CPropertyIndex &index) const; + //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/comparefunctions.cpp b/src/blackmisc/comparefunctions.cpp new file mode 100644 index 000000000..6ee020468 --- /dev/null +++ b/src/blackmisc/comparefunctions.cpp @@ -0,0 +1,42 @@ +/* Copyright (C) 2015 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "comparefunctions.h" + +namespace BlackMisc +{ + namespace Compare + { + int compare(bool a, bool b) + { + if ((a && b) || (!a && !b)) return 0; + if (a && !b) return 10; + return -10; + } + + int compare(int a, int b) + { + if (a == b) return 0; + return a < b ? -10 : 10; + } + + int compare(qint64 a, qint64 b) + { + if (a == b) return 0; + return a < b ? -10 : 10; + } + + int compare(double a, double b) + { + if (a == b) return 0; + return a < b ? -10 : 10; + } + + } // ns +} // ns diff --git a/src/blackmisc/comparefunctions.h b/src/blackmisc/comparefunctions.h new file mode 100644 index 000000000..25fe97a4f --- /dev/null +++ b/src/blackmisc/comparefunctions.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_COMPAREFUNCTIONS_H +#define BLACKMISC_COMPAREFUNCTIONS_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/variant.h" + +namespace BlackMisc +{ + namespace Compare + { + //! Compare bool + BLACKMISC_EXPORT int compare(bool a, bool b); + + //! Compare int + BLACKMISC_EXPORT int compare(int a, int b); + + //! Compare qint64 + BLACKMISC_EXPORT int compare(qint64 a, qint64 b); + + //! Compare qint64 + BLACKMISC_EXPORT int compare(double a, double b); + } // ns +} // ns + +#endif diff --git a/src/blackmisc/country.cpp b/src/blackmisc/country.cpp index 794b90c25..77e3f8366 100644 --- a/src/blackmisc/country.cpp +++ b/src/blackmisc/country.cpp @@ -130,6 +130,23 @@ namespace BlackMisc } } + int CCountry::comparePropertyByIndex(const CCountry &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return getIsoCode().compare(compareValue.getIsoCode(), Qt::CaseInsensitive); } + if (IDatastoreObjectWithStringKey::canHandleIndex(index)) { return IDatastoreObjectWithStringKey::comparePropertyByIndex(compareValue, index);} + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexIsoCode: + return getIsoCode().compare(compareValue.getIsoCode(), Qt::CaseInsensitive); + case IndexName: + return getName().compare(compareValue.getName(), Qt::CaseInsensitive); + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison possible"); + } + return 0; + } + CCountry CCountry::fromDatabaseJson(const QJsonObject &json, const QString &prefix) { if (!existsKey(json, prefix)) diff --git a/src/blackmisc/country.h b/src/blackmisc/country.h index 3eac021d4..35bd308c0 100644 --- a/src/blackmisc/country.h +++ b/src/blackmisc/country.h @@ -81,6 +81,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CCountry &compareValue, const CPropertyIndex &index) const; + //! From our database JSON format static CCountry fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString()); diff --git a/src/blackmisc/datastore.cpp b/src/blackmisc/datastore.cpp index 0351dbc6a..ff6af0ee4 100644 --- a/src/blackmisc/datastore.cpp +++ b/src/blackmisc/datastore.cpp @@ -10,6 +10,7 @@ #include "blackmisc/datastore.h" #include "blackmisc/datastoreutility.h" #include "blackmisc/blackmiscfreefunctions.h" +#include "blackmisc/comparefunctions.h" namespace BlackMisc { @@ -80,6 +81,21 @@ namespace BlackMisc } } + int IDatastoreObjectWithIntegerKey::comparePropertyByIndex(const IDatastoreObjectWithIntegerKey &compareValue, const CPropertyIndex &index) const + { + if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::comparePropertyByIndex(compareValue, index); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexDbIntegerKey: + return Compare::compare(this->m_dbKey, compareValue.getDbKey()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed"); + return 0; + } + bool IDatastoreObjectWithIntegerKey::canHandleIndex(const BlackMisc::CPropertyIndex &index) { if (ITimestampBased::canHandleIndex(index)) { return true;} @@ -132,8 +148,24 @@ namespace BlackMisc } } + int IDatastoreObjectWithStringKey::comparePropertyByIndex(const IDatastoreObjectWithStringKey &compareValue, const CPropertyIndex &index) const + { + if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::comparePropertyByIndex(compareValue, index); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexDbStringKey: + return this->m_dbKey.compare(compareValue.getDbKey()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed"); + return 0; + } + bool IDatastoreObjectWithStringKey::canHandleIndex(const CPropertyIndex &index) { + if (index.isEmpty()) { return false; } if (ITimestampBased::canHandleIndex(index)) { return true;} int i = index.frontCasted(); return (i >= static_cast(IndexDbStringKey)) && (i <= static_cast(IndexDbStringKey)); diff --git a/src/blackmisc/datastore.h b/src/blackmisc/datastore.h index 5c75b1a25..c41524357 100644 --- a/src/blackmisc/datastore.h +++ b/src/blackmisc/datastore.h @@ -68,6 +68,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare by index + int comparePropertyByIndex(const IDatastoreObjectWithIntegerKey &compareValue, const CPropertyIndex &index) const; + //! Can given index be handled? static bool canHandleIndex(const BlackMisc::CPropertyIndex &index); @@ -114,6 +117,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare by index + int comparePropertyByIndex(const IDatastoreObjectWithStringKey &compareValue, const BlackMisc::CPropertyIndex &index) const; + //! Can given index be handled static bool canHandleIndex(const BlackMisc::CPropertyIndex &index); diff --git a/src/blackmisc/network/user.cpp b/src/blackmisc/network/user.cpp index 8397c77a0..5c07ea114 100644 --- a/src/blackmisc/network/user.cpp +++ b/src/blackmisc/network/user.cpp @@ -218,5 +218,30 @@ namespace BlackMisc break; } } + + int CUser::comparePropertyByIndex(const CUser &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return this->getRealName().compare(compareValue.getRealName(), Qt::CaseInsensitive); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexEmail: + return this->m_email.compare(compareValue.getEmail(), Qt::CaseInsensitive); + case IndexId: + return this->m_id.compare(compareValue.getId(), Qt::CaseInsensitive); + case IndexPassword: + break; + case IndexRealName: + return this->m_realname.compare(compareValue.getRealName(), Qt::CaseInsensitive); + case IndexHomebase: + return this->m_homebase.comparePropertyByIndex(compareValue.getHomebase(), index.copyFrontRemoved()); + case IndexCallsign: + return this->m_callsign.comparePropertyByIndex(compareValue.getCallsign(), index.copyFrontRemoved()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "compare failed"); + return 0; + } } // namespace } // namespace diff --git a/src/blackmisc/network/user.h b/src/blackmisc/network/user.h index fa03edbaf..4f76c1a59 100644 --- a/src/blackmisc/network/user.h +++ b/src/blackmisc/network/user.h @@ -122,6 +122,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare by index + int comparePropertyByIndex(const CUser &compareValue, const CPropertyIndex &index) const; + //! This and another user exchange missing data, This user has priority and overrides first. void syncronizeData(CUser &otherUser); diff --git a/src/blackmisc/pq/physicalquantity.cpp b/src/blackmisc/pq/physicalquantity.cpp index 3ec880204..12ca9dc2c 100644 --- a/src/blackmisc/pq/physicalquantity.cpp +++ b/src/blackmisc/pq/physicalquantity.cpp @@ -8,6 +8,7 @@ */ #include "blackmisc/pq/pq.h" +#include "blackmisc/comparefunctions.h" #include "blackmisc/blackmiscfreefunctions.h" #include @@ -15,7 +16,6 @@ namespace BlackMisc { namespace PhysicalQuantities { - template MU CPhysicalQuantity::getUnit() const { @@ -394,6 +394,22 @@ namespace BlackMisc } } + template + int CPhysicalQuantity::comparePropertyByIndex(const PQ &pq, const CPropertyIndex &index) const + { + if (index.isMyself()) { return compareImpl(*derived(), pq); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexValue: + return Compare::compare(this->m_value, pq.m_value); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison"); + return 0; + } + template int CPhysicalQuantity::compareImpl(const PQ &a, const PQ &b) { diff --git a/src/blackmisc/pq/physicalquantity.h b/src/blackmisc/pq/physicalquantity.h index 6e9a4b223..e4b06ab51 100644 --- a/src/blackmisc/pq/physicalquantity.h +++ b/src/blackmisc/pq/physicalquantity.h @@ -211,6 +211,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare + int comparePropertyByIndex(const PQ &pq, const CPropertyIndex &index) const; + //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/propertyindex.cpp b/src/blackmisc/propertyindex.cpp index 1006da176..494424f90 100644 --- a/src/blackmisc/propertyindex.cpp +++ b/src/blackmisc/propertyindex.cpp @@ -36,12 +36,11 @@ namespace BlackMisc CPropertyIndex CPropertyIndex::copyFrontRemoved() const { - Q_ASSERT(!this->isEmpty()); + Q_ASSERT_X(!this->isEmpty(), Q_FUNC_INFO, "Empty index"); if (this->isEmpty()) { return CPropertyIndex(); } - QList l = this->indexList(); - l.removeAt(0); - CPropertyIndex pi(l); - return pi; + int p = this->m_indexString.indexOf(';'); + if (p < 0) { return CPropertyIndex(); } + return CPropertyIndex(this->m_indexString.mid(p + 1)); } bool CPropertyIndex::isNested() const @@ -102,7 +101,7 @@ namespace BlackMisc QList list; if (this->m_indexString.isEmpty()) { return list; } QStringList indexes = this->m_indexString.split(';'); - foreach(QString index, indexes) + for (const QString &index : indexes) { if (index.isEmpty()) { continue; } bool ok; @@ -126,4 +125,22 @@ namespace BlackMisc return this->indexList().contains(index); } + int CPropertyIndex::frontToInt() const + { + Q_ASSERT_X(!this->isEmpty(), Q_FUNC_INFO, "No index"); + int f = -1; + bool ok; + int p = this->m_indexString.indexOf(';'); + if (p < 0) + { + f = this->m_indexString.toInt(&ok); + } + else + { + f = this->m_indexString.left(p).toInt(&ok); + } + Q_ASSERT_X(ok && f >= 0, Q_FUNC_INFO, "Invalid index"); + return f; + } + } // namespace diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h index 788074aae..c6ad6eb04 100644 --- a/src/blackmisc/propertyindex.h +++ b/src/blackmisc/propertyindex.h @@ -22,7 +22,6 @@ namespace BlackMisc { - /*! * Property index. The index can be nested, that's why it is a sequence * (e.g. PropertyIndexPilot, PropertyIndexRealname). @@ -136,13 +135,14 @@ namespace BlackMisc return contains(static_cast(ev)); } - //! First element casted to given type, usually then PropertIndex enum + //! Front to integer + int frontToInt() const; + + //! First element casted to given type, usually the PropertIndex enum template CastType frontCasted() const { - QList l = indexList(); - Q_ASSERT(!l.isEmpty()); - int f = l.isEmpty() ? 0 : l.first(); - return static_cast(f); + static_assert(std::is_enum::value || std::is_integral::value, "CastType must be an enum or integer"); + return static_cast(frontToInt()); } //! Compare with index given by enum diff --git a/src/blackmisc/rgbcolor.cpp b/src/blackmisc/rgbcolor.cpp index 0acacff41..b80b2bf81 100644 --- a/src/blackmisc/rgbcolor.cpp +++ b/src/blackmisc/rgbcolor.cpp @@ -9,11 +9,13 @@ #include "blackmisc/rgbcolor.h" #include "blackmiscfreefunctions.h" +#include "comparefunctions.h" #include +using namespace BlackMisc; + namespace BlackMisc { - CRgbColor::CRgbColor(const QString &color, bool isName) { this->setByString(color, isName); @@ -217,6 +219,28 @@ namespace BlackMisc } } + int CRgbColor::comparePropertyByIndex(const CRgbColor &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return this->hex().compare(compareValue.hex(), Qt::CaseInsensitive); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexBlue: + return Compare::compare(this->m_b, compareValue.m_b); + case IndexRed: + return Compare::compare(this->m_r, compareValue.m_r); + case IndexGreen: + return Compare::compare(this->m_g, compareValue.m_g); + case IndexWebHex: + this->hex().compare(compareValue.hex(), Qt::CaseInsensitive); + break; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Missing compare"); + break; + } + return 0; + } + double CRgbColor::colorRange() const { if (!this->isValid()) { return 255; } diff --git a/src/blackmisc/rgbcolor.h b/src/blackmisc/rgbcolor.h index 7285a63bc..26e6113c8 100644 --- a/src/blackmisc/rgbcolor.h +++ b/src/blackmisc/rgbcolor.h @@ -106,6 +106,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CRgbColor &compareValue, const CPropertyIndex &index) const; + private: BLACK_ENABLE_TUPLE_CONVERSION(CRgbColor) int m_r = -1; diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index b7e17c55c..14ad09bbd 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -10,10 +10,12 @@ #include "aircraftmodel.h" #include "distributor.h" #include "blackmisc/datastoreutility.h" +#include "blackmisc/comparefunctions.h" #include #include #include +using namespace BlackMisc; using namespace BlackMisc::Aviation; namespace BlackMisc @@ -140,6 +142,42 @@ namespace BlackMisc } } + int CAircraftModel::comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const + { + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::comparePropertyByIndex(compareValue, index);} + if (index.isMyself()) { return this->m_modelString.compare(compareValue.getModelString(), Qt::CaseInsensitive); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexModelString: + return this->m_modelString.compare(compareValue.getModelString(), Qt::CaseInsensitive); + case IndexAircraftIcaoCode: + return this->m_aircraftIcao.comparePropertyByIndex(compareValue.getAircraftIcaoCode(), index.copyFrontRemoved()); + case IndexLivery: + return this->m_livery.comparePropertyByIndex(compareValue.getLivery(), index.copyFrontRemoved()); + case IndexDistributor: + return this->m_distributor.comparePropertyByIndex(compareValue.getDistributor(), index.copyFrontRemoved()); + case IndexDescription: + return this->m_description.compare(compareValue.getDescription(), Qt::CaseInsensitive); + case IndexSimulatorInfo: + return this->m_simulator.comparePropertyByIndex(compareValue.getSimulatorInfo(), index.copyFrontRemoved()); + case IndexName: + return this->m_modelName.compare(compareValue.getName(), Qt::CaseInsensitive); + case IndexCallsign: + break; + case IndexFileName: + return this->m_fileName.compare(compareValue.getFileName(), Qt::CaseInsensitive); + case IndexModelType: + return Compare::compare(this->m_modelType, compareValue.getModelType()); + case IndexModelMode: + return Compare::compare(this->m_modelMode, compareValue.getModelMode()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison"); + return 0; + } + bool CAircraftModel::setAircraftIcaoCode(const CAircraftIcaoCode &aircraftIcaoCode) { if (this->m_aircraftIcao == aircraftIcaoCode) { return false; } diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index 03b33d75d..262f64203 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -94,6 +94,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CAircraftModel &compareValue, const CPropertyIndex &index) const; + //! Corresponding callsign if applicable const BlackMisc::Aviation::CCallsign &getCallsign() const { return this->m_callsign; } diff --git a/src/blackmisc/simulation/distributor.cpp b/src/blackmisc/simulation/distributor.cpp index bcacd8e8b..a8e0c4930 100644 --- a/src/blackmisc/simulation/distributor.cpp +++ b/src/blackmisc/simulation/distributor.cpp @@ -71,6 +71,25 @@ namespace BlackMisc } } + int CDistributor::comparePropertyByIndex(const CDistributor &compareValue, const CPropertyIndex &index) const + { + if (IDatastoreObjectWithStringKey::canHandleIndex(index)) { return IDatastoreObjectWithStringKey::comparePropertyByIndex(compareValue, index); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexAlias1: + return this->m_alias1.compare(compareValue.m_alias1, Qt::CaseInsensitive); + case IndexAlias2: + return this->m_alias2.compare(compareValue.m_alias2, Qt::CaseInsensitive); + case IndexDescription: + return this->m_description.compare(compareValue.getDescription(), Qt::CaseInsensitive); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed"); + return 0; + } + QString CDistributor::convertToQString(bool i18n) const { Q_UNUSED(i18n); diff --git a/src/blackmisc/simulation/distributor.h b/src/blackmisc/simulation/distributor.h index 80fbbfa17..b5da55844 100644 --- a/src/blackmisc/simulation/distributor.h +++ b/src/blackmisc/simulation/distributor.h @@ -84,6 +84,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CDistributor &compareValue, const CPropertyIndex &index) const; + //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/simulation/simulatedaircraft.cpp b/src/blackmisc/simulation/simulatedaircraft.cpp index 812721f6e..b6e1d426e 100644 --- a/src/blackmisc/simulation/simulatedaircraft.cpp +++ b/src/blackmisc/simulation/simulatedaircraft.cpp @@ -9,7 +9,9 @@ #include "simulatedaircraft.h" #include "blackmisc/propertyindex.h" +#include "blackmisc/comparefunctions.h" +using namespace BlackMisc; using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Aviation; using namespace BlackMisc::Network; @@ -315,7 +317,8 @@ namespace BlackMisc this->m_transponder.setPropertyByIndex(variant, index.copyFrontRemoved()); break; case IndexAircraftIcaoCode: - this->m_livery.setPropertyByIndex(variant, index); // intentionally not removing front, delegating + // intentionally not removing front, delegating + this->m_livery.setPropertyByIndex(variant, index); break; case IndexLivery: this->m_livery.setPropertyByIndex(variant, index.copyFrontRemoved()); @@ -348,6 +351,46 @@ namespace BlackMisc } } + int CSimulatedAircraft::comparePropertyByIndex(const CSimulatedAircraft &compareValue, const CPropertyIndex &index) const + { + if (index.isMyself()) { return this->m_callsign.comparePropertyByIndex(compareValue.getCallsign(), index.copyFrontRemoved()); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexCallsign: + return this->m_callsign.comparePropertyByIndex(compareValue.getCallsign(), index.copyFrontRemoved()); + case IndexPilot: + return this->m_pilot.comparePropertyByIndex(compareValue.getPilot(), index.copyFrontRemoved()); + case IndexSituation: + case IndexDistanceToOwnAircraft: + return this->m_distanceToOwnAircraft.comparePropertyByIndex(compareValue.getDistanceToOwnAircraft(), index.copyFrontRemoved()); + case IndexCom1System: + return m_com1system.getFrequencyActive().comparePropertyByIndex(compareValue.getCom1System().getFrequencyActive(), index.copyFrontRemoved()); + case IndexCom2System: + return m_com2system.getFrequencyActive().comparePropertyByIndex(compareValue.getCom2System().getFrequencyActive(), index.copyFrontRemoved()); + case IndexTransponder: + return Compare::compare(m_transponder.getTransponderCode(), compareValue.getTransponder().getTransponderCode()); + case IndexLivery: + return this->m_livery.comparePropertyByIndex(compareValue.getLivery(), index.copyFrontRemoved()); + case IndexParts: + return this->m_parts.comparePropertyByIndex(compareValue.getParts(), index.copyFrontRemoved()); + case IndexModel: + return m_model.comparePropertyByIndex(compareValue.getModel(), index.copyFrontRemoved()); + case IndexEnabled: + return Compare::compare(this->m_enabled, compareValue.isEnabled()); + case IndexRendered: + return Compare::compare(this->m_rendered, compareValue.isRendered()); + case IndexPartsSynchronized: + return Compare::compare(this->m_partsSynchronized, compareValue.isPartsSynchronized()); + case IndexFastPositionUpdates: + return Compare::compare(this->m_fastPositionUpdates, compareValue.fastPositionUpdates()); + default: + break; + } + Q_ASSERT_X(false, Q_FUNC_INFO, "Comapre failed"); + return 0; + } + void CSimulatedAircraft::setModel(const CAircraftModel &model) { // sync the callsigns diff --git a/src/blackmisc/simulation/simulatedaircraft.h b/src/blackmisc/simulation/simulatedaircraft.h index 3d4be087c..070eab8ee 100644 --- a/src/blackmisc/simulation/simulatedaircraft.h +++ b/src/blackmisc/simulation/simulatedaircraft.h @@ -301,6 +301,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const CSimulatedAircraft &compareValue, const CPropertyIndex &index) const; + //! Get model const BlackMisc::Simulation::CAircraftModel &getModel() const { return m_model; } diff --git a/src/blackmisc/simulation/simulatorinfo.cpp b/src/blackmisc/simulation/simulatorinfo.cpp index d6e5efd3b..9099b7715 100644 --- a/src/blackmisc/simulation/simulatorinfo.cpp +++ b/src/blackmisc/simulation/simulatorinfo.cpp @@ -9,6 +9,7 @@ #include "simulatorinfo.h" #include "blackmisc/project.h" +#include "blackmisc/comparefunctions.h" #include "blackmisc/simulation/fscommon/fscommonutil.h" using namespace BlackMisc; @@ -85,6 +86,12 @@ namespace BlackMisc return (this->m_simulator & otherInfo.m_simulator) > 0; } + int CSimulatorInfo::comparePropertyByIndex(const CSimulatorInfo &compareValue, const CPropertyIndex &index) const + { + Q_UNUSED(index); + return Compare::compare(this->m_simulator, compareValue.m_simulator); + } + QString CSimulatorInfo::convertToQString(bool i18n) const { Q_UNUSED(i18n); diff --git a/src/blackmisc/simulation/simulatorinfo.h b/src/blackmisc/simulation/simulatorinfo.h index 58e102b63..dc3281af8 100644 --- a/src/blackmisc/simulation/simulatorinfo.h +++ b/src/blackmisc/simulation/simulatorinfo.h @@ -101,6 +101,9 @@ namespace BlackMisc //! All simulators void setAllSimulators() { setSimulator(All); } + //! Compare for index + int comparePropertyByIndex(const CSimulatorInfo &compareValue, const CPropertyIndex &index) const; + //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/timestampbased.cpp b/src/blackmisc/timestampbased.cpp index ed59351b0..59fed15d7 100644 --- a/src/blackmisc/timestampbased.cpp +++ b/src/blackmisc/timestampbased.cpp @@ -8,7 +8,8 @@ */ #include "timestampbased.h" -#include "variant.h" +#include "blackmisc/comparefunctions.h" +#include "blackmisc/variant.h" namespace BlackMisc { @@ -138,6 +139,7 @@ namespace BlackMisc bool ITimestampBased::canHandleIndex(const CPropertyIndex &index) { + if (index.isEmpty()) { return false; } int i = index.frontCasted(); return (i >= static_cast(IndexUtcTimestamp)) && (i <= static_cast(IndexMSecsSinceEpoch)); } @@ -168,7 +170,7 @@ namespace BlackMisc } } const QString m = QString("Cannot handle index %1").arg(index.toQString()); - Q_ASSERT_X(false, "propertyByIndex", m.toLocal8Bit().constData()); + Q_ASSERT_X(false, Q_FUNC_INFO, m.toLocal8Bit().constData()); return CVariant::fromValue(m); } @@ -199,7 +201,13 @@ namespace BlackMisc } } const QString m = QString("Cannot handle index %1").arg(index.toQString()); - Q_ASSERT_X(false, "setPropertyByIndex", m.toLocal8Bit().constData()); + Q_ASSERT_X(false, Q_FUNC_INFO, m.toLocal8Bit().constData()); + } + + int ITimestampBased::comparePropertyByIndex(const ITimestampBased &compareValue, const CPropertyIndex &index) const + { + Q_UNUSED(index); + return Compare::compare(this->m_timestampMSecsSinceEpoch, compareValue.m_timestampMSecsSinceEpoch); } } // namespace diff --git a/src/blackmisc/timestampbased.h b/src/blackmisc/timestampbased.h index 974940b3f..68de4e333 100644 --- a/src/blackmisc/timestampbased.h +++ b/src/blackmisc/timestampbased.h @@ -111,6 +111,9 @@ namespace BlackMisc //! \copydoc CValueObject::setPropertyByIndex void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Compare for index + int comparePropertyByIndex(const ITimestampBased &compareValue, const CPropertyIndex &index) const; + qint64 m_timestampMSecsSinceEpoch; //!< timestamp value };