mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 11:55:35 +08:00
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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
//! @}
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
//! @}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user