Allow to update model directories

This commit is contained in:
Klaus Basan
2019-05-03 16:55:58 +02:00
parent 71fbe5b604
commit 3be753a6a7
9 changed files with 163 additions and 24 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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(

View File

@@ -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(); }