23 #include "datapaths.h"
25 #include "application.h"
26 #include "doomseekerfilepaths.h"
27 #include "fileutils.h"
29 #include "plugins/engineplugin.h"
30 #include "strings.hpp"
35 #include <QCoreApplication>
36 #include <QDesktopServices>
38 #include <QProcessEnvironment>
41 #include <QStandardPaths>
44 #if !defined(INSTALL_PREFIX) || !defined(INSTALL_LIBDIR)
45 #error Build system should provide definition for INSTALL_PREFIX and INSTALL_LIBDIR
48 static QList<DirErrno> uniqueErrnosByDir(
const QList<DirErrno> &errnos)
50 QSet<QString> uniqueDirs;
51 QList<DirErrno> uniqueErrnos;
52 for (
const DirErrno &dirErrno : errnos)
54 if (!uniqueDirs.contains(dirErrno.directory.path()))
56 uniqueDirs.insert(dirErrno.directory.path());
57 uniqueErrnos << dirErrno;
63 static QStringList uniquePaths(
const QStringList &paths)
65 QList<QFileInfo> uniqueMarkers;
67 for (
const QString &path : paths)
69 QFileInfo fileInfo(path);
70 if (!uniqueMarkers.contains(fileInfo))
72 uniqueMarkers << fileInfo;
82 static const QString PLUGINS_DIR_NAME;
88 bool bIsPortableModeOn;
90 QDir portableRoot()
const
92 return QDir::current();
95 QString legacyAppDataBaseDir()
const
97 if (bIsPortableModeOn)
99 return QCoreApplication::applicationDirPath();
108 QString envVar = QProcessEnvironment::systemEnvironment().value(
"APPDATA");
109 if (validateDir(envVar))
116 dir = QDir::homePath();
117 if (!validateDir(dir))
123 bool validateDir(
const QString &path)
const
125 QFileInfo fileInfo(path);
126 return !path.isEmpty() && fileInfo.exists() && fileInfo.isDir();
134 static const QString CACHE_DIR_NAME = ".cache";
135 static const QString CONFIG_DIR_NAME = ".doomseeker";
136 static const QString DATA_DIR_NAME = ".static";
137 static const QString DEMOS_DIR_NAME = "demos";
139 const QString
DataPaths::CHATLOGS_DIR_NAME = "chatlogs";
141 const QString
DataPaths::TRANSLATIONS_DIR_NAME = "translations";
142 const QString
DataPaths::UPDATE_PACKAGES_DIR_NAME = "updates";
143 const QString
DataPaths::UPDATE_PACKAGE_FILENAME_PREFIX = "doomseeker-update-pkg-";
147 d->bIsPortableModeOn = bPortableModeOn;
151 setBaseDir(QDir(
"."));
155 d->cacheDirectory.setPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
156 #if QT_VERSION >= 0x050500
158 d->configDirectory.setPath(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation));
162 QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation),
165 d->dataDirectory.setPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
169 DataPaths::~DataPaths()
175 return d->cacheDirectory.path();
178 QStringList DataPaths::canWrite()
const
180 QStringList failedList;
183 if (!d->validateDir(dataDirectory))
184 failedList.append(dataDirectory);
189 QList<DirErrno> DataPaths::createDirectories()
191 QList<DirErrno> failedDirs;
194 if (cacheDirError.isError())
195 failedDirs << cacheDirError;
198 if (configDirError.isError())
199 failedDirs << configDirError;
202 if (dataDirError.isError())
203 failedDirs << dataDirError;
206 if (demosDirError.isError())
207 failedDirs << demosDirError;
209 return uniqueErrnosByDir(failedDirs);
214 return staticDefaultInstance;
220 QStringList filePaths;
222 if (d->bIsPortableModeOn)
227 for (
int i = 0; i < filePaths.size(); ++i)
237 const QDir appDir(QCoreApplication::applicationDirPath());
238 const QString progBinDirName = appDir.dirName();
239 if (progBinDirName !=
"bin" && progBinDirName !=
"MacOS")
240 filePaths << appDir.path();
248 return d->dataDirectory.filePath(DEMOS_DIR_NAME);
254 if (!isPortableModeOn())
256 rootPath = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first();
261 rootPath = QCoreApplication::applicationDirPath();
264 return QDir(rootPath).filePath(subpath);
267 QString DataPaths::env(
const QString &key)
269 return QProcessEnvironment::systemEnvironment().value(key);
272 void DataPaths::initDefault(
bool bPortableModeOn)
274 assert(staticDefaultInstance ==
nullptr &&
"DataPaths can have only one default.");
275 if (staticDefaultInstance ==
nullptr)
276 staticDefaultInstance =
new DataPaths(bPortableModeOn);
279 bool DataPaths::isPortableModeOn()
const
281 return d->bIsPortableModeOn;
301 QStringList DataPaths::pluginSearchLocationPaths()
const
304 paths.append(QCoreApplication::applicationDirPath());
307 #if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN32)
311 const QString installDir = INSTALL_PREFIX
"/" INSTALL_LIBDIR
"/doomseeker/";
312 if (QCoreApplication::applicationDirPath() == INSTALL_PREFIX
"/bin")
313 paths = QStringList(installDir);
315 paths.append(installDir);
318 paths = uniquePaths(paths);
324 if (isPortableModeOn())
326 QFileInfo pathInfo(path);
327 if (pathInfo.isAbsolute())
329 return d->portableRoot().relativeFilePath(path);
338 QString envVarName =
"";
343 envVarName =
"ProgramFiles(x86)";
347 envVarName =
"ProgramW6432";
351 envVarName =
"ProgramFiles";
358 QString path = env(envVarName);
359 if (path.isEmpty() && machineType != Preferred)
372 Q_UNUSED(machineType);
379 return d->configDirectory.path();
382 void DataPaths::setBaseDir(
const QDir &baseDir)
384 d->cacheDirectory.setPath(baseDir.filePath(CACHE_DIR_NAME));
385 d->configDirectory.setPath(baseDir.filePath(CONFIG_DIR_NAME));
386 d->dataDirectory.setPath(baseDir.filePath(DATA_DIR_NAME));
389 void DataPaths::setWorkingDirectory(
const QString &workingDirectory)
397 paths.append(QDir::currentPath());
398 paths.append(QCoreApplication::applicationDirPath());
400 paths.append(INSTALL_PREFIX
"/share/doomseeker");
402 paths = uniquePaths(paths);
403 QString subdirFiltered = subdir.trimmed();
404 if (!subdirFiltered.isEmpty())
406 for (
int i = 0; i < paths.size(); ++i)
412 QString DataPaths::systemAppDataDirectory(QString append)
const
414 return QDir(d->legacyAppDataBaseDir()).filePath(append);
417 bool DataPaths::validateAppDataDirectory()
424 QFileInfo fileInfo(path);
426 bool bCondition1 = !path.isEmpty();
427 bool bCondition2 = fileInfo.exists();
428 bool bCondition3 = fileInfo.isDir();
430 return bCondition1 && bCondition2 && bCondition3;
436 static QString dirPath = QCoreApplication::applicationDirPath();