diff --git a/src/blackmisc/datastore.h b/src/blackmisc/datastore.h index 5ab878287..1302d9faf 100644 --- a/src/blackmisc/datastore.h +++ b/src/blackmisc/datastore.h @@ -24,6 +24,8 @@ namespace BlackMisc */ class BLACKMISC_EXPORT IDatastoreObjectWithIntegerKey : public ITimestampBased { + Q_INTERFACES(BlackMisc::ITimestampBased) + public: //! Property index enum ColumnIndex @@ -95,6 +97,8 @@ namespace BlackMisc */ class BLACKMISC_EXPORT IDatastoreObjectWithStringKey : public ITimestampBased { + Q_INTERFACES(BlackMisc::ITimestampBased) + public: //! Property index enum ColumnIndex @@ -151,4 +155,7 @@ namespace BlackMisc } // namespace +Q_DECLARE_INTERFACE(BlackMisc::IDatastoreObjectWithIntegerKey, "org.swift-project.blackmisc.idatastoreobjectwithintegerkey") +Q_DECLARE_INTERFACE(BlackMisc::IDatastoreObjectWithStringKey, "org.swift-project.blackmisc.idatastoreobjectwithstringkey") + #endif // guard diff --git a/src/blackmisc/orderable.cpp b/src/blackmisc/orderable.cpp new file mode 100644 index 000000000..5a7c65eee --- /dev/null +++ b/src/blackmisc/orderable.cpp @@ -0,0 +1,87 @@ +/* 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 "orderable.h" +#include "blackmisc/comparefunctions.h" +#include "blackmisc/variant.h" +#include + +namespace BlackMisc +{ + IOrderable::IOrderable() { } + + IOrderable::IOrderable(int order) : m_order(order) + { } + + QString IOrderable::getOrderAsString() const + { + if (this->hasValidOrder()) { return QString::number(this->getOrder()); } + return "-"; + } + + bool IOrderable::hasValidOrder() const + { + return this->getOrder() >= 0; + } + + bool IOrderable::canHandleIndex(const CPropertyIndex &index) + { + if (index.isEmpty()) { return false; } + int i = index.frontCasted(); + return (i >= static_cast(IndexOrder)) && (i <= static_cast(IndexOrderString)); + } + + CVariant IOrderable::propertyByIndex(const CPropertyIndex &index) const + { + if (!index.isEmpty()) + { + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexOrder: + return CVariant::fromValue(this->m_order); + case IndexOrderString: + return CVariant::fromValue(this->getOrderAsString()); + default: + break; + } + } + const QString m = QString("Cannot handle index %1").arg(index.toQString()); + Q_ASSERT_X(false, Q_FUNC_INFO, m.toLocal8Bit().constData()); + return CVariant::fromValue(m); + } + + void IOrderable::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index) + { + if (!index.isEmpty()) + { + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexOrder: + this->setOrder(variant.toInt()); + return; + case IndexOrderString: + default: + break; + } + } + const QString m = QString("Cannot handle index %1").arg(index.toQString()); + Q_ASSERT_X(false, Q_FUNC_INFO, m.toLocal8Bit().constData()); + } + + int IOrderable::comparePropertyByIndex(const IOrderable &compareValue, const CPropertyIndex &index) const + { + Q_UNUSED(index); + static const int max = std::numeric_limits::max(); + const int o1 = this->hasValidOrder() ? this->getOrder() : max; + const int o2 = compareValue.hasValidOrder() ? compareValue.getOrder() : max; + return Compare::compare(o1, o2); + } +} // namespace diff --git a/src/blackmisc/orderable.h b/src/blackmisc/orderable.h new file mode 100644 index 000000000..5eb725d1b --- /dev/null +++ b/src/blackmisc/orderable.h @@ -0,0 +1,68 @@ +/* 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_ORDERABLE_H +#define BLACKMISC_ORDERABLE_H + +#include "blackmiscexport.h" +#include "propertyindex.h" + +namespace BlackMisc +{ + //! Entity with timestamp + class BLACKMISC_EXPORT IOrderable + { + public: + //! Properties by index + enum ColumnIndex + { + IndexOrder = BlackMisc::CPropertyIndex::GlobalIndexIOrderable, + IndexOrderString + }; + + //! Order + int getOrder() const { return m_order; } + + //! Order as string + QString getOrderAsString() const; + + //! Set order + void setOrder(int order) { m_order = order; } + + //! Valid order set? + bool hasValidOrder() const; + + //! Can given index be handled + static bool canHandleIndex(const BlackMisc::CPropertyIndex &index); + + protected: + //! Constructor + IOrderable(); + + //! Constructor + IOrderable(int order); + + //! \copydoc BlackMisc::Mixin::Index::propertyByIndex + CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; + + //! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex + void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + + //! Compare for index + int comparePropertyByIndex(const IOrderable &compareValue, const CPropertyIndex &index) const; + + int m_order = -1; //!< order number + }; +} // namespace + +Q_DECLARE_INTERFACE(BlackMisc::IOrderable, "org.swift-project.blackmisc.iorderable") + +#endif // guard diff --git a/src/blackmisc/orderablelist.cpp b/src/blackmisc/orderablelist.cpp new file mode 100644 index 000000000..d988ff796 --- /dev/null +++ b/src/blackmisc/orderablelist.cpp @@ -0,0 +1,142 @@ +/* Copyright (C) 2016 + * 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 "blackmisc/orderablelist.h" +#include "blackmisc/simulation/distributorlist.h" +#include "blackmisc/simulation/aircraftmodellist.h" +#include +#include + +namespace BlackMisc +{ + template + IOrderableList::IOrderableList() + { } + + template + const CONTAINER &IOrderableList::container() const + { + return static_cast(*this); + } + + template + CONTAINER &IOrderableList::container() + { + return static_cast(*this); + } + + template + void IOrderableList::sortDescendingByOrder() + { + IOrderableList::container().sortAscendingByOrder(); + std::reverse(this->container().begin(), this->container().end()); + } + + template + void IOrderableList::sortAscendingByOrder() + { + IOrderableList::container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getOrder)); + } + + template + void IOrderableList::resetOrder(int offset) + { + int c = offset; + for (OBJ &obj : container()) + { + obj.setOrder(c++); + } + } + + template + bool IOrderableList::needsOrder() const + { + for (const OBJ &obj : container()) + { + if (!obj.hasValidOrder()) { return true; } + } + return false; + } + + template + QList IOrderableList::orderValues() const + { + QList orders; + for (const OBJ &obj : container()) + { + if (!obj.hasValidOrder()) { continue; } + orders.append(obj.getOrder()); + } + return orders; + } + + template + CONTAINER IOrderableList::withoutItemsOfSameOrder(const CONTAINER &items) const + { + const QList orders = items.orderValues(); + if (orders.isEmpty()) { return this->container(); } + + CONTAINER newContainer; + for (const OBJ &obj : container()) + { + if (orders.contains(obj.getOrder())) { continue; } + newContainer.push_back(obj); + } + return newContainer; + } + + template + void IOrderableList::removeItemsWithSameOrder(const CONTAINER &items) + { + const QList orders = items.orderValues(); + if (orders.isEmpty()) { return; } + + CONTAINER newContainer; + for (const OBJ &obj : container()) + { + if (orders.contains(obj.getOrder())) { continue; } + newContainer.push_back(obj); + } + this->container() = newContainer; + } + + template + void IOrderableList::moveTo(const CONTAINER &items, int targetOrder) + { + if (items.isEmpty()) { return; } + CONTAINER newContainer(this->withoutItemsOfSameOrder(items)); // this container without items + CONTAINER newItems(items); + const int shift = items.size(); + newContainer.sortAscendingByOrder(); // sorted by old order + newContainer.resetOrder(); + for (OBJ &obj : newContainer) + { + if (obj.getOrder() < targetOrder) { continue; } + obj.setOrder(obj.getOrder() + shift); + } + newItems.sortAscendingByOrder(); // sort by old order + newItems.resetOrder(targetOrder); + newContainer.push_back(newItems); + this->container() = newContainer; + } + + template + void IOrderableList::freezeOrder() + { + int c = 0; + for (OBJ &obj : container()) + { + obj.setOrder(c++); + } + } + + template class IOrderableList; + template class IOrderableList; + +} // namespace diff --git a/src/blackmisc/orderablelist.h b/src/blackmisc/orderablelist.h new file mode 100644 index 000000000..1f5a0d541 --- /dev/null +++ b/src/blackmisc/orderablelist.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2016 + * 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_ORDERABLELIST_H +#define BLACKMISC_ORDERABLELIST_H + +#include "blackmisc/collection.h" +#include "blackmisc/sequence.h" + +namespace BlackMisc +{ + //! List of orderable IOrderable objects + template + class IOrderableList + { + public: + //! Sort ascending + void sortAscendingByOrder(); + + //! Sort descending + void sortDescendingByOrder(); + + //! Set order member to current order + void resetOrder(int offset = 0); + + //! All order values set or missing some? + bool needsOrder() const; + + //! All order values IOrderable::order + QList orderValues() const; + + //! Items with order will not be included + CONTAINER withoutItemsOfSameOrder(const CONTAINER &items) const; + + //! Remove the items based on their order IOrderable::order + void removeItemsWithSameOrder(const CONTAINER &items); + + //! Move items to given order + void moveTo(const CONTAINER &items, int targetOrder); + + //! Current order of list will be new order values + void freezeOrder(); + + protected: + //! Constructor + IOrderableList(); + + //! Container + const CONTAINER &container() const; + + //! Container + CONTAINER &container(); + }; + + //! \cond PRIVATE + namespace Simulation + { + class CDistributor; + class CDistributorList; + class CAircraftModel; + class CAircraftModelList; + } + + extern template class BLACKMISC_EXPORT_TEMPLATE IOrderableList; + extern template class BLACKMISC_EXPORT_TEMPLATE IOrderableList; + + //! \endcond +} //namespace + +#endif //guard diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h index 3bb9b87e3..ab0f1948c 100644 --- a/src/blackmisc/propertyindex.h +++ b/src/blackmisc/propertyindex.h @@ -50,9 +50,10 @@ namespace BlackMisc GlobalIndexCStatusMessage = 200, GlobalIndexCNameVariantPair = 300, GlobalIndexITimestampBased = 400, - GlobalIndexCIdentifier = 500, - GlobalIndexCRgbColor = 600, - GlobalIndexCCountry = 700, + GlobalIndexIOrderable = 500, + GlobalIndexCIdentifier = 600, + GlobalIndexCRgbColor = 700, + GlobalIndexCCountry = 800, GlobalIndexCCallsign = 1000, GlobalIndexCAircraftSituation = 1100, GlobalIndexCAtcStation = 1200, diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index 13c7745fd..ce957581b 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -328,6 +328,7 @@ namespace BlackMisc CAircraftModel, BLACK_METAMEMBER(dbKey), BLACK_METAMEMBER(timestampMSecsSinceEpoch), + BLACK_METAMEMBER(order), BLACK_METAMEMBER(callsign), BLACK_METAMEMBER(aircraftIcao), BLACK_METAMEMBER(livery), diff --git a/src/blackmisc/simulation/distributor.h b/src/blackmisc/simulation/distributor.h index cb0510a9a..0741af226 100644 --- a/src/blackmisc/simulation/distributor.h +++ b/src/blackmisc/simulation/distributor.h @@ -30,6 +30,9 @@ namespace BlackMisc public BlackMisc::IDatastoreObjectWithStringKey, public BlackMisc::IOrderable { + Q_INTERFACES(BlackMisc::IDatastoreObjectWithStringKey) + Q_INTERFACES(BlackMisc::IOrderable) + public: //! Property indexes enum ColumnIndex diff --git a/src/blackmisc/timestampbased.h b/src/blackmisc/timestampbased.h index 3b8a46563..14a6ebcdb 100644 --- a/src/blackmisc/timestampbased.h +++ b/src/blackmisc/timestampbased.h @@ -18,7 +18,6 @@ namespace BlackMisc { - //! Entity with timestamp class BLACKMISC_EXPORT ITimestampBased { @@ -116,7 +115,8 @@ namespace BlackMisc qint64 m_timestampMSecsSinceEpoch; //!< timestamp value }; - } // namespace +Q_DECLARE_INTERFACE(BlackMisc::ITimestampBased, "org.swift-project.blackmisc.itimestampbased") + #endif // guard diff --git a/src/blackmisc/timestampobjectlist.cpp b/src/blackmisc/timestampobjectlist.cpp index 7e9215cf0..fbf60f3c6 100644 --- a/src/blackmisc/timestampobjectlist.cpp +++ b/src/blackmisc/timestampobjectlist.cpp @@ -183,12 +183,9 @@ namespace BlackMisc template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; - template class ITimestampObjectList; template class ITimestampObjectList; - template class ITimestampObjectList; - template class ITimestampObjectList; template class ITimestampObjectList; template class ITimestampObjectList; diff --git a/src/blackmisc/timestampobjectlist.h b/src/blackmisc/timestampobjectlist.h index 01b124824..297932759 100644 --- a/src/blackmisc/timestampobjectlist.h +++ b/src/blackmisc/timestampobjectlist.h @@ -124,12 +124,9 @@ namespace BlackMisc extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; - extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; - extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; - extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList; extern template class BLACKMISC_EXPORT_TEMPLATE ITimestampObjectList;