File indexing completed on 2024-05-12 04:57:52

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2014-2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "datapaths.h"
0019 #include "qztools.h"
0020 #include "../config.h"
0021 #include "mainapplication.h"
0022 
0023 #include <QApplication>
0024 #include <QDir>
0025 
0026 #include <QStandardPaths>
0027 #include <QTemporaryDir>
0028 
0029 Q_GLOBAL_STATIC(DataPaths, qz_data_paths)
0030 
0031 DataPaths::DataPaths()
0032 {
0033     init();
0034 }
0035 
0036 DataPaths::~DataPaths()
0037 = default;
0038 
0039 // static
0040 void DataPaths::setCurrentProfilePath(const QString &profilePath)
0041 {
0042     qz_data_paths()->initCurrentProfile(profilePath);
0043 }
0044 
0045 // static
0046 void DataPaths::setPortableVersion()
0047 {
0048     DataPaths* d = qz_data_paths();
0049 
0050     const QString appDir = QCoreApplication::applicationDirPath();
0051 
0052     d->m_paths[AppData] = QStringList{appDir};
0053     d->m_paths[Config] = QStringList{appDir + QSL("/config")};
0054     d->m_paths[Cache] = QStringList{appDir + QSL("/cache")};
0055     d->m_paths[Profiles] = QStringList{appDir + QSL("/config/profiles")};
0056 
0057     d->m_paths[Themes].clear();
0058     d->m_paths[Plugins].clear();
0059     d->initAssetsIn(appDir);
0060 
0061     // Make sure Temp path exists
0062     QDir().mkpath(d->m_paths[Temp].at(0));
0063 }
0064 
0065 // static
0066 QString DataPaths::path(DataPaths::Path path)
0067 {
0068     Q_ASSERT(!qz_data_paths()->m_paths[path].isEmpty());
0069 
0070     return qz_data_paths()->m_paths[path].at(0);
0071 }
0072 
0073 // static
0074 QStringList DataPaths::allPaths(DataPaths::Path type)
0075 {
0076     Q_ASSERT(!qz_data_paths()->m_paths[type].isEmpty());
0077 
0078     return qz_data_paths()->m_paths[type];
0079 }
0080 
0081 // static
0082 QString DataPaths::locate(Path type, const QString &file)
0083 {
0084     const QStringList dirs = allPaths(type);
0085     for (const QString &dir : dirs) {
0086         const QString fullPath = QDir(dir).absoluteFilePath(file);
0087         if (QFileInfo::exists(fullPath)) {
0088             return fullPath;
0089         }
0090     }
0091     return {};
0092 }
0093 
0094 // static
0095 QString DataPaths::currentProfilePath()
0096 {
0097     return path(CurrentProfile);
0098 }
0099 
0100 void DataPaths::init()
0101 {
0102     m_paths[AppData].append(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation));
0103 
0104 #ifdef FALKON_PLUGIN_PATH
0105     m_paths[Plugins].append(QStringLiteral(FALKON_PLUGIN_PATH));
0106 #endif
0107 
0108     for (const QString &location : std::as_const(m_paths[AppData])) {
0109         initAssetsIn(location);
0110     }
0111 
0112     if (MainApplication::isTestModeEnabled()) {
0113         m_paths[Config].append(QDir::tempPath() + QSL("/Falkon-test"));
0114     } else {
0115         m_paths[Config].append(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation));
0116     }
0117 
0118     m_paths[Profiles].append(m_paths[Config].at(0) + QLatin1String("/profiles"));
0119     // We also allow to load data from Config path
0120     initAssetsIn(m_paths[Config].at(0));
0121 
0122     // If FALKON_PLUGIN_PATH is set, only load plugins from there
0123     const QByteArray pluginPath = qgetenv("FALKON_PLUGIN_PATH");
0124     if (!pluginPath.isNull()) {
0125         m_paths[Plugins] = QStringList{QString::fromLocal8Bit(pluginPath)};
0126     }
0127 
0128     m_tmpdir.reset(new QTemporaryDir());
0129     m_paths[Temp].append(m_tmpdir->path());
0130     if (!m_tmpdir->isValid()) {
0131         qWarning() << "Failed to create temporary directory" << m_tmpdir->path();
0132     }
0133 
0134     m_paths[Cache].append(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
0135 }
0136 
0137 void DataPaths::initCurrentProfile(const QString &profilePath)
0138 {
0139     m_paths[CurrentProfile].append(profilePath);
0140 
0141     if (m_paths[Cache].isEmpty())
0142         m_paths[Cache].append(m_paths[CurrentProfile].at(0) + QLatin1String("/cache"));
0143 
0144     if (m_paths[Sessions].isEmpty())
0145         m_paths[Sessions].append(m_paths[CurrentProfile].at(0) + QLatin1String("/sessions"));
0146 
0147     QDir dir;
0148     dir.mkpath(m_paths[Cache].at(0));
0149     dir.mkpath(m_paths[Sessions].at(0));
0150 }
0151 
0152 void DataPaths::initAssetsIn(const QString &path)
0153 {
0154     m_paths[Themes].append(path + QLatin1String("/themes"));
0155     m_paths[Plugins].append(path + QLatin1String("/plugins"));
0156 }