From d797d76a601b130603ddf87fd2dda356e6a23d88 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 15 Aug 2014 18:17:49 +0200 Subject: [PATCH] refs #314, CPropertyIndex class for nested indexes --- src/blackmisc/blackmiscfreefunctions.cpp | 2 +- src/blackmisc/propertyindex.cpp | 229 +++++++++++++++++++++++ src/blackmisc/propertyindex.h | 162 ++++++++++++++++ 3 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 src/blackmisc/propertyindex.cpp create mode 100644 src/blackmisc/propertyindex.h diff --git a/src/blackmisc/blackmiscfreefunctions.cpp b/src/blackmisc/blackmiscfreefunctions.cpp index 50de5d380..f0a16d8db 100644 --- a/src/blackmisc/blackmiscfreefunctions.cpp +++ b/src/blackmisc/blackmiscfreefunctions.cpp @@ -150,6 +150,7 @@ void BlackMisc::Hardware::registerMetadata() */ void BlackMisc::registerMetadata() { + CPropertyIndex::registerMetadata(); CVariant::registerMetadata(); CIndexVariantMap::registerMetadata(); CNameVariantPair::registerMetadata(); @@ -158,7 +159,6 @@ void BlackMisc::registerMetadata() CStatusMessageList::registerMetadata(); CIcon::registerMetadata(); CIconList::registerMetadata(); - CHotkeyFunction::registerMetadata(); // sub namespaces diff --git a/src/blackmisc/propertyindex.cpp b/src/blackmisc/propertyindex.cpp new file mode 100644 index 000000000..8fc953f74 --- /dev/null +++ b/src/blackmisc/propertyindex.cpp @@ -0,0 +1,229 @@ +/* Copyright (C) 2013 + * 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 "propertyindex.h" +#include "predicates.h" +#include "blackmiscfreefunctions.h" + +namespace BlackMisc +{ + /* + * Constructor + */ + CPropertyIndex::CPropertyIndex() {} + + /* + * Non nested index + */ + CPropertyIndex::CPropertyIndex(int singleProperty) + { + this->m_indexes.append(singleProperty); + this->listToString(); + } + + /* + * Construct from initializer list + */ + CPropertyIndex::CPropertyIndex(std::initializer_list il) : + m_indexes(il) + { + this->listToString(); + } + + /* + * Construct from QList + */ + CPropertyIndex::CPropertyIndex(const QList &indexes) : + m_indexes(indexes) + { + this->listToString(); + } + + /* + * From string + */ + CPropertyIndex::CPropertyIndex(const QString &indexes) : m_indexString(indexes) + { + this->parseFromString(indexes); + } + + /* + * Current property index, front element removed + */ + CPropertyIndex CPropertyIndex::copyFrontRemoved() const + { + Q_ASSERT(!this->m_indexes.isEmpty()); + if (this->m_indexes.isEmpty()) return CPropertyIndex(); + QList c = this->m_indexes; + c.removeAt(0); + CPropertyIndex pi(c); + return pi; + } + + /* + * Nested index + */ + bool CPropertyIndex::isNested() const + { + return this->m_indexes.size() > 1; + } + + /* + * Register metadata + */ + void CPropertyIndex::registerMetadata() + { + qRegisterMetaType(); + qDBusRegisterMetaType(); + } + + /* + * Convert to string + */ + QString CPropertyIndex::convertToQString(bool i18n) const + { + Q_UNUSED(i18n); + return this->m_indexString; + } + + /* + * metaTypeId + */ + int CPropertyIndex::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CPropertyIndex::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CPropertyIndex::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + return compare(TupleConverter::toTuple(*this), TupleConverter::toTuple(other)); + } + + /* + * Marshall to DBus + */ + void CPropertyIndex::marshallToDbus(QDBusArgument &argument) const + { + argument << TupleConverter::toTuple(*this); + } + + /* + * Unmarshall from DBus + */ + void CPropertyIndex::unmarshallFromDbus(const QDBusArgument &argument) + { + argument >> TupleConverter::toTuple(*this); + this->stringToList(); + } + + /* + * Parse from string + */ + void CPropertyIndex::parseFromString(const QString &indexes) + { + this->m_indexString = indexes.simplified().replace(" ", ";").replace(",", ";"); + this->stringToList(); + } + + /* + * To string + */ + void CPropertyIndex::listToString() + { + QString l; + foreach(int i, this->m_indexes) + { + if (!l.isEmpty()) { l.append(";"); } + l.append(QString::number(i)); + } + this->m_indexString = l; + } + + /* + * To int list + */ + void CPropertyIndex::stringToList() + { + this->m_indexes.clear(); + if (this->m_indexString.isEmpty()) { return; } + QStringList indexes = this->m_indexString.split(';'); + foreach(QString index, indexes) + { + if (index.isEmpty()) continue; + bool ok; + int i = index.toInt(&ok); + Q_ASSERT(ok); + this->m_indexes.append(i); + } + } + + /* + * Equal? + */ + bool CPropertyIndex::operator ==(const CPropertyIndex &other) const + { + if (this == &other) return true; + return TupleConverter::toTuple(*this) == TupleConverter::toTuple(other); + } + + /* + * Unequal? + */ + bool CPropertyIndex::operator !=(const CPropertyIndex &other) const + { + return !((*this) == other); + } + + /* + * Hash + */ + uint CPropertyIndex::getValueHash() const + { + return qHash(TupleConverter::toTuple(*this)); + } + + /* + * To JSON + */ + QJsonObject CPropertyIndex::toJson() const + { + return BlackMisc::serializeJson(CPropertyIndex::jsonMembers(), TupleConverter::toTuple(*this)); + } + + /* + * From JSON + */ + void CPropertyIndex::fromJson(const QJsonObject &json) + { + BlackMisc::deserializeJson(json, CPropertyIndex::jsonMembers(), TupleConverter::toTuple(*this)); + this->stringToList(); + } + + /* + * Members + */ + const QStringList &CPropertyIndex::jsonMembers() + { + return TupleConverter::jsonMembers(); + } + +} // namespace diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h new file mode 100644 index 000000000..94915f1ec --- /dev/null +++ b/src/blackmisc/propertyindex.h @@ -0,0 +1,162 @@ +/* Copyright (C) 2013 + * 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_PROPERTYINDEX_H +#define BLACKMISC_PROPERTYINDEX_H + +#include "valueobject.h" +#include + +namespace BlackMisc +{ + + /*! + * Property index. The index can be nested, that's why it is a sequence + * (e.g. PropertyIndexPilot, PropertyIndexRealname). + */ + class CPropertyIndex : public CValueObject + { + // In the first trial I have used CSequence as base class + // This has created too much circular dependencies of the headers + // CIndexVariantMap is used in CValueObject, CPropertyIndex in CIndexVariantMap + + public: + //! Global index, make sure the indexes are unqiue (for using them in class hierarchy) + enum GlobalIndex + { + GlobalIndexCValueObject = 0, + GlobalIndexCPhysicalQuantity = 100, + GlobalIndexCStatusMessage = 200, + GlobalIndexCCallsign = 1000, + GlobalIndexCAircraftIcao = 1100, + GlobalIndexCAircraft = 1200, + GlobalIndexCAtcStation = 1300, + GlobalIndexCAirport = 1400, + GlobalIndexCModulator = 2000, + GlobalIndexICoordinateGeodetic = 3000, + GlobalIndexCCoordinateGeodetic = 3100, + GlobalIndexCClient = 4000, + GlobalIndexCUser = 4100, + GlobalIndexCAircraftModel = 4200, + GlobalIndexCVoiceRoom = 5000, + GlobalIndexCAircraftMapping = 6000, + GlobalIndexCAircraftCfgEntries = 6100 + }; + + //! Default constructor. + CPropertyIndex(); + + //! Non nested index + CPropertyIndex(int singleProperty); + + //! Initializer list constructor + CPropertyIndex(std::initializer_list il); + + //! Construct from a base class object. + CPropertyIndex(const QList &indexes); + + //! From string + CPropertyIndex(const QString &indexes); + + //! Copy with first element removed + CPropertyIndex copyFrontRemoved() const; + + //! Is nested index? + bool isNested() const; + + //! Myself index, used with nesting + bool isMyself() const { return this->m_indexes.isEmpty(); } + + //! Empty? + bool isEmpty() const { return this->m_indexes.isEmpty(); } + + //! First element casted to given type, usually then PropertIndex enum + template CastType frontCasted() const + { + Q_ASSERT(!this->m_indexes.isEmpty()); + int f = this->m_indexes.isEmpty() ? 0 : this->m_indexes.first(); + return static_cast(f); + } + + //! Equal operator == + bool operator ==(const CPropertyIndex &other) const; + + //! Unequal operator != + bool operator !=(const CPropertyIndex &other) const; + + //! \copydoc CValueObject::CPropertyIndexlueHash() + virtual uint getValueHash() const override; + + //! CValueObject::toQVariant() + virtual QVariant toQVariant() const override { return QVariant::fromValue(*this); } + + //! \copydoc CValueObject::fromQVariant + virtual void fromQVariant(const QVariant &variant) override + { + Q_ASSERT(variant.canConvert()); + if (variant.canConvert()) + { + (*this) = variant.value(); + } + } + + //! \copydoc CValueObject::toJson + virtual QJsonObject toJson() const override; + + //! \copydoc CValueObject::fromJson + virtual void fromJson(const QJsonObject &json) override; + + //! Register metadata + static void registerMetadata(); + + //! Members + static const QStringList &jsonMembers(); + + protected: + //! \copydoc CValueObject::convertToQString + virtual QString convertToQString(bool i18n = false) const override; + + //! \copydoc CValueObject::getMetaTypeId + virtual int getMetaTypeId() const override; + + //! \copydoc CValueObject::isA + virtual bool isA(int metaTypeId) const override; + + //! \copydoc CValueObject::compareImpl + virtual int compareImpl(const CValueObject &other) const override; + + //! \copydoc CValueObject::marshallToDbus + virtual void marshallToDbus(QDBusArgument &argument) const override; + + //! \copydoc CValueObject::unmarshallFromDbus + virtual void unmarshallFromDbus(const QDBusArgument &argument) override; + + //! \copydoc CValueObject::parseFromString + virtual void parseFromString(const QString &indexes) override; + + private: + BLACK_ENABLE_TUPLE_CONVERSION(CPropertyIndex) + QList m_indexes; + QString m_indexString; //! I use a little trick here, the string is used with the tupel system, as it provides all operators, hash .. + + //! Convert list to string + void listToString(); + + //! String to list + void stringToList(); + + }; +} //namespace + +BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::CPropertyIndex, (o.m_indexString)) +Q_DECLARE_METATYPE(BlackMisc::CPropertyIndex) + +#endif //guard