From e519942c4acfe13d36751fef486b78c10a4ab7e5 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 5 Mar 2014 23:55:53 +0100 Subject: [PATCH] refs #74 , class for FSX aircraft.cfg entries --- src/blacksim/fscommon/aircraftcfgentries.cpp | 163 ++++++++++++++++++ src/blacksim/fscommon/aircraftcfgentries.h | 140 +++++++++++++++ .../fscommon/aircraftcfgentrieslist.cpp | 98 +++++++++++ .../fscommon/aircraftcfgentrieslist.h | 88 ++++++++++ 4 files changed, 489 insertions(+) create mode 100644 src/blacksim/fscommon/aircraftcfgentries.cpp create mode 100644 src/blacksim/fscommon/aircraftcfgentries.h create mode 100644 src/blacksim/fscommon/aircraftcfgentrieslist.cpp create mode 100644 src/blacksim/fscommon/aircraftcfgentrieslist.h diff --git a/src/blacksim/fscommon/aircraftcfgentries.cpp b/src/blacksim/fscommon/aircraftcfgentries.cpp new file mode 100644 index 000000000..82d75a70f --- /dev/null +++ b/src/blacksim/fscommon/aircraftcfgentries.cpp @@ -0,0 +1,163 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "aircraftcfgentries.h" +#include "blackmisc/blackmiscfreefunctions.h" + +namespace BlackSim +{ + namespace FsCommon + { + + /* + * Constructor + */ + CAircraftCfgEntries::CAircraftCfgEntries(const QString &filePath, qint32 index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode) : + m_index(index), m_filePath(filePath), m_title(title), m_atcType(atcType), + m_atcModel(atcModel), m_atcParkingCode(atcParkingCode) + { + // void + } + + /* + * Operator == + */ + bool CAircraftCfgEntries::operator ==(const CAircraftCfgEntries &otherEntry) const + { + if (this == &otherEntry) return true; + return this->m_title == otherEntry.m_title; + } + + /* + * Operator != + */ + bool CAircraftCfgEntries::operator !=(const CAircraftCfgEntries &otherEntry) const + { + if (this == &otherEntry) return false; + return !((*this) == otherEntry); + } + + /* + * String representation + */ + QString CAircraftCfgEntries::convertToQString(bool) const + { + QString s = "{%1, %2, %3, %4, %5, %6}"; + s = s.arg(this->m_filePath).arg(this->m_index).arg(this->m_title) + .arg(this->m_atcModel).arg(this->m_atcType).arg(this->m_atcParkingCode); + return s; + } + + /* + * Get particular column + */ + QVariant CAircraftCfgEntries::propertyByIndex(int index) const + { + switch (index) + { + case IndexFilePath: + return this->m_filePath; + break; + case IndexTitle: + return this->m_title; + break; + case IndexAtcType: + return this->m_atcType; + break; + case IndexAtcModel: + return this->m_atcModel; + break; + case IndexParkingCode: + return this->m_atcParkingCode; + break; + case IndexEntryIndex: + return this->m_index; + break; + default: + break; + } + + Q_ASSERT_X(false, "CAircraftCfgEntries", "index unknown"); + QString m = QString("no property, index ").append(QString::number(index)); + return QVariant::fromValue(m); + } + + /* + * Hash + */ + uint CAircraftCfgEntries::getValueHash() const + { + QList hashs; + hashs << qHash(this->m_atcModel); + hashs << qHash(this->m_atcParkingCode); + hashs << qHash(this->m_atcType); + hashs << qHash(this->m_filePath); + hashs << qHash(this->m_index); + hashs << qHash(this->m_title); + return BlackMisc::calculateHash(hashs, "CAircraftCfgEntries"); + } + + /* + * Register metadata + */ + void CAircraftCfgEntries::registerMetadata() + { + qRegisterMetaType(); + qDBusRegisterMetaType(); + } + + /* + * Compare + */ + int CAircraftCfgEntries::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + if (this->m_index != other.m_index) + { + return (this->m_index > other.m_index) ? 1 : -1; + } + int result; + if ((result = this->m_atcModel.compare(other.m_atcModel, Qt::CaseInsensitive))) return result; + if ((result = this->m_atcParkingCode.compare(other.m_atcParkingCode, Qt::CaseInsensitive))) return result; + if ((result = this->m_atcType.compare(other.m_atcType, Qt::CaseInsensitive))) return result;; + if ((result = this->m_filePath.compare(other.m_filePath, Qt::CaseInsensitive))) return result;; + return this->m_title.compare(other.m_title, Qt::CaseInsensitive); + } + + /* + * Metatype + */ + int CAircraftCfgEntries::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * Marshall to DBus + */ + void CAircraftCfgEntries::marshallToDbus(QDBusArgument &argument) const + { + argument << this->m_atcModel; + argument << this->m_atcParkingCode; + argument << this->m_atcType; + argument << this->m_filePath; + argument << this->m_index; + argument << this->m_title; + } + + /* + * Unmarshall from DBus + */ + void CAircraftCfgEntries::unmarshallFromDbus(const QDBusArgument &argument) + { + argument >> this->m_atcModel; + argument >> this->m_atcParkingCode; + argument >> this->m_atcType; + argument >> this->m_filePath; + argument >> this->m_index; + argument >> this->m_title; + } + } +} // namespace diff --git a/src/blacksim/fscommon/aircraftcfgentries.h b/src/blacksim/fscommon/aircraftcfgentries.h new file mode 100644 index 000000000..cb6ff19dc --- /dev/null +++ b/src/blacksim/fscommon/aircraftcfgentries.h @@ -0,0 +1,140 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BLACKSIM_FSCOMMON_AIRCRAFTCFGENTRY_H +#define BLACKSIM_FSCOMMON_AIRCRAFTCFGENTRY_H + +#include "blackmisc/valueobject.h" +#include + +namespace BlackSim +{ + namespace FsCommon + { + + /*! + * \brief Set of aircraft.cfg entries representing an aircraft (FSX) + * \remarks an entry in the aircraft.cfg is title, atc type, ... This class already bundles + * relevant entries, hence the class is named Entries (plural) + */ + class CAircraftCfgEntries: public BlackMisc::CValueObject + { + private: + qint32 m_index; //!< current index in given config + QString m_filePath; //!< file path of aircraft.cfg + QString m_title; //!< Title in aircraft.cfg + QString m_atcType; //!< ATC type + QString m_atcModel; //!< ATC model + QString m_atcParkingCode; //!< ATC parking code + + protected: + //! \copydoc CValueObject::convertToQString + virtual QString convertToQString(bool i18n = false) const override; + + //! \copydoc CValueObject::marshallToDbus + virtual void marshallToDbus(QDBusArgument &) const override; + + //! \copydoc CValueObject::unmarshallFromDbus + virtual void unmarshallFromDbus(const QDBusArgument &) override; + + //! \copydoc CValueObject::compareImpl + int compareImpl(const CValueObject &otherBase) const override; + + //! \copydoc CValueObject::getMetaTypeId() + int getMetaTypeId() const override; + + public: + + //! \brief Properties by index + enum ColumnIndex + { + IndexEntryIndex = 0, + IndexFilePath, + IndexTitle, + IndexAtcType, + IndexAtcModel, + IndexParkingCode + }; + + //! \brief Default constructor + CAircraftCfgEntries() {} + + /*! + * \brief Entries representing an aircraft + * \param filePath + * \param index + * \param title + * \param atcType + * \param atcModel + * \param atcParkingCode + */ + CAircraftCfgEntries(const QString &filePath, qint32 index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode); + + //! \brief Virtual destructor + virtual ~CAircraftCfgEntries() {} + + //! \brief operator == + bool operator ==(const CAircraftCfgEntries &otherEntry) const; + + //! \brief operator != + bool operator !=(const CAircraftCfgEntries &otherEntry) const; + + //! \copydoc CValueObject::propertyByIndex + QVariant propertyByIndex(int index) const; + + //! \brief Filepath + QString getFilePath() const { return this->m_filePath; } + + //! \brief Title + QString getTitle() const { return this->m_title; } + + //! \brief Index + qint32 getIndex() const { return this->m_index; } + + //! \brief ATC model + QString getAtcModel() const { return this->m_atcModel; } + + //! \brief ATC type + QString getAtcType() const { return this->m_atcType; } + + //! \brief ATC parking code + QString getAtcParkingCode() const { return this->m_atcParkingCode; } + + //! \brief Filepath + void setFilePath(const QString &filePath) { this->m_filePath = filePath; } + + //! \brief Title + void setTitle(const QString &title) { this->m_title = title; } + + //! \brief Index + void setIndex(const qint32 index) { this->m_index = index; } + + //! \brief ATC model + void setAtcModel(const QString &atcModel) { this->m_atcModel = atcModel; } + + //! \brief ATC type + void setAtcType(const QString &atcType) { this->m_atcType = atcType; } + + //! \brief Parking code + void setAtcParkingCode(const QString &parkingCode) { this->m_atcParkingCode = parkingCode; } + + //! \copydoc CValueObject::getValueHash() + virtual uint getValueHash() const override; + + //! \copydoc CValueObject::toQVariant() + virtual QVariant toQVariant() const override + { + return QVariant::fromValue(*this); + } + + //! \brief Register the metatypes + static void registerMetadata(); + }; + } +} // namespace + +Q_DECLARE_METATYPE(BlackSim::FsCommon::CAircraftCfgEntries) + +#endif // guard diff --git a/src/blacksim/fscommon/aircraftcfgentrieslist.cpp b/src/blacksim/fscommon/aircraftcfgentrieslist.cpp new file mode 100644 index 000000000..5254a6843 --- /dev/null +++ b/src/blacksim/fscommon/aircraftcfgentrieslist.cpp @@ -0,0 +1,98 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "aircraftcfgentrieslist.h" + +namespace BlackSim +{ + namespace FsCommon + { + + /* + * Does the directory exist? + */ + bool CAircraftCfgEntriesList::existsDir(const QString &directory) const + { + QString d = directory.isEmpty() ? this->m_rootDirectory : directory; + if (d.isEmpty()) return false; + QDir dir(d); + return (dir.exists()); + } + + /* + * Read all entrities in given directory + */ + qint32 CAircraftCfgEntriesList::read(const QString &directory) + { + // set directory with name filters, get aircraft.cfg and sub directories + QDir dir(directory, "aircraft.cfg", QDir::Name, QDir::Files | QDir::AllDirs); + if (!dir.exists()) return 0; // can happen if there are shortcuts or linked dirs not available + + qint32 counter = 0; + QString currentDir = dir.absolutePath(); + + // Dirs last is crucial,since I will break recursion on "aircraft.cfg" level + QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::AllDirs, QDir::DirsLast); + + foreach(QFileInfo file, files) + { + if (file.isDir()) + { + QString nextDir = file.absoluteFilePath(); + if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) continue; // do not go up + if (dir == currentDir) continue; // do not recursively call same directory + counter += CAircraftCfgEntriesList::read(nextDir); + } + else + { + // due to the filter we expect only "aircraft.cfg" here + QString path = file.absoluteFilePath(); + + // I abuse the QSettings as ini-file reader + QSettings aircraftCfg(path, QSettings::IniFormat); + const QString atcType = aircraftCfg.value("atc_type").toString(); + const QString atcModel = aircraftCfg.value("atc_model").toString(); + + int index = 0; + while (index >= 0) + { + QString group = QString("fltsim.%1").arg(index); + aircraftCfg.beginGroup(group); + if (aircraftCfg.contains("title")) + { + CAircraftCfgEntries entry(path, index, "", atcType, atcModel, ""); + entry.setTitle(aircraftCfg.value("title").toString()); + entry.setAtcParkingCode(aircraftCfg.value("atc_parking_codes").toString()); + this->push_back(entry); + aircraftCfg.endGroup(); + ++index; + ++counter; + } + else + { + index = -1; + } + } + break; + } + } + return counter; + } + + /* + * Register metadata + */ + void CAircraftCfgEntriesList::registerMetadata() + { + qRegisterMetaType>(); + qDBusRegisterMetaType>(); + qRegisterMetaType>(); + qDBusRegisterMetaType>(); + qRegisterMetaType(); + qDBusRegisterMetaType(); + } + + } // namespace +} // namespace diff --git a/src/blacksim/fscommon/aircraftcfgentrieslist.h b/src/blacksim/fscommon/aircraftcfgentrieslist.h new file mode 100644 index 000000000..9fd3b1ab3 --- /dev/null +++ b/src/blacksim/fscommon/aircraftcfgentrieslist.h @@ -0,0 +1,88 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BLACKSIM_FSCOMMON_AIRCRAFTCFG_H +#define BLACKSIM_FSCOMMON_AIRCRAFTCFG_H + +#include "aircraftcfgentries.h" +#include "blackmisc/sequence.h" +#include "blackmisc/collection.h" +#include +#include +#include +#include + +namespace BlackSim +{ + namespace FsCommon + { + + //! \brief Utility, providing FSX aircraft.cfg entries + class CAircraftCfgEntriesList : public BlackMisc::CSequence + { + private: + QString m_rootDirectory; //!< root directory reading aircraft.cfg files + bool m_readForDirectory; //!< valid read for given directory + + //! \brief Read all entries in one directory + qint32 read(const QString &directory); + + public: + + //! \brief Constructor + CAircraftCfgEntriesList(const QString &rootDirectory = "") : m_rootDirectory(rootDirectory), m_readForDirectory(false) {} + + //! \brief Read all aircraft.cfg files starting from root directory + qint32 read() + { + if (this->m_readForDirectory) return this->size(); + + // not read so far, read it + this->clear(); + this->m_readForDirectory = true; + return this->read(this->m_rootDirectory); + } + + //! \brief Change the directory + bool changeDirectory(const QString &directory) + { + if (this->m_rootDirectory != directory) + { + this->m_rootDirectory = directory; + this->m_readForDirectory = false; + } + return !directory.isEmpty() && this->existsDir(directory); + } + + //! \brief Virtual destructor + virtual ~CAircraftCfgEntriesList() {} + + //! \brief Does the directory exist? + bool existsDir(const QString &directory = "") const; + + //! \brief Has current directory been read? + bool hasReadDirectory() const { return this->m_readForDirectory; } + + //! \brief Current root directory + QString getRootDirectory() const { return this->m_rootDirectory; } + + //! \brief Unknown entries + static const CAircraftCfgEntries &UnknownCfgEntries() + { + static CAircraftCfgEntries entries; + return entries; + } + + //! \brief Register metadata + static void registerMetadata(); + }; + } +} + +Q_DECLARE_METATYPE(BlackSim::FsCommon::CAircraftCfgEntriesList) +Q_DECLARE_METATYPE(BlackMisc::CCollection) +Q_DECLARE_METATYPE(BlackMisc::CSequence) + +#endif // guard