Skip to content

Commit

Permalink
Added option to read extra scenery library folder.
Browse files Browse the repository at this point in the history
  • Loading branch information
albar965 committed Apr 27, 2023
1 parent e9733ef commit bd6d7bf
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 126 deletions.
101 changes: 66 additions & 35 deletions src/fs/navdatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ using atools::fs::scenery::AddOnCfgEntry;
using atools::fs::scenery::SceneryArea;
using atools::fs::scenery::AddOnComponent;
using atools::fs::scenery::AddOnPackage;
using atools::fs::FsPaths;
using atools::buildPathNoCase;

NavDatabase::NavDatabase(const NavDatabaseOptions *readerOptions, sql::SqlDatabase *sqlDb, NavDatabaseErrors *databaseErrors,
Expand All @@ -96,8 +97,8 @@ atools::fs::ResultFlags NavDatabase::compileDatabase()
QString sceneryCfgCodec;

if(options != nullptr)
sceneryCfgCodec = (options->getSimulatorType() == atools::fs::FsPaths::P3D_V4 ||
options->getSimulatorType() == atools::fs::FsPaths::P3D_V5) ? "UTF-8" : QString();
sceneryCfgCodec = (options->getSimulatorType() == FsPaths::P3D_V4 ||
options->getSimulatorType() == FsPaths::P3D_V5) ? "UTF-8" : QString();

atools::fs::ResultFlags result = createInternal(sceneryCfgCodec);
if(aborted)
Expand Down Expand Up @@ -206,9 +207,9 @@ bool NavDatabase::isSceneryConfigValid(const QString& filename, const QString& c

bool NavDatabase::isBasePathValid(const QString& filepath, QStringList& errors, atools::fs::FsPaths::SimulatorType type)
{
if(atools::fs::FsPaths::isAnyXplane(type))
if(FsPaths::isAnyXplane(type))
errors.append(atools::checkDirMsg(buildPathNoCase({filepath, "Resources", "default data"})));
else if(type == atools::fs::FsPaths::MSFS)
else if(type == FsPaths::MSFS)
{
// Base is C:\Users\alex\AppData\Local\Packages\Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalCache\Packages

Expand Down Expand Up @@ -568,14 +569,15 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
// ==============================================================================
// Calculate the total number of progress steps
int total = 0;
if(atools::fs::FsPaths::isAnyXplane(sim))
if(FsPaths::isAnyXplane(sim))
total = countXplaneSteps(&progress);
else if(sim == atools::fs::FsPaths::NAVIGRAPH)
else if(sim == FsPaths::NAVIGRAPH)
total = countDfdSteps();
else if(sim == atools::fs::FsPaths::MSFS)
else if(sim == FsPaths::MSFS)
{
// Fill with default required entries but does not read a file
readSceneryConfigMsfs(sceneryCfg);
readSceneryConfigIncludePathsFsxP3dMsfs(sceneryCfg);
total = countMsfsSteps(&progress, sceneryCfg);

// Check for Navigraph packages to report back to caller
Expand All @@ -592,6 +594,7 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
{
// Read scenery.cfg
readSceneryConfigFsxP3d(sceneryCfg);
readSceneryConfigIncludePathsFsxP3dMsfs(sceneryCfg);
total = countFsxP3dSteps(&progress, sceneryCfg);
}

Expand Down Expand Up @@ -620,10 +623,10 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig

// ================================================================================================
// Start compilation
if(sim == atools::fs::FsPaths::NAVIGRAPH)
if(sim == FsPaths::NAVIGRAPH)
{
// Create a single Navigraph scenery area
atools::fs::scenery::SceneryArea area(1, tr("Navigraph"), QString());
SceneryArea area(1, tr("Navigraph"), QString());

// Prepare error collection for single area
if(errors != nullptr)
Expand All @@ -634,10 +637,10 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
loadDfd(&progress, dfdCompiler.data(), area);
dfdCompiler->close();
}
else if(atools::fs::FsPaths::isAnyXplane(sim))
else if(FsPaths::isAnyXplane(sim))
{
// Create a single X-Plane scenery area
atools::fs::scenery::SceneryArea area(1, tr("X-Plane"), QString());
SceneryArea area(1, tr("X-Plane"), QString());

// Prepare error collection for single area
if(errors != nullptr)
Expand All @@ -648,7 +651,7 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
loadXplane(&progress, xpDataCompiler.data(), area);
xpDataCompiler->close();
}
else if(sim == atools::fs::FsPaths::MSFS)
else if(sim == FsPaths::MSFS)
{
// Load FSX / P3D scenery database ======================================================
fsDataWriter.reset(new atools::fs::db::DataWriter(*db, *options, &progress));
Expand Down Expand Up @@ -700,13 +703,13 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
// ===========================================================================
// Loading is done here - now continue with the post process steps

if(options->isResolveAirways() && sim != atools::fs::FsPaths::NAVIGRAPH)
if(options->isResolveAirways() && sim != FsPaths::NAVIGRAPH)
{
// All simulators ====================
// Read tmp_airway_point table, connect all waypoints and write the ordered result into the airway table
atools::fs::db::AirwayResolver resolver(db, progress);

if(sim != atools::fs::FsPaths::NAVIGRAPH && !atools::fs::FsPaths::isAnyXplane(sim))
if(sim != FsPaths::NAVIGRAPH && !FsPaths::isAnyXplane(sim))
// Drop large segments only for the borked data of FSX/P3D/MSFS - default is 8000 nm
resolver.setMaxAirwaySegmentLengthNm(800);

Expand All @@ -716,7 +719,7 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
return result;
}

if(!atools::fs::FsPaths::isAnyXplane(sim) && sim != atools::fs::FsPaths::NAVIGRAPH && sim != atools::fs::FsPaths::MSFS)
if(!FsPaths::isAnyXplane(sim) && sim != FsPaths::NAVIGRAPH && sim != FsPaths::MSFS)
{
// Create VORTACs
if((aborted = runScript(&progress, "fs/db/update_vor.sql", tr("Merging VOR and TACAN to VORTAC"))))
Expand All @@ -727,14 +730,14 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
if((aborted = runScript(&progress, "fs/db/update_wp_ids.sql", tr("Updating waypoints"))))
return result;

if(!atools::fs::FsPaths::isAnyXplane(sim) && sim != atools::fs::FsPaths::NAVIGRAPH)
if(!FsPaths::isAnyXplane(sim) && sim != FsPaths::NAVIGRAPH)
{
// Assign airport ids based on stored idents for waypoint and ndb
if((aborted = runScript(&progress, "fs/db/update_nav_ids.sql", tr("Updating Navaids"))))
return result;
}

if(sim == atools::fs::FsPaths::NAVIGRAPH)
if(sim == FsPaths::NAVIGRAPH)
{
// Remove all unreferenced dummy waypoints that were added for airway generation
if((aborted = runScript(&progress, "fs/db/dfd/clean_waypoints.sql", tr("Cleaning up waypoints"))))
Expand All @@ -749,12 +752,12 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
if((aborted = runScript(&progress, "fs/db/update_airport.sql", tr("Updating Airports"))))
return result;

if(sim == atools::fs::FsPaths::DFD)
if(sim == FsPaths::DFD)
{
if((aborted = runScript(&progress, "fs/db/dfd/update_airport_ils.sql", tr("Updating ILS"))))
return result;
}
else if(!atools::fs::FsPaths::isAnyXplane(sim))
else if(!FsPaths::isAnyXplane(sim))
{
// The ids are already updated when reading the X-Plane data
// Set runway end ids into the ILS
Expand Down Expand Up @@ -790,7 +793,7 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
if((aborted = runScript(&progress, "fs/db/finish_airport_schema.sql", tr("Creating indexes for airport"))))
return result;

if(!atools::fs::FsPaths::isAnyXplane(sim) && sim != atools::fs::FsPaths::NAVIGRAPH)
if(!FsPaths::isAnyXplane(sim) && sim != FsPaths::NAVIGRAPH)
{
if((aborted = runScript(&progress, "fs/db/update_sea_base.sql", tr("Clean up runways"))))
return result;
Expand All @@ -811,7 +814,7 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
return result;
}

if(sim == atools::fs::FsPaths::MSFS)
if(sim == FsPaths::MSFS)
{
if((aborted = progress.reportOther(tr("Loading translations"))))
return result;
Expand All @@ -826,7 +829,7 @@ atools::fs::ResultFlags NavDatabase::createInternal(const QString& sceneryConfig
// Update the metadata in the database
atools::fs::db::DatabaseMeta databaseMetadata(db);

if(sim == atools::fs::FsPaths::MSFS && result.testFlag(atools::fs::COMPILE_MSFS_NAVIGRAPH_FOUND))
if(sim == FsPaths::MSFS && result.testFlag(atools::fs::COMPILE_MSFS_NAVIGRAPH_FOUND))
databaseMetadata.addProperty(atools::fs::db::PROPERTYNAME_MSFS_NAVIGRAPH_FOUND);

if(!xpDataCompiler.isNull())
Expand Down Expand Up @@ -1020,13 +1023,17 @@ bool NavDatabase::loadXplane(ProgressHandler *progress, atools::fs::xp::XpDataCo

if(options->isIncludedNavDbObject(atools::fs::type::AIRPORT))
{
// Airports are overloaded by ident
// Airports are overloaded by ident - first coming in overload the rest

// X-Plane 11/Custom Scenery/KSEA Demo Area/Earth nav data/apt.dat
if((aborted = xpDataCompiler->compileUserIncludeApt())) // Add-on
return true;

// X-Plane 11/Custom Scenery/KSEA Demo Area/Earth nav data/apt.dat
if((aborted = xpDataCompiler->compileCustomApt())) // Add-on
return true;

if(options->getSimulatorType() == atools::fs::FsPaths::XPLANE_11)
if(options->getSimulatorType() == FsPaths::XPLANE_11)
{
// X-Plane 11/Custom Scenery/Global Airports/Earth nav data/apt.dat
if((aborted = xpDataCompiler->compileCustomGlobalApt()))
Expand All @@ -1042,7 +1049,7 @@ bool NavDatabase::loadXplane(ProgressHandler *progress, atools::fs::xp::XpDataCo
return true;
}

if(options->getSimulatorType() == atools::fs::FsPaths::XPLANE_12)
if(options->getSimulatorType() == FsPaths::XPLANE_12)
{
// X-Plane 12/Global Scenery/Global Airports/Earth nav data/apt.dat
if((aborted = xpDataCompiler->compileGlobalApt12()))
Expand Down Expand Up @@ -1178,7 +1185,7 @@ bool NavDatabase::loadFsxP3dMsfsSimulator(ProgressHandler *progress, db::DataWri
const QList<atools::fs::scenery::SceneryArea>& areas)
{
scenery::MaterialLib materialLib(options);
for(const atools::fs::scenery::SceneryArea& area : areas)
for(const SceneryArea& area : areas)
{
if((area.isActive() || options->isReadInactive()) && options->isIncludedLocalPath(area.getLocalPath()))
{
Expand All @@ -1197,7 +1204,7 @@ bool NavDatabase::loadFsxP3dMsfsSimulator(ProgressHandler *progress, db::DataWri
fileinfo.setFile(options->getMsfsOfficialPath() % SEP % area.getLocalPath());
}

if(options->getSimulatorType() == atools::fs::FsPaths::MSFS && (area.isAddOn() || area.isCommunity()))
if(options->getSimulatorType() == FsPaths::MSFS && (area.isAddOn() || area.isCommunity()))
{
// Load package specific material library for MSFS
materialLib.clear();
Expand Down Expand Up @@ -1658,6 +1665,32 @@ bool NavDatabase::isNavigraphNavdata(atools::fs::scenery::ManifestJson& manifest
manifest.getTitle().contains("AIRAC Cycle", Qt::CaseInsensitive);
}

void NavDatabase::readSceneryConfigIncludePathsFsxP3dMsfs(atools::fs::scenery::SceneryCfg& cfg)
{
int nextNum = nextAreaNum(cfg.getAreas());

// All included paths in GUI
for(int i = 0; i < options->getDirIncludesGui().size(); i++)
{
// One included directory
QDir dir(options->getDirIncludesGui().at(i));

// Get all folders in the directory where each one is an add-on
for(const QFileInfo& addonDir : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot))
{
if(options->getSimulatorType() == FsPaths::MSFS)
{
// The MSFS add-on dir needs two JSON files to be valid
if(QDir(addonDir.canonicalFilePath()).entryList({"layout.json", "manifest.json"}, QDir::Files).size() == 2)
cfg.appendArea(SceneryArea(nextNum + i, tr("Custom scenery path %1").arg(i + 1), addonDir.canonicalFilePath()));
}
else if(!QDir(addonDir.canonicalFilePath() + SEP + "scenery").entryList({"*.bgl"}, QDir::Files).isEmpty())
// The FSX/P3D addon directory needs a sub-folder "scenery" with BGL files
cfg.appendArea(SceneryArea(nextNum + i, tr("Custom scenery path %1").arg(i + 1), addonDir.canonicalFilePath()));
}
}
}

void NavDatabase::readSceneryConfigFsxP3d(atools::fs::scenery::SceneryCfg& cfg)
{
// Get entries from scenery.cfg file
Expand All @@ -1666,18 +1699,17 @@ void NavDatabase::readSceneryConfigFsxP3d(atools::fs::scenery::SceneryCfg& cfg)
bool readInactive = options->isReadInactive();
FsPaths::SimulatorType sim = options->getSimulatorType();

if(options->isReadAddOnXml() &&
(sim == atools::fs::FsPaths::P3D_V3 || sim == atools::fs::FsPaths::P3D_V4 || sim == atools::fs::FsPaths::P3D_V5))
if(options->isReadAddOnXml() && (sim == FsPaths::P3D_V3 || sim == FsPaths::P3D_V4 || sim == FsPaths::P3D_V5))
{
// Read the Prepar3D add on packages and add them to the scenery list ===============================
QString documents(atools::documentsDir());

int simNum = 0;
if(sim == atools::fs::FsPaths::P3D_V3)
if(sim == FsPaths::P3D_V3)
simNum = 3;
else if(sim == atools::fs::FsPaths::P3D_V4)
else if(sim == FsPaths::P3D_V4)
simNum = 4;
else if(sim == atools::fs::FsPaths::P3D_V5)
else if(sim == FsPaths::P3D_V5)
simNum = 5;

// Calculate maximum area number
Expand Down Expand Up @@ -1716,8 +1748,7 @@ void NavDatabase::readSceneryConfigFsxP3d(atools::fs::scenery::SceneryCfg& cfg)
// Use $HOME/.config for testing
QString addonsCfgFile = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).at(0);
#endif
addonsCfgFile += SEP % QString("Lockheed Martin") % SEP % QString("Prepar3D v%1").arg(simNum) %
SEP % "add-ons.cfg";
addonsCfgFile += SEP % QString("Lockheed Martin") % SEP % QString("Prepar3D v%1").arg(simNum) % SEP % "add-ons.cfg";
addonsCfgFiles.append(addonsCfgFile);
}

Expand Down Expand Up @@ -1925,7 +1956,7 @@ void NavDatabase::countFiles(ProgressHandler *progress, const QList<atools::fs::
qDebug() << Q_FUNC_INFO << "Entry";
atools::fs::scenery::FileResolver resolver(*options, true);

for(const atools::fs::scenery::SceneryArea& area : areas)
for(const SceneryArea& area : areas)
{
if((aborted = progress->reportOtherMsg(tr("Counting files for %1 ...").arg(area.getTitle()))))
return;
Expand Down
5 changes: 4 additions & 1 deletion src/fs/navdatabase.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*****************************************************************************
* Copyright 2015-2020 Alexander Barthel alex@littlenavmap.org
* Copyright 2015-2023 Alexander Barthel alex@littlenavmap.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -126,6 +126,9 @@ class NavDatabase
/* Fill MSFS scenery configuration with the two default entries */
void readSceneryConfigMsfs(scenery::SceneryCfg& cfg);

/* Read all included extra folders */
void readSceneryConfigIncludePathsFsxP3dMsfs(atools::fs::scenery::SceneryCfg& cfg);

/* Source dependent compilation methods */

/* FSX, FSX SE and P3D */
Expand Down
9 changes: 9 additions & 0 deletions src/fs/navdatabaseoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ void NavDatabaseOptions::setLanguage(const QString& value)
language = language.section('-', 0, 0) + "-" + language.section('-', 1, 1).toUpper();
}

void NavDatabaseOptions::addIncludeGui(const QFileInfo& path)
{
if(path.exists() && path.isDir())
dirIncludesGui.append(atools::canonicalFilePath(path));
else
qWarning() << Q_FUNC_INFO << "Inclusion path does not exist or is no dir" << path;
}

void NavDatabaseOptions::addExcludeGui(const QFileInfo& path)
{
if(path.exists())
Expand Down Expand Up @@ -369,6 +377,7 @@ QDebug operator<<(QDebug out, const NavDatabaseOptions& opts)
out << ", addonFiltersInc [" << patternStr(opts.addonFiltersInc) << "]";
out << ", addonFiltersExcl [" << patternStr(opts.addonFiltersExcl) << "]";
out << ", highPriorityFiltersInc [" << patternStr(opts.highPriorityFiltersInc) << "]";
out << ", dirIncludesGui [" << opts.dirIncludesGui << "]";
out << ", dirExcludesGui [" << patternStr(opts.dirExcludesGui) << "]";
out << ", fileExcludesGui [" << patternStr(opts.fileExcludesGui) << "]";
out << ", dirAddonExcludesGui [" << patternStr(opts.dirAddonExcludesGui) << "]";
Expand Down
10 changes: 10 additions & 0 deletions src/fs/navdatabaseoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ class NavDatabaseOptions
/* Set progress callback function/method */
void setProgressCallback(ProgressCallbackType func);

/* Include absolute directories paths. Used by the GUI options dialog. Not saved. */
void addIncludeGui(const QFileInfo& path);

/* Exclude absolute directories and file paths. Used by the GUI options dialog. Not saved. */
void addExcludeGui(const QFileInfo& path);

Expand Down Expand Up @@ -440,6 +443,12 @@ class NavDatabaseOptions

bool isIncludedNavDbObject(atools::fs::type::NavDbObjectType type) const;

/* Paths to add to search list */
const QStringList& getDirIncludesGui() const
{
return dirIncludesGui;
}

ProgressCallbackType getProgressCallback() const;

atools::fs::FsPaths::SimulatorType getSimulatorType() const
Expand Down Expand Up @@ -519,6 +528,7 @@ class NavDatabaseOptions

/* Elements set from GUI. Not loaded from config file */
QList<QRegExp> dirExcludesGui, fileExcludesGui, dirAddonExcludesGui, fileAddonExcludesGui;
QStringList dirIncludesGui;

QSet<atools::fs::type::NavDbObjectType> navDbObjectTypeFiltersInc, navDbObjectTypeFiltersExcl;
ProgressCallbackType progressCallback = nullptr;
Expand Down
6 changes: 2 additions & 4 deletions src/fs/scenery/fileresolver.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*****************************************************************************
* Copyright 2015-2020 Alexander Barthel alex@littlenavmap.org
* Copyright 2015-2023 Alexander Barthel alex@littlenavmap.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -88,9 +88,7 @@ int FileResolver::getFiles(const SceneryArea& area, QStringList *filepaths, QStr
// Get all scenery folders for FSX and P3D
QDir sceneryAreaDir(sceneryArea.filePath());

sceneryDirs.append(sceneryAreaDir.entryInfoList({"scenery"},
QDir::Dirs | QDir::Hidden | QDir::System |
QDir::NoDotAndDotDot));
sceneryDirs.append(sceneryAreaDir.entryInfoList({"scenery"}, QDir::Dirs | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot));

if(sceneryDirs.isEmpty() && sceneryAreaDir.dirName().toLower() == "scenery")
// Special case where entry points to scenery directory which is allowed by P3D
Expand Down
Loading

0 comments on commit bd6d7bf

Please sign in to comment.