mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 11:55:35 +08:00
Allow to update model directories
This commit is contained in:
@@ -200,6 +200,56 @@ namespace BlackCore
|
||||
return consolidatedModels;
|
||||
}
|
||||
|
||||
CAircraftModelList CDatabaseUtils::updateModelsDirectoriesAllowsGuiRefresh(const CAircraftModelList &models, const CAircraftModelList &simulatorModels, QStringList &removedModelStrings, bool processEvents)
|
||||
{
|
||||
if (models.isEmpty() || simulatorModels.isEmpty()) { return models; }
|
||||
|
||||
QTime timer;
|
||||
timer.start();
|
||||
const QSet<QString> allOwnModelsModelStrings = simulatorModels.getModelStringSet();
|
||||
CAircraftModelList consolidatedModels;
|
||||
removedModelStrings.clear();
|
||||
|
||||
int c = 0;
|
||||
for (const CAircraftModel &model : models)
|
||||
{
|
||||
c++;
|
||||
if (processEvents && c % 125 == 0)
|
||||
{
|
||||
if (!sApp || sApp->isShuttingDown()) { return models; }
|
||||
sApp->processEventsFor(25);
|
||||
}
|
||||
|
||||
const QString ms(model.getModelString());
|
||||
if (ms.isEmpty()) { continue; }
|
||||
if (!allOwnModelsModelStrings.contains(ms))
|
||||
{
|
||||
removedModelStrings.push_back(ms);
|
||||
continue;
|
||||
}
|
||||
CAircraftModel consolidated = simulatorModels.findFirstByModelStringAliasOrDefault(ms);
|
||||
if (consolidated.hasModelString())
|
||||
{
|
||||
if (consolidated.hasExistingCorrespondingFile())
|
||||
{
|
||||
// update by existing one
|
||||
consolidatedModels.push_back(consolidated);
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep
|
||||
consolidatedModels.push_back(model);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
consolidatedModels.push_back(model);
|
||||
}
|
||||
}
|
||||
CLogMessage(static_cast<CDatabaseUtils *>(nullptr)).info(u"Updated directories %1 vs. %2 in %3 ms") << models.size() << simulatorModels.size() << timer.elapsed() << "ms";
|
||||
return consolidatedModels;
|
||||
}
|
||||
|
||||
int CDatabaseUtils::consolidateModelsWithDbDataAllowsGuiRefresh(CAircraftModelList &models, bool force, bool processEvents)
|
||||
{
|
||||
QTime timer;
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace BlackCore
|
||||
//! \remark kept here with the other consolidate functions, but actually DB independent
|
||||
static BlackMisc::Simulation::CAircraftModelList consolidateModelsWithSimulatorModelsAllowsGuiRefresh(const BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::Simulation::CAircraftModelList &simulatorModels, QStringList &removedModelStrings, bool processEvents);
|
||||
|
||||
//! Update directories in models with simulator model data (aka "models on disk")
|
||||
//! \remark kept here with the other consolidate functions, but actually DB independent
|
||||
static BlackMisc::Simulation::CAircraftModelList updateModelsDirectoriesAllowsGuiRefresh(const BlackMisc::Simulation::CAircraftModelList &models, const BlackMisc::Simulation::CAircraftModelList &simulatorModels, QStringList &removedModelStrings, bool processEvents);
|
||||
|
||||
//! Consolidate own (aircraft) model data with DB data
|
||||
static BlackMisc::Simulation::CAircraftModel consolidateOwnAircraftModelWithDbData(const BlackMisc::Simulation::CAircraftModel &model, bool force, bool *modified = nullptr);
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
if (m_messageFrame && !model.getIconPath().isEmpty())
|
||||
if (m_messageFrame && !model.getIconFile().isEmpty())
|
||||
{
|
||||
added = true;
|
||||
menuActions.addMenuSimulator();
|
||||
@@ -133,7 +133,7 @@ namespace BlackGui
|
||||
const CAircraftModelView *mv = modelView();
|
||||
if (!mv->hasSingleSelectedRow()) { return; }
|
||||
const CAircraftModel model(mv->selectedObject());
|
||||
if (model.getIconPath().isEmpty()) { return; }
|
||||
if (model.getIconFile().isEmpty()) { return; }
|
||||
CStatusMessage msg(this);
|
||||
const CPixmap pm(model.loadIcon(msg));
|
||||
if (msg.isSuccess())
|
||||
@@ -288,11 +288,14 @@ namespace BlackGui
|
||||
|
||||
menuActions.addMenuConsolidateModels();
|
||||
|
||||
// consolidate
|
||||
m_consolidateAll = menuActions.addAction(m_consolidateAll, CIcons::appModels16(), "All with simulator models", CMenuAction::pathModelConsolidate(), { this, &CConsolidateWithSimulatorModels::consolidateData });
|
||||
if (mv->hasSelection())
|
||||
{
|
||||
m_consolidateSelected = menuActions.addAction(m_consolidateSelected, CIcons::appModels16(), "Selected with simulator models", CMenuAction::pathModelConsolidate(), { this, &CConsolidateWithSimulatorModels::consolidateSelectedData });
|
||||
}
|
||||
if (mv->hasSelection()) { m_consolidateSelected = menuActions.addAction(m_consolidateSelected, CIcons::appModels16(), "Selected with simulator models", CMenuAction::pathModelConsolidate(), { this, &CConsolidateWithSimulatorModels::consolidateSelectedData }); }
|
||||
|
||||
// update directories
|
||||
m_updateDirsAll = menuActions.addAction(m_updateDirsAll, CIcons::disk16(), "Update all directories", CMenuAction::pathModelConsolidate(), { this, &CConsolidateWithSimulatorModels::updateDirectoryData });
|
||||
if (mv->hasSelection()) { m_updateDirsSelected = menuActions.addAction(m_updateDirsSelected, CIcons::disk16(), "Update directories for selected", CMenuAction::pathModelConsolidate(), { this, &CConsolidateWithSimulatorModels::updateDirectorySelectedData }); }
|
||||
|
||||
this->nestedCustomMenu(menuActions);
|
||||
}
|
||||
|
||||
@@ -354,6 +357,64 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
void CConsolidateWithSimulatorModels::updateDirectoryData()
|
||||
{
|
||||
bool filtered = false;
|
||||
const CAircraftModelList models(this->getAllOrAllFilteredAircraftModels(&filtered));
|
||||
if (models.isEmpty()) { return; }
|
||||
QStringList removedModelStrings;
|
||||
const int i = this->modelView()->showLoadIndicator();
|
||||
const CAircraftModelList consolidated = CDatabaseUtils::updateModelsDirectoriesAllowsGuiRefresh(models, this->getSimulatorModels(), removedModelStrings, true);
|
||||
const CSimulatorInfo sim(this->getSimulator());
|
||||
|
||||
if (!filtered)
|
||||
{
|
||||
this->modelsTargetSetable()->setModelsForSimulator(consolidated, sim);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this->modelsTargetUpdatable())
|
||||
{
|
||||
CLogMessage(this).warning(u"No updatable target");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->modelsTargetUpdatable()->updateModelsForSimulator(consolidated, sim);
|
||||
}
|
||||
}
|
||||
this->modelView()->hideLoadIndicator(i);
|
||||
if (!removedModelStrings.isEmpty() && this->getMappingComponent())
|
||||
{
|
||||
const CStatusMessage m = CStatusMessage(this).info(u"Removed %1 model(s)") << removedModelStrings.size();
|
||||
this->getMappingComponent()->showOverlayMessage(m, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
void CConsolidateWithSimulatorModels::updateDirectorySelectedData()
|
||||
{
|
||||
Q_ASSERT_X(sGui, Q_FUNC_INFO, "Missing sGui");
|
||||
const CAircraftModelList models(this->getSelectedAircraftModels());
|
||||
if (models.isEmpty()) { return; }
|
||||
if (!this->modelsTargetUpdatable())
|
||||
{
|
||||
CLogMessage(this).warning(u"No updatable target");
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList removedModelStrings;
|
||||
const int i = this->modelView()->showLoadIndicator();
|
||||
const CAircraftModelList consolidated = CDatabaseUtils::updateModelsDirectoriesAllowsGuiRefresh(models, this->getSimulatorModels(), removedModelStrings, true);
|
||||
const CSimulatorInfo sim(this->getSimulator());
|
||||
|
||||
this->modelsTargetUpdatable()->updateModelsForSimulator(consolidated, sim);
|
||||
this->modelView()->hideLoadIndicator(i);
|
||||
if (!removedModelStrings.isEmpty() && this->getMappingComponent())
|
||||
{
|
||||
const CStatusMessage m = CStatusMessage(this).info(u"Removed %1 model(s)") << removedModelStrings.size();
|
||||
this->getMappingComponent()->showOverlayMessage(m, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
CAircraftModelList CConsolidateWithSimulatorModels::getSimulatorModels() const
|
||||
{
|
||||
CDbMappingComponent *mc = this->getMappingComponent();
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace BlackGui
|
||||
QAction *m_consolidateSelected = nullptr; //!< consolidate data with DB (selected)
|
||||
};
|
||||
|
||||
//! Merge with simulator models (e.g. remove no longer existing models)
|
||||
//! Merge/update with simulator models (e.g. remove no longer existing models)
|
||||
class CConsolidateWithSimulatorModels : public IAircraftModelViewMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -136,6 +136,8 @@ namespace BlackGui
|
||||
private:
|
||||
void consolidateData();
|
||||
void consolidateSelectedData();
|
||||
void updateDirectoryData();
|
||||
void updateDirectorySelectedData();
|
||||
|
||||
//! Get models
|
||||
BlackMisc::Simulation::CAircraftModelList getSimulatorModels() const;
|
||||
@@ -151,6 +153,8 @@ namespace BlackGui
|
||||
QObject *m_modelsTarget = nullptr; //!< optional target for setting/updating the models
|
||||
QAction *m_consolidateAll = nullptr; //!< consolidate data with DB (all)
|
||||
QAction *m_consolidateSelected = nullptr; //!< consolidate data with DB (selected)
|
||||
QAction *m_updateDirsAll = nullptr; //!< consolidate file name/dir (all)
|
||||
QAction *m_updateDirsSelected = nullptr; //!< consolidate file name/dir (selected)
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
@@ -258,7 +258,7 @@ namespace BlackMisc
|
||||
case IndexSupportedParts: return CVariant(m_supportedParts);
|
||||
case IndexFileTimestamp: return CVariant::fromValue(this->getFileTimestamp());
|
||||
case IndexFileTimestampFormattedYmdhms: return CVariant::fromValue(this->getFormattedFileTimestampYmdhms());
|
||||
case IndexIconPath: return CVariant(m_iconPath);
|
||||
case IndexIconPath: return CVariant(m_iconFile);
|
||||
case IndexAircraftIcaoCode: return m_aircraftIcao.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexLivery: return m_livery.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexCallsign: return m_callsign.propertyByIndex(index.copyFrontRemoved());
|
||||
@@ -284,7 +284,7 @@ namespace BlackMisc
|
||||
case IndexDescription: m_description = variant.toQString(); break;
|
||||
case IndexSimulatorInfo: m_simulator.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexName: m_name = variant.toQString(); break;
|
||||
case IndexIconPath: m_iconPath = variant.toQString(); break;
|
||||
case IndexIconPath: m_iconFile = variant.toQString(); break;
|
||||
case IndexCG: m_cg.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexSupportedParts: this->setSupportedParts(variant.toQString()); break;
|
||||
case IndexModelType: m_modelType = variant.value<ModelType>(); break;
|
||||
@@ -345,7 +345,7 @@ namespace BlackMisc
|
||||
case IndexName: return m_name.compare(compareValue.getName(), Qt::CaseInsensitive);
|
||||
case IndexCallsign: return m_callsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getCallsign());
|
||||
case IndexFileName: return m_fileName.compare(compareValue.getFileName(), Qt::CaseInsensitive);
|
||||
case IndexIconPath: return m_iconPath.compare(compareValue.getIconPath(), Qt::CaseInsensitive);
|
||||
case IndexIconPath: return m_iconFile.compare(compareValue.getIconFile(), Qt::CaseInsensitive);
|
||||
case IndexCG: return m_cg.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getCG());
|
||||
case IndexSupportedParts: return m_supportedParts.compare(compareValue.getSupportedParts());
|
||||
case IndexModelTypeAsString:
|
||||
@@ -567,10 +567,10 @@ namespace BlackMisc
|
||||
CPixmap CAircraftModel::loadIcon(CStatusMessage &success) const
|
||||
{
|
||||
static const CStatusMessage noIcon(this, CStatusMessage::SeverityInfo, u"no icon");
|
||||
if (m_iconPath.isEmpty()) { success = noIcon; return CPixmap(); }
|
||||
if (m_iconFile.isEmpty()) { success = noIcon; return CPixmap(); }
|
||||
|
||||
// load from file
|
||||
const CPixmap pm(CPixmap::loadFromFile(m_iconPath, success));
|
||||
const CPixmap pm(CPixmap::loadFromFile(m_iconFile, success));
|
||||
return pm;
|
||||
}
|
||||
|
||||
@@ -659,6 +659,12 @@ namespace BlackMisc
|
||||
m_distributor.updateMissingParts(otherModel.getDistributor());
|
||||
}
|
||||
|
||||
void CAircraftModel::updateByExistingDirectories(const CAircraftModel &otherModel)
|
||||
{
|
||||
if (otherModel.hasExistingCorrespondingFile()) { this->setFileName(otherModel.getFileName()); }
|
||||
if (otherModel.hasExistingIconFile()) { this->setIconFile(otherModel.getIconFile()); }
|
||||
}
|
||||
|
||||
bool CAircraftModel::hasQueriedModelString() const
|
||||
{
|
||||
return m_modelType == TypeQueriedFromNetwork && this->hasModelString();
|
||||
@@ -710,13 +716,13 @@ namespace BlackMisc
|
||||
{
|
||||
// other local, priority
|
||||
this->setFileName(model.getFileName());
|
||||
this->setIconPath(model.getIconPath());
|
||||
this->setIconFile(model.getIconFile());
|
||||
return;
|
||||
}
|
||||
|
||||
// both not local, override empty values
|
||||
if (m_fileName.isEmpty()) { this->setFileName(model.getFileName()); }
|
||||
if (m_iconPath.isEmpty()) { this->setIconPath(model.getIconPath()); }
|
||||
if (m_iconFile.isEmpty()) { this->setIconFile(model.getIconFile()); }
|
||||
}
|
||||
|
||||
bool CAircraftModel::adjustLocalFileNames(const QString &newModelDir, const QString &stripModelDirIndicator)
|
||||
@@ -760,6 +766,13 @@ namespace BlackMisc
|
||||
return this->getFileDirectory().absolutePath();
|
||||
}
|
||||
|
||||
bool CAircraftModel::hasExistingIconFile() const
|
||||
{
|
||||
if (m_iconFile.isEmpty()) { return false; }
|
||||
const QFileInfo fi(m_iconFile);
|
||||
return fi.exists();
|
||||
}
|
||||
|
||||
bool CAircraftModel::matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const
|
||||
{
|
||||
return stringCompare(modelString, m_modelString, sensitivity);
|
||||
|
||||
@@ -366,6 +366,10 @@ namespace BlackMisc
|
||||
//! Update missing parts from another model
|
||||
void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority = true);
|
||||
|
||||
//! Update the directories from other model
|
||||
//! \sa updateLocalFileNames
|
||||
void updateByExistingDirectories(const CAircraftModel &otherModel);
|
||||
|
||||
//! Queried model string?
|
||||
bool hasQueriedModelString() const;
|
||||
|
||||
@@ -450,11 +454,14 @@ namespace BlackMisc
|
||||
//! File name
|
||||
void setFileName(const QString &fileName) { m_fileName = fileName; }
|
||||
|
||||
//! File representing model
|
||||
const QString &getIconPath() const { return m_iconPath; }
|
||||
//! Icon file representing model
|
||||
const QString &getIconFile() const { return m_iconFile; }
|
||||
|
||||
//! File representing model
|
||||
void setIconPath(const QString &iconFile) { m_iconPath = iconFile; }
|
||||
//! Icon file representing model
|
||||
void setIconFile(const QString &iconFile) { m_iconFile = iconFile; }
|
||||
|
||||
//! Is the icon file existing?
|
||||
bool hasExistingIconFile() const;
|
||||
|
||||
//! Get timestamp
|
||||
QDateTime getFileTimestamp() const;
|
||||
@@ -544,7 +551,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
|
||||
QString m_iconFile; //!< a file representing the aircraft as icon
|
||||
QString m_supportedParts; //!< supported parts
|
||||
qint64 m_fileTimestamp = -1; //!< file timestamp of originating file (if applicable)
|
||||
ModelType m_modelType = TypeUnknown; //!< model string is coming representing ...?
|
||||
@@ -568,7 +575,7 @@ namespace BlackMisc
|
||||
BLACK_METAMEMBER(name),
|
||||
BLACK_METAMEMBER(description, 0, DisabledForComparison),
|
||||
BLACK_METAMEMBER(fileName, 0, DisabledForComparison),
|
||||
BLACK_METAMEMBER(iconPath, 0, DisabledForComparison),
|
||||
BLACK_METAMEMBER(iconFile, 0, DisabledForComparison),
|
||||
BLACK_METAMEMBER(fileTimestamp, 0, DisabledForComparison),
|
||||
BLACK_METAMEMBER(modelType),
|
||||
BLACK_METAMEMBER(modelMode)
|
||||
|
||||
@@ -491,14 +491,14 @@ namespace BlackMisc
|
||||
{
|
||||
if (modelString.isEmpty()) { return {}; }
|
||||
const CAircraftModel m(findFirstByModelStringOrDefault(modelString, Qt::CaseInsensitive));
|
||||
return m.getIconPath();
|
||||
return m.getIconFile();
|
||||
}
|
||||
|
||||
QString CAircraftModelList::findModelIconPathByCallsign(const CCallsign &callsign) const
|
||||
{
|
||||
if (callsign.isEmpty()) { return {}; }
|
||||
const CAircraftModel m(findFirstByCallsignOrDefault(callsign));
|
||||
return m.getIconPath();
|
||||
return m.getIconFile();
|
||||
}
|
||||
|
||||
CAircraftModelList CAircraftModelList::findModelsWithoutExistingFile() const
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace BlackMisc
|
||||
model.setName(this->getSimName());
|
||||
model.setMSecsSinceEpoch(m_timestampMSecsSinceEpoch); // aircraft.cfg file timestamp
|
||||
model.setFileTimestamp(m_timestampMSecsSinceEpoch);
|
||||
model.setIconPath(this->getThumbnailFileNameChecked());
|
||||
model.setIconFile(this->getThumbnailFileNameChecked());
|
||||
|
||||
const QString designator(CAircraftIcaoCode::normalizeDesignator(this->getAtcModel()));
|
||||
CAircraftIcaoCode aircraft(
|
||||
|
||||
@@ -381,7 +381,7 @@ namespace BlackMisc
|
||||
QString getNetworkModelLiveryDifference() const;
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getIconPath
|
||||
const QString &getIconPath() const { return m_models[CurrentModel].getIconPath(); }
|
||||
const QString &getIconFile() const { return m_models[CurrentModel].getIconFile(); }
|
||||
|
||||
//! Get model string
|
||||
const QString &getModelString() const { return m_models[CurrentModel].getModelString(); }
|
||||
|
||||
Reference in New Issue
Block a user