refs #643, moved aircraft model icon loading to model class

* removed iconForModel from interface and aircraft config parser
* CPixmap support for loading pixmap from file
* Access to model of model set loader by model string
* icon path as member of CAircraftModel
This commit is contained in:
Klaus Basan
2016-04-15 18:49:55 +02:00
parent a3a3380008
commit ddc7347927
20 changed files with 143 additions and 67 deletions

View File

@@ -146,9 +146,9 @@ namespace BlackCore
// with an interpolator the interpolated situation is used
// to avoid position jittering when displayed
qint64 time = QDateTime::currentMSecsSinceEpoch();
const qint64 time = QDateTime::currentMSecsSinceEpoch();
IInterpolator::InterpolationStatus interpolationStatus;
CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, aircraft.isVtol(), interpolationStatus));
const CAircraftSituation as(m_interpolator->getInterpolatedSituation(callsign, time, aircraft.isVtol(), interpolationStatus));
if (interpolationStatus.interpolationSucceeded)
{
aircraft.setSituation(as);

View File

@@ -72,6 +72,7 @@ namespace BlackGui
// this->m_columns.addColumn(CColumn::standardString("ct", "combined type", { CAircraftModel::IndexIcao, CAircraftIcaoData::IndexCombinedAircraftType}));
this->m_columns.addColumn(CColumn::standardString("description", CAircraftModel::IndexDescription));
this->m_columns.addColumn(CColumn::standardString("filename", CAircraftModel::IndexFileName));
this->m_columns.addColumn(CColumn::standardString("icon", CAircraftModel::IndexIconPath));
this->m_columns.addColumn(CColumn::standardString("changed", CAircraftModel::IndexUtcTimestampFormattedYmdhms));
// default sort order

View File

@@ -9,6 +9,7 @@
#include "pixmap.h"
#include <QBuffer>
#include <QFile>
#include <tuple>
namespace BlackMisc
@@ -69,6 +70,31 @@ namespace BlackMisc
return "Pixmap";
}
CPixmap CPixmap::loadFromFile(const QString &filePath, CStatusMessage &msg)
{
if (filePath.isEmpty())
{
msg = CStatusMessage(CStatusMessage::SeverityError, "no file path");
return CPixmap();
}
if (!QFile(filePath).exists())
{
msg = CStatusMessage().error("file %1 does not exist") << filePath;
return CPixmap();
}
QPixmap pm;
if (pm.load(filePath))
{
msg = CStatusMessage().info("file %1 loaded") << filePath;
return CPixmap(pm);
}
else
{
msg = CStatusMessage().error("file %1 not loaded") << filePath;
return CPixmap();
}
}
QPixmap CPixmap::toPixmap() const
{
return this->pixmap();

View File

@@ -14,6 +14,7 @@
#include "blackmiscexport.h"
#include "valueobject.h"
#include "statusmessage.h"
#include <QPixmap>
#include <QReadWriteLock>
@@ -51,6 +52,9 @@ namespace BlackMisc
//! \copydoc BlackMisc::Mixin::String::toQString
QString convertToQString(bool i18n = false) const;
//! Load from file
static CPixmap loadFromFile(const QString &filePath, CStatusMessage &msg);
private:
//! Init the byte array with data
void fillByteArray();

View File

@@ -134,6 +134,8 @@ namespace BlackMisc
return CVariant(this->m_name);
case IndexFileName:
return CVariant(this->m_fileName);
case IndexIconPath:
return CVariant(this->m_iconPath);
case IndexAircraftIcaoCode:
return m_aircraftIcao.propertyByIndex(index.copyFrontRemoved());
case IndexLivery:
@@ -180,6 +182,9 @@ namespace BlackMisc
case IndexFileName:
this->m_fileName = variant.toQString();
break;
case IndexIconPath:
this->m_iconPath = variant.toQString();
break;
case IndexModelType:
this->m_modelType = variant.value<ModelType>();
break;
@@ -225,6 +230,8 @@ namespace BlackMisc
return this->m_callsign.comparePropertyByIndex(compareValue.getCallsign(), index.copyFrontRemoved());
case IndexFileName:
return this->m_fileName.compare(compareValue.getFileName(), Qt::CaseInsensitive);
case IndexIconPath:
return this->m_iconPath.compare(compareValue.getIconPath(), Qt::CaseInsensitive);
case IndexModelType:
return Compare::compare(this->m_modelType, compareValue.getModelType());
case IndexModelMode:
@@ -335,6 +342,16 @@ namespace BlackMisc
return (static_cast<int>(simulator.getSimulator()) & static_cast<int>(this->getSimulatorInfo().getSimulator())) > 0;
}
CPixmap CAircraftModel::loadIcon(CStatusMessage &success) const
{
static const CStatusMessage noIcon(this, CStatusMessage::SeverityInfo, "no icon");
if (this->m_iconPath.isEmpty()) { success = noIcon; return CPixmap(); }
// load from file
const CPixmap pm(CPixmap::loadFromFile(this->m_iconPath, success));
return pm;
}
QString CAircraftModel::getSwiftLiveryString() const
{
const QString cc(this->getLivery().getCombinedCode());
@@ -360,6 +377,7 @@ namespace BlackMisc
if (this->m_modelString.isEmpty()) { this->setModelString(otherModel.getModelString()); }
if (this->m_description.isEmpty()) { this->setDescription(otherModel.getDescription()); }
if (this->m_fileName.isEmpty()) { this->setFileName(otherModel.getFileName()); }
if (this->m_iconPath.isEmpty()) { this->setIconPath(otherModel.getIconPath()); }
if (this->m_callsign.isEmpty()) { this->setCallsign(otherModel.getCallsign()); }
if (this->m_modelType == TypeUnknown) { this->m_modelType = otherModel.getModelType(); }
if (this->m_modelMode == Undefined) { this->m_modelType = otherModel.getModelType(); }

View File

@@ -19,6 +19,7 @@
#include "blackmisc/aviation/aircrafticaocode.h"
#include "blackmisc/network/user.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/pixmap.h"
#include <QUrlQuery>
namespace BlackMisc
@@ -71,6 +72,7 @@ namespace BlackMisc
IndexLivery,
IndexDistributor,
IndexFileName,
IndexIconPath,
IndexModelType,
IndexModelTypeAsString,
IndexModelMode,
@@ -242,6 +244,15 @@ namespace BlackMisc
//! File name
void setFileName(const QString &fileName) { m_fileName = fileName; }
//! File representing model
const QString &getIconPath() const { return m_iconPath; }
//! File representing model
void setIconPath(const QString &iconFile) { m_iconPath = iconFile; }
//! Load icon from disk
CPixmap loadIcon(CStatusMessage &success) const;
//! swift livery string (to be sent via network), "liveryCode [modelString]";
//! \sa splitNetworkLiveryString
QString getSwiftLiveryString() const;
@@ -309,6 +320,7 @@ namespace BlackMisc
QString m_name; //!< Model name
QString m_description; //!< descriptive text
QString m_fileName; //!< file name
QString m_iconPath; //!< a file representing the aircraft as icon
ModelType m_modelType = TypeUnknown; //!< model string is coming representing ...?
ModelMode m_modelMode = Include; //!< model mode (include / exclude)
@@ -325,6 +337,7 @@ namespace BlackMisc
BLACK_METAMEMBER(name),
BLACK_METAMEMBER(description, 0, DisabledForComparison),
BLACK_METAMEMBER(fileName, 0, DisabledForComparison),
BLACK_METAMEMBER(iconPath, 0, DisabledForComparison),
BLACK_METAMEMBER(modelType),
BLACK_METAMEMBER(modelMode)
);

View File

@@ -59,6 +59,15 @@ namespace BlackMisc
});
}
CAircraftModel CAircraftModelList::findFirstByCallsignOrDefault(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return CAircraftModel(); }
return this->findFirstByOrDefault([ = ](const CAircraftModel & model)
{
return model.getCallsign() == callsign;
});
}
CAircraftModelList CAircraftModelList::findByIcaoDesignators(const CAircraftIcaoCode &aircraftIcaoCode, const CAirlineIcaoCode &airlineIcaoCode) const
{
const QString aircraft(aircraftIcaoCode.getDesignator());
@@ -180,6 +189,20 @@ namespace BlackMisc
});
}
QString CAircraftModelList::findModelIconPathByModelString(const QString &modelString) const
{
if (modelString.isEmpty()) { return ""; }
const CAircraftModel m(findFirstByModelStringOrDefault(modelString, Qt::CaseInsensitive));
return m.getIconPath();
}
QString CAircraftModelList::findModelIconPathByCallsign(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return ""; }
const CAircraftModel m(findFirstByCallsignOrDefault(callsign));
return m.getIconPath();
}
QString CAircraftModelList::designatorToFamily(const CAircraftIcaoCode &aircraftIcaoCode) const
{
if (aircraftIcaoCode.hasFamily()) { return aircraftIcaoCode.getFamily(); }

View File

@@ -45,12 +45,15 @@ namespace BlackMisc
bool containsModelStringOrDbKey(const BlackMisc::Simulation::CAircraftModel &model, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
//! Find by model string
//! \remark normally CAircraftModelList::findFirstByModelString would be used
//! \remark normally CAircraftModelList::findFirstByModelStringOrDefault would be used
CAircraftModelList findByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
//! Find first by model string
CAircraftModel findFirstByModelStringOrDefault(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
//! Find first by callsign
CAircraftModel findFirstByCallsignOrDefault(const BlackMisc::Aviation::CCallsign &callsign) const;
//! Find models starting with
CAircraftModelList findModelsStartingWith(const QString &modelString, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive) const;
@@ -96,6 +99,12 @@ namespace BlackMisc
//! Find by military flag
CAircraftModelList findByMilitaryFlag(bool military) const;
//! Model icon path
QString findModelIconPathByModelString(const QString &modelString) const;
//! Model icon path
QString findModelIconPathByCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
//! Take a designator and find its family
QString designatorToFamily(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode) const;

View File

@@ -83,9 +83,6 @@ namespace BlackMisc
//! Model files updated?
virtual bool areModelFilesUpdated() const = 0;
//! A representive pixmap for given model
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const = 0;
//! Which simulator is supported by that very loader
const BlackMisc::Simulation::CSimulatorInfo &getSimulator() const;
@@ -101,7 +98,7 @@ namespace BlackMisc
//! Shutdown
void gracefulShutdown();
//! \name Implementations of the models interfaces
//! \name Implementations of the model interfaces (allows to set models modified in utility functions)
//! @{
virtual void setModels(const CAircraftModelList &models) override { this->setCachedModels(models, this->m_simulatorInfo); }
virtual void updateModels(const CAircraftModelList &models) override { this->replaceOrAddCachedModels(models, this->m_simulatorInfo); }

View File

@@ -66,6 +66,18 @@ namespace BlackMisc
return this->m_caches.getCachedModels(this->m_simulatorInfo);
}
CAircraftModelList CAircraftModelSetLoader::getAircraftModels(const CSimulatorInfo &simulator) const
{
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
return this->m_caches.getCachedModels(simulator);
}
CAircraftModel CAircraftModelSetLoader::getModelForModelString(const QString &modelString) const
{
if (modelString.isEmpty()) { return CAircraftModel(); }
return this->getAircraftModels().findFirstByModelStringOrDefault(modelString);
}
QDateTime CAircraftModelSetLoader::getCacheTimestamp() const
{
return this->m_caches.getCacheTimestamp(this->m_simulatorInfo);

View File

@@ -50,8 +50,13 @@ namespace BlackMisc
BlackMisc::Simulation::CAircraftModelList getAircraftModels() const;
//! Count of loaded models
//! \threadsafe
int getAircraftModelsCount() const { return getAircraftModels().size(); }
//! Model for given model string
//! \threadsafe
BlackMisc::Simulation::CAircraftModel getModelForModelString(const QString &modelString) const;
//! Which simulator is supported by that very loader
const BlackMisc::Simulation::CSimulatorInfo &getSimulator() const;

View File

@@ -120,6 +120,7 @@ namespace BlackMisc
model.setFileName(this->getFileName());
model.setName(this->getSimName());
model.setUtcTimestamp(this->getUtcTimestamp()); // aircraft.cfg file last modified
model.setIconPath(this->getThumbnailFileName());
const QString designator(CAircraftIcaoCode::normalizeDesignator(getAtcModel()));
CAircraftIcaoCode aircraft(

View File

@@ -67,34 +67,6 @@ namespace BlackMisc
if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); }
}
CPixmap CAircraftCfgParser::iconForModel(const QString &modelString, CStatusMessage &statusMessage) const
{
static const CPixmap empty {};
if (modelString.isEmpty()) { return empty; }
CAircraftCfgEntriesList cfgEntries = this->getAircraftCfgEntriesList().findByTitle(modelString);
if (cfgEntries.isEmpty())
{
statusMessage = CStatusMessage(CStatusMessage::SeverityWarning, QString("No .cfg entry for '%1'").arg(modelString));
return empty;
}
// normally we should have only one entry
if (cfgEntries.size() > 1)
{
statusMessage = CStatusMessage(CStatusMessage::SeverityWarning, QString("Multiple FSX .cfg entries for '%1'").arg(modelString));
}
// use first with icon
for (const CAircraftCfgEntries &entry : cfgEntries)
{
const QString thumbnail = entry.getThumbnailFileName();
if (thumbnail.isEmpty()) { continue; }
QPixmap pm;
if (pm.load(thumbnail)) { return CPixmap(pm); }
}
return empty;
}
void CAircraftCfgParser::startLoadingFromDisk(LoadMode mode, const CAircraftModelList &dbModels)
{
if (mode.testFlag(LoadInBackground))

View File

@@ -45,7 +45,6 @@ namespace BlackMisc
//! \name Interface functions
//! @{
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const override;
virtual bool isLoadingFinished() const override;
virtual bool areModelFilesUpdated() const override;
//! @}

View File

@@ -313,6 +313,9 @@ namespace BlackMisc
//! Get model
const BlackMisc::Simulation::CAircraftModel &getModel() const { return m_model; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getIconPath
const QString &getIconPath() const { return m_model.getIconPath(); }
//! Get model string
QString getModelString() const { return m_model.getModelString(); }

View File

@@ -55,14 +55,6 @@ namespace BlackMisc
if (this->m_parserWorker) { this->m_parserWorker->waitForFinished(); }
}
CPixmap CAircraftModelLoaderXPlane::iconForModel(const QString &modelString, CStatusMessage &statusMessage) const
{
// X-Plane does not have previews. Maybe we can just use the textures?
Q_UNUSED(modelString)
Q_UNUSED(statusMessage)
return {};
}
void CAircraftModelLoaderXPlane::startLoadingFromDisk(LoadMode mode, const CAircraftModelList &dbModels)
{
if (m_rootDirectory.isEmpty())

View File

@@ -43,7 +43,6 @@ namespace BlackMisc
//! \name Interface functions
//! @{
virtual BlackMisc::CPixmap iconForModel(const QString &modelName, BlackMisc::CStatusMessage &statusMessage) const override;
virtual bool isLoadingFinished() const override;
virtual bool areModelFilesUpdated() const override;
//! @}

View File

@@ -98,9 +98,11 @@ namespace BlackSimPlugin
CPixmap CSimulatorFsCommon::iconForModel(const QString &modelString) const
{
const CAircraftModel model(this->m_modelSetLoader.getModelForModelString(modelString));
// load from file
CStatusMessage msg;
// CPixmap pm(m_aircraftCfgParser->iconForModel(modelString, msg));
CPixmap pm;
const CPixmap pm(model.loadIcon(msg));
if (!msg.isEmpty()) { CLogMessage::preformatted(msg);}
return pm;
}