mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 11:55:35 +08:00
refs #361, some own ini reader got lost in master, re-applied changes
This commit is contained in:
committed by
Mathew Sutcliffe
parent
1c3bb8d463
commit
66075ca0d0
@@ -22,19 +22,13 @@ namespace BlackMisc
|
|||||||
namespace FsCommon
|
namespace FsCommon
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
CAircraftCfgEntries::CAircraftCfgEntries(const QString &fileName, qint32 index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode, const QString &description) :
|
||||||
* Constructor
|
m_index(index), m_fileName(fileName), m_title(title.trimmed()), m_atcType(atcType.trimmed()),
|
||||||
*/
|
|
||||||
CAircraftCfgEntries::CAircraftCfgEntries(const QString &filePath, qint32 index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode, const QString &description) :
|
|
||||||
m_index(index), m_fileName(filePath), m_title(title.trimmed()), m_atcType(atcType.trimmed()),
|
|
||||||
m_atcModel(atcModel.trimmed()), m_atcParkingCode(atcParkingCode.trimmed()), m_description(description.trimmed())
|
m_atcModel(atcModel.trimmed()), m_atcParkingCode(atcParkingCode.trimmed()), m_description(description.trimmed())
|
||||||
{
|
{
|
||||||
// void
|
// void
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* String representation
|
|
||||||
*/
|
|
||||||
QString CAircraftCfgEntries::convertToQString(bool) const
|
QString CAircraftCfgEntries::convertToQString(bool) const
|
||||||
{
|
{
|
||||||
QString s = "{%1, %2, %3, %4, %5, %6}";
|
QString s = "{%1, %2, %3, %4, %5, %6}";
|
||||||
@@ -43,9 +37,10 @@ namespace BlackMisc
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
CAircraftCfgEntries::CAircraftCfgEntries(const QString &fileName, int index) :
|
||||||
* Aircraft model
|
m_index(index), m_fileName(fileName)
|
||||||
*/
|
{ }
|
||||||
|
|
||||||
QString CAircraftCfgEntries::getFileDirectory() const
|
QString CAircraftCfgEntries::getFileDirectory() const
|
||||||
{
|
{
|
||||||
if (this->m_fileName.isEmpty()) { return ""; }
|
if (this->m_fileName.isEmpty()) { return ""; }
|
||||||
@@ -63,9 +58,31 @@ namespace BlackMisc
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void CAircraftCfgEntries::setFileName(const QString &filePath)
|
||||||
* Convert
|
{
|
||||||
*/
|
this->m_fileName = filePath.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAircraftCfgEntries::setTitle(const QString &title)
|
||||||
|
{
|
||||||
|
this->m_title = title.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAircraftCfgEntries::setAtcModel(const QString &atcModel)
|
||||||
|
{
|
||||||
|
this->m_atcModel = atcModel.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAircraftCfgEntries::setAtcType(const QString &atcType)
|
||||||
|
{
|
||||||
|
this->m_atcType = atcType.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAircraftCfgEntries::setAtcParkingCode(const QString &parkingCode)
|
||||||
|
{
|
||||||
|
this->m_atcParkingCode = parkingCode.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
CAircraftModel CAircraftCfgEntries::toAircraftModel() const
|
CAircraftModel CAircraftCfgEntries::toAircraftModel() const
|
||||||
{
|
{
|
||||||
CAircraftModel model(this->getTitle(), CAircraftModel::TypeModelMapping);
|
CAircraftModel model(this->getTitle(), CAircraftModel::TypeModelMapping);
|
||||||
@@ -82,9 +99,6 @@ namespace BlackMisc
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Get particular column
|
|
||||||
*/
|
|
||||||
CVariant CAircraftCfgEntries::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
CVariant CAircraftCfgEntries::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||||
{
|
{
|
||||||
if (index.isMyself()) { return this->toCVariant(); }
|
if (index.isMyself()) { return this->toCVariant(); }
|
||||||
@@ -112,9 +126,6 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Set property as index
|
|
||||||
*/
|
|
||||||
void CAircraftCfgEntries::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
|
void CAircraftCfgEntries::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
|
||||||
{
|
{
|
||||||
if (index.isMyself()) { this->convertFromCVariant(variant); return; }
|
if (index.isMyself()) { this->convertFromCVariant(variant); return; }
|
||||||
|
|||||||
@@ -23,11 +23,9 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace FsCommon
|
namespace FsCommon
|
||||||
{
|
{
|
||||||
/*!
|
//! Set of aircraft.cfg entries representing an aircraft (FSX)
|
||||||
* Set of aircraft.cfg entries representing an aircraft (FSX)
|
//! \remarks an entry in the aircraft.cfg is title, atc type, ...
|
||||||
* \remarks an entry in the aircraft.cfg is title, atc type, ... This class already bundles
|
//! This class already bundles relevant entries, hence the class is named Entries (plural)
|
||||||
* relevant entries, hence the class is named Entries (plural)
|
|
||||||
*/
|
|
||||||
class BLACKMISC_EXPORT CAircraftCfgEntries: public BlackMisc::CValueObject<CAircraftCfgEntries>
|
class BLACKMISC_EXPORT CAircraftCfgEntries: public BlackMisc::CValueObject<CAircraftCfgEntries>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -47,6 +45,9 @@ namespace BlackMisc
|
|||||||
//! Default constructor
|
//! Default constructor
|
||||||
CAircraftCfgEntries() = default;
|
CAircraftCfgEntries() = default;
|
||||||
|
|
||||||
|
//! Entries representing an aircraft
|
||||||
|
CAircraftCfgEntries(const QString &fileName, int index);
|
||||||
|
|
||||||
//! Entries representing an aircraft
|
//! Entries representing an aircraft
|
||||||
CAircraftCfgEntries(const QString &filePath, int index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode, const QString &description);
|
CAircraftCfgEntries(const QString &filePath, int index, const QString &title, const QString &atcType, const QString &atcModel, const QString &atcParkingCode, const QString &description);
|
||||||
|
|
||||||
@@ -83,26 +84,29 @@ namespace BlackMisc
|
|||||||
//! Texture
|
//! Texture
|
||||||
QString getTexture() const { return this->m_texture; }
|
QString getTexture() const { return this->m_texture; }
|
||||||
|
|
||||||
|
//! Is Rotorcraft?
|
||||||
|
bool isRotorcraft() const { return m_rotorcraft; }
|
||||||
|
|
||||||
//! Manufacturer + type
|
//! Manufacturer + type
|
||||||
QString getUiCombinedDescription() const;
|
QString getUiCombinedDescription() const;
|
||||||
|
|
||||||
//! Filepath
|
//! Filepath
|
||||||
void setFileName(const QString &filePath) { this->m_fileName = filePath; }
|
void setFileName(const QString &filePath);
|
||||||
|
|
||||||
//! Title
|
//! Title
|
||||||
void setTitle(const QString &title) { this->m_title = title; }
|
void setTitle(const QString &title);
|
||||||
|
|
||||||
//! Index
|
//! Index
|
||||||
void setIndex(int index) { this->m_index = index; }
|
void setIndex(int index) { this->m_index = index; }
|
||||||
|
|
||||||
//! ATC model
|
//! ATC model
|
||||||
void setAtcModel(const QString &atcModel) { this->m_atcModel = atcModel.trimmed(); }
|
void setAtcModel(const QString &atcModel);
|
||||||
|
|
||||||
//! ATC type
|
//! ATC type
|
||||||
void setAtcType(const QString &atcType) { this->m_atcType = atcType.trimmed(); }
|
void setAtcType(const QString &atcType);
|
||||||
|
|
||||||
//! Parking code
|
//! Parking code
|
||||||
void setAtcParkingCode(const QString &parkingCode) { this->m_atcParkingCode = parkingCode.trimmed(); }
|
void setAtcParkingCode(const QString &parkingCode);
|
||||||
|
|
||||||
//! Description
|
//! Description
|
||||||
void setDescription(const QString &description) { this->m_description = description.trimmed(); }
|
void setDescription(const QString &description) { this->m_description = description.trimmed(); }
|
||||||
@@ -116,6 +120,9 @@ namespace BlackMisc
|
|||||||
//! UI manufacturer (e.g. Airbus)
|
//! UI manufacturer (e.g. Airbus)
|
||||||
void setUiManufacturer(const QString &manufacturer) { this->m_uiManufacturer = manufacturer.trimmed(); }
|
void setUiManufacturer(const QString &manufacturer) { this->m_uiManufacturer = manufacturer.trimmed(); }
|
||||||
|
|
||||||
|
//! Is Rotorcraft?
|
||||||
|
void setRotorcraft(bool isRotorcraft) { m_rotorcraft = isRotorcraft; }
|
||||||
|
|
||||||
//! To aircraft model
|
//! To aircraft model
|
||||||
BlackMisc::Simulation::CAircraftModel toAircraftModel() const;
|
BlackMisc::Simulation::CAircraftModel toAircraftModel() const;
|
||||||
|
|
||||||
@@ -133,20 +140,21 @@ namespace BlackMisc
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftCfgEntries)
|
BLACK_ENABLE_TUPLE_CONVERSION(CAircraftCfgEntries)
|
||||||
int m_index; //!< current index in given config
|
int m_index; //!< current index in given config
|
||||||
QString m_fileName; //!< file name of aircraft.cfg
|
QString m_fileName; //!< file name of .cfg
|
||||||
QString m_title; //!< Title in aircraft.cfg
|
QString m_title; //!< Title in .cfg
|
||||||
QString m_atcType; //!< ATC type
|
QString m_atcType; //!< ATC type
|
||||||
QString m_atcModel; //!< ATC model
|
QString m_atcModel; //!< ATC model
|
||||||
QString m_atcParkingCode; //!< ATC parking code
|
QString m_atcParkingCode; //!< ATC parking code
|
||||||
QString m_description; //!< descriptive text
|
QString m_description; //!< descriptive text
|
||||||
QString m_uiType; //!< e.g. A321-231 IAE
|
QString m_uiType; //!< e.g. A321-231 IAE
|
||||||
QString m_uiManufacturer; //!< e.g. Airbus
|
QString m_uiManufacturer; //!< e.g. Airbus
|
||||||
QString m_texture; //!< texture, needed to identify thumbnail.jpg
|
QString m_texture; //!< texture, needed to identify thumbnail.jpg
|
||||||
|
bool m_rotorcraft = false; //!< hint if rotorcraft
|
||||||
};
|
};
|
||||||
}
|
} // ns
|
||||||
}
|
} // ns
|
||||||
}
|
} // ns
|
||||||
|
|
||||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Simulation::FsCommon::CAircraftCfgEntries, (o.m_index, o.m_fileName, o.m_title, o.m_atcType, o.m_atcModel, o.m_atcParkingCode))
|
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Simulation::FsCommon::CAircraftCfgEntries, (o.m_index, o.m_fileName, o.m_title, o.m_atcType, o.m_atcModel, o.m_atcParkingCode))
|
||||||
Q_DECLARE_METATYPE(BlackMisc::Simulation::FsCommon::CAircraftCfgEntries)
|
Q_DECLARE_METATYPE(BlackMisc::Simulation::FsCommon::CAircraftCfgEntries)
|
||||||
|
|||||||
@@ -21,24 +21,38 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace Simulation
|
namespace Simulation
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace FsCommon
|
namespace FsCommon
|
||||||
{
|
{
|
||||||
|
int CAircraftCfgEntriesList::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, excludeDirectories());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAircraftCfgEntriesList::changeDirectory(const QString &directory)
|
||||||
|
{
|
||||||
|
if (this->m_rootDirectory != directory)
|
||||||
|
{
|
||||||
|
this->m_rootDirectory = directory;
|
||||||
|
this->m_readForDirectory = false;
|
||||||
|
}
|
||||||
|
return (!directory.isEmpty() && this->existsDir(directory));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Does the directory exist?
|
|
||||||
*/
|
|
||||||
bool CAircraftCfgEntriesList::existsDir(const QString &directory) const
|
bool CAircraftCfgEntriesList::existsDir(const QString &directory) const
|
||||||
{
|
{
|
||||||
QString d = directory.isEmpty() ? this->m_rootDirectory : directory;
|
QString d = directory.isEmpty() ? this->m_rootDirectory : directory;
|
||||||
if (d.isEmpty()) { return false; }
|
if (d.isEmpty()) { return false; }
|
||||||
QDir dir(d);
|
QDir dir(d);
|
||||||
//! \todo not available network dir can make this hang here
|
//! \todo unavailable network dir can make this hang here
|
||||||
return dir.exists();
|
return dir.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Model for title
|
|
||||||
*/
|
|
||||||
bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity)
|
bool CAircraftCfgEntriesList::containsModelWithTitle(const QString &title, Qt::CaseSensitivity caseSensitivity)
|
||||||
{
|
{
|
||||||
if (title.isEmpty()) { return false; }
|
if (title.isEmpty()) { return false; }
|
||||||
@@ -47,9 +61,6 @@ namespace BlackMisc
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Double titles
|
|
||||||
*/
|
|
||||||
QStringList CAircraftCfgEntriesList::detectAmbiguousTitles() const
|
QStringList CAircraftCfgEntriesList::detectAmbiguousTitles() const
|
||||||
{
|
{
|
||||||
QStringList titles = this->getTitles(true);
|
QStringList titles = this->getTitles(true);
|
||||||
@@ -70,9 +81,6 @@ namespace BlackMisc
|
|||||||
return ambiguousTitles;
|
return ambiguousTitles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* All titles
|
|
||||||
*/
|
|
||||||
QStringList CAircraftCfgEntriesList::getTitles(bool sorted) const
|
QStringList CAircraftCfgEntriesList::getTitles(bool sorted) const
|
||||||
{
|
{
|
||||||
QStringList titles = this->transform(Predicates::MemberTransform(&CAircraftCfgEntries::getTitle));
|
QStringList titles = this->transform(Predicates::MemberTransform(&CAircraftCfgEntries::getTitle));
|
||||||
@@ -80,9 +88,6 @@ namespace BlackMisc
|
|||||||
return titles;
|
return titles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* As model list
|
|
||||||
*/
|
|
||||||
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList() const
|
CAircraftModelList CAircraftCfgEntriesList::toAircraftModelList() const
|
||||||
{
|
{
|
||||||
CAircraftModelList ml;
|
CAircraftModelList ml;
|
||||||
@@ -93,18 +98,24 @@ namespace BlackMisc
|
|||||||
return ml;
|
return ml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Models for title
|
|
||||||
*/
|
|
||||||
CAircraftCfgEntriesList CAircraftCfgEntriesList::findByTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) const
|
CAircraftCfgEntriesList CAircraftCfgEntriesList::findByTitle(const QString &title, Qt::CaseSensitivity caseSensitivity) const
|
||||||
{
|
{
|
||||||
return this->findBy([ = ](const CAircraftCfgEntries & entries) -> bool
|
return this->findBy([ = ](const CAircraftCfgEntries & entries) -> bool
|
||||||
{ return title.compare(entries.getTitle(), caseSensitivity) == 0; });
|
{ return title.compare(entries.getTitle(), caseSensitivity) == 0; });
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
const QStringList &CAircraftCfgEntriesList::excludeDirectories()
|
||||||
* Read all entrities in given directory
|
{
|
||||||
*/
|
static const QStringList exclude
|
||||||
|
{
|
||||||
|
// "SimObjects/Misc",
|
||||||
|
"SimObjects/Animals",
|
||||||
|
"SimObjects/GroundVehicles",
|
||||||
|
"SimObjects/Boats"
|
||||||
|
};
|
||||||
|
return exclude;
|
||||||
|
}
|
||||||
|
|
||||||
int CAircraftCfgEntriesList::read(const QString &directory, const QStringList &excludeDirectories)
|
int CAircraftCfgEntriesList::read(const QString &directory, const QStringList &excludeDirectories)
|
||||||
{
|
{
|
||||||
if (m_cancelRead) { return -1; }
|
if (m_cancelRead) { return -1; }
|
||||||
@@ -121,104 +132,168 @@ namespace BlackMisc
|
|||||||
|
|
||||||
// set directory with name filters, get aircraft.cfg and sub directories
|
// set directory with name filters, get aircraft.cfg and sub directories
|
||||||
QDir dir(directory, "aircraft.cfg", QDir::Name, QDir::Files | QDir::AllDirs);
|
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
|
if (!dir.exists()) return 0; // can happen if there are shortcuts or linked dirs not available
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
QString currentDir = dir.absolutePath();
|
QString currentDir = dir.absolutePath();
|
||||||
|
|
||||||
// Dirs last is crucial,since I will break recursion on "aircraft.cfg" level
|
// Dirs last is crucial, since I will break recursion on ".cfg" level
|
||||||
|
// once I have found .cfg, I do not go any deeper
|
||||||
QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::AllDirs, QDir::DirsLast);
|
QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::AllDirs, QDir::DirsLast);
|
||||||
|
|
||||||
for (const QFileInfo &file : files)
|
for (const QFileInfo &file : files)
|
||||||
{
|
{
|
||||||
if (m_cancelRead) { return -1; }
|
if (m_cancelRead) { return -1; }
|
||||||
if (file.isDir())
|
if (file.isDir())
|
||||||
{
|
{
|
||||||
QString nextDir = file.absoluteFilePath();
|
QString nextDir = file.absoluteFilePath();
|
||||||
if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) continue; // do not go up
|
if (currentDir.startsWith(nextDir, Qt::CaseInsensitive)) { continue; } // do not go up
|
||||||
if (dir == currentDir) { continue; } // do not recursively call same directory
|
if (dir == currentDir) { continue; } // do not recursively call same directory
|
||||||
counter += CAircraftCfgEntriesList::read(nextDir, excludeDirectories);
|
counter += CAircraftCfgEntriesList::read(nextDir, excludeDirectories);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// due to the filter we expect only "aircraft.cfg" here
|
// due to the filter we expect only ".cfg" here
|
||||||
QString path = file.absoluteFilePath();
|
// remark: in a 1st version I have used QSettings to parse to file as ini file
|
||||||
|
// unfortunately some files are malformed which could end up in wrong data
|
||||||
// I abuse the QSettings as ini-file reader
|
QString fileName = file.absoluteFilePath();
|
||||||
QSettings aircraftCfg(path, QSettings::IniFormat);
|
QFile file(fileName);
|
||||||
|
if (!file.open(QFile::ReadOnly | QFile::Text))
|
||||||
// from the general section
|
|
||||||
const QString atcType = aircraftCfg.value("atc_type").toString();
|
|
||||||
const QString atcModel = aircraftCfg.value("atc_model").toString();
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
while (index >= 0)
|
|
||||||
{
|
{
|
||||||
if (m_cancelRead) { return -1; }
|
CLogMessage(this).warning("Unable to read file %1") << fileName;
|
||||||
QString group = QString("fltsim.%1").arg(index);
|
continue;
|
||||||
aircraftCfg.beginGroup(group);
|
|
||||||
|
|
||||||
// does group exist?
|
|
||||||
if (aircraftCfg.contains("title"))
|
|
||||||
{
|
|
||||||
QString title = fixedStringContent(aircraftCfg, "title");
|
|
||||||
if (!title.isEmpty())
|
|
||||||
{
|
|
||||||
CAircraftCfgEntries entry(path, index, title, atcType, atcModel, "", "");
|
|
||||||
entry.setAtcParkingCode(fixedStringContent(aircraftCfg, "atc_parking_codes"));
|
|
||||||
entry.setDescription(fixedStringContent(aircraftCfg, "description"));
|
|
||||||
entry.setUiManufacturer(fixedStringContent(aircraftCfg, "ui_manufacturer"));
|
|
||||||
entry.setUiType(fixedStringContent(aircraftCfg, "ui_type"));
|
|
||||||
entry.setTexture(fixedStringContent(aircraftCfg, "texture"));
|
|
||||||
this->push_back(entry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CLogMessage(this).info("FSX model in %1, index %2 has no title") << path << index;
|
|
||||||
}
|
|
||||||
++index;
|
|
||||||
++counter;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// marks end of the "fltsim.x" groups
|
|
||||||
index = -1;
|
|
||||||
}
|
|
||||||
aircraftCfg.endGroup();
|
|
||||||
}
|
}
|
||||||
break;
|
QTextStream in(&file);
|
||||||
}
|
QList<CAircraftCfgEntries> tempEntries;
|
||||||
}
|
|
||||||
|
// parse through the file
|
||||||
|
QString atcType;
|
||||||
|
QString atcModel;
|
||||||
|
QString fltSection("[FLTSIM.0]");
|
||||||
|
int fltsimCounter = 0;
|
||||||
|
FileSection currentSection = Unknown;
|
||||||
|
bool isRotorcraftPath = fileName.toLower().contains("rotorcraft");
|
||||||
|
|
||||||
|
while (!in.atEnd())
|
||||||
|
{
|
||||||
|
const QString lineFixed(in.readLine().trimmed());
|
||||||
|
if (lineFixed.isEmpty()) { continue; }
|
||||||
|
if (lineFixed.startsWith("["))
|
||||||
|
{
|
||||||
|
if (lineFixed.startsWith("[GENERAL]", Qt::CaseInsensitive)) { currentSection = General; continue; }
|
||||||
|
if (lineFixed.startsWith(fltSection, Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
CAircraftCfgEntries e(fileName, fltsimCounter);
|
||||||
|
if (isRotorcraftPath)
|
||||||
|
{
|
||||||
|
e.setRotorcraft(true);
|
||||||
|
}
|
||||||
|
tempEntries.append(e);
|
||||||
|
currentSection = Fltsim;
|
||||||
|
fltSection = QString("[FLTSIM.%1]").arg(++fltsimCounter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentSection = Unknown;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (currentSection)
|
||||||
|
{
|
||||||
|
case General:
|
||||||
|
{
|
||||||
|
if (lineFixed.startsWith("//")) { break; }
|
||||||
|
if (atcType.isEmpty() || atcModel.isEmpty())
|
||||||
|
{
|
||||||
|
QString c = getFixedIniLineContent(lineFixed);
|
||||||
|
if (lineFixed.startsWith("atc_type", Qt::CaseInsensitive)) { atcType = c; }
|
||||||
|
else if (lineFixed.startsWith("atc_model", Qt::CaseInsensitive)) { atcModel = c; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Fltsim:
|
||||||
|
{
|
||||||
|
if (lineFixed.startsWith("//")) { break; }
|
||||||
|
CAircraftCfgEntries &e = tempEntries[tempEntries.size() - 1];
|
||||||
|
if (lineFixed.startsWith("atc_parking_codes", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
e.setAtcParkingCode(getFixedIniLineContent(lineFixed));
|
||||||
|
}
|
||||||
|
else if (lineFixed.startsWith("description", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
e.setDescription(getFixedIniLineContent(lineFixed));
|
||||||
|
}
|
||||||
|
else if (lineFixed.startsWith("ui_manufacturer", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
e.setUiManufacturer(getFixedIniLineContent(lineFixed));
|
||||||
|
}
|
||||||
|
else if (lineFixed.startsWith("ui_typerole", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
bool r = getFixedIniLineContent(lineFixed).toLower().contains("rotor");
|
||||||
|
e.setRotorcraft(r);
|
||||||
|
}
|
||||||
|
else if (lineFixed.startsWith("ui_type", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
e.setUiType(getFixedIniLineContent(lineFixed));
|
||||||
|
}
|
||||||
|
else if (lineFixed.startsWith("texture", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
e.setTexture(getFixedIniLineContent(lineFixed));
|
||||||
|
}
|
||||||
|
else if (lineFixed.startsWith("title", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
e.setTitle(getFixedIniLineContent(lineFixed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case Unknown: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // all lines
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// store all entries
|
||||||
|
for (const CAircraftCfgEntries &e : tempEntries)
|
||||||
|
{
|
||||||
|
if (e.getTitle().isEmpty())
|
||||||
|
{
|
||||||
|
CLogMessage(this).info("FSX model in %1, index %2 has no title") << fileName << e.getIndex();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CAircraftCfgEntries newEntries(e);
|
||||||
|
newEntries.setAtcModel(atcModel);
|
||||||
|
newEntries.setAtcType(atcType);
|
||||||
|
this->push_back(newEntries);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
return counter; // do not go any deeper in file tree, we found aircraft.cfg
|
||||||
|
|
||||||
|
} // file, no directory
|
||||||
|
} // files
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAircraftCfgEntriesList::fixedStringContent(const QSettings &settings, const QString &key)
|
QString CAircraftCfgEntriesList::getFixedIniLineContent(const QString &line)
|
||||||
{
|
{
|
||||||
return fixedStringContent(settings.value(key));
|
if (line.isEmpty()) { return ""; }
|
||||||
|
int index = line.indexOf('=');
|
||||||
|
if (index < 0) { return ""; }
|
||||||
|
if (line.length() < index + 1) { return ""; }
|
||||||
|
|
||||||
|
QString content(line.mid(index + 1).trimmed());
|
||||||
|
|
||||||
|
// fix "" strings, some are malformed and just contain " at beginning, end
|
||||||
|
if (content.endsWith('"')) { content.remove(content.size() - 1 , 1); }
|
||||||
|
if (content.startsWith('"')) { content.remove(0 , 1); }
|
||||||
|
|
||||||
|
// fix C style linebreaks
|
||||||
|
content.replace("\\n", " ");
|
||||||
|
content.replace("\\t", " ");
|
||||||
|
|
||||||
|
// return
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAircraftCfgEntriesList::fixedStringContent(const QVariant &qv)
|
|
||||||
{
|
|
||||||
if (qv.isNull() || !qv.isValid())
|
|
||||||
{
|
|
||||||
return ""; // normal when there is no settings value
|
|
||||||
}
|
|
||||||
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QStringList)
|
|
||||||
{
|
|
||||||
QStringList l = qv.toStringList();
|
|
||||||
return l.join(",").trimmed();
|
|
||||||
}
|
|
||||||
else if (static_cast<QMetaType::Type>(qv.type()) == QMetaType::QString)
|
|
||||||
{
|
|
||||||
return qv.toString().trimmed();
|
|
||||||
}
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register metadata
|
|
||||||
*/
|
|
||||||
void CAircraftCfgEntriesList::registerMetadata()
|
void CAircraftCfgEntriesList::registerMetadata()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<BlackMisc::CSequence<CAircraftCfgEntries>>();
|
qRegisterMetaType<BlackMisc::CSequence<CAircraftCfgEntries>>();
|
||||||
|
|||||||
@@ -39,26 +39,10 @@ namespace BlackMisc
|
|||||||
CAircraftCfgEntriesList(const QString &rootDirectory = "") : m_rootDirectory(rootDirectory) {}
|
CAircraftCfgEntriesList(const QString &rootDirectory = "") : m_rootDirectory(rootDirectory) {}
|
||||||
|
|
||||||
//! Read all aircraft.cfg files starting from root directory
|
//! Read all aircraft.cfg files starting from root directory
|
||||||
int read()
|
int 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, excludeDirectories());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Change the directory
|
//! Change the directory
|
||||||
bool changeDirectory(const QString &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));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Virtual destructor
|
//! Virtual destructor
|
||||||
virtual ~CAircraftCfgEntriesList() {}
|
virtual ~CAircraftCfgEntriesList() {}
|
||||||
@@ -97,17 +81,7 @@ namespace BlackMisc
|
|||||||
void convertFromQVariant(const QVariant &variant) { BlackMisc::setFromQVariant(this, variant); }
|
void convertFromQVariant(const QVariant &variant) { BlackMisc::setFromQVariant(this, variant); }
|
||||||
|
|
||||||
//! Do not include the following directories for FS
|
//! Do not include the following directories for FS
|
||||||
static const QStringList &excludeDirectories()
|
static const QStringList &excludeDirectories();
|
||||||
{
|
|
||||||
static const QStringList exclude
|
|
||||||
{
|
|
||||||
"SimObjects/Animals",
|
|
||||||
"SimObjects/Misc",
|
|
||||||
"SimObjects/GroundVehicles",
|
|
||||||
"SimObjects/Boats"
|
|
||||||
};
|
|
||||||
return exclude;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Register metadata
|
//! Register metadata
|
||||||
static void registerMetadata();
|
static void registerMetadata();
|
||||||
@@ -120,11 +94,16 @@ namespace BlackMisc
|
|||||||
//! Read all entries in one directory
|
//! Read all entries in one directory
|
||||||
int read(const QString &directory, const QStringList &excludeDirectories = QStringList());
|
int read(const QString &directory, const QStringList &excludeDirectories = QStringList());
|
||||||
|
|
||||||
//! Fix the content read
|
//! Section within file
|
||||||
static QString fixedStringContent(const QVariant &qv);
|
enum FileSection
|
||||||
|
{
|
||||||
|
General,
|
||||||
|
Fltsim,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
//! Value from settings, fixed string
|
//! Content after "="
|
||||||
static QString fixedStringContent(const QSettings &settings, const QString &key);
|
static QString getFixedIniLineContent(const QString &line);
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
Reference in New Issue
Block a user