This commit is contained in:
BruebachL 2026-07-05 18:26:20 -07:00 committed by GitHub
commit 08e0981372
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 358 additions and 261 deletions

View file

@ -75,7 +75,7 @@ void SpoilerBackgroundUpdater::actDownloadFinishedSpoilersFile()
bool SpoilerBackgroundUpdater::deleteSpoilerFile() bool SpoilerBackgroundUpdater::deleteSpoilerFile()
{ {
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath(); QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
QFileInfo fi(fileName); QFileInfo fi(fileName);
QDir fileDir(fi.path()); QDir fileDir(fi.path());
QFile file(fileName); QFile file(fileName);
@ -126,7 +126,7 @@ void SpoilerBackgroundUpdater::actCheckIfSpoilerSeasonEnabled()
bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data) bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
{ {
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath(); QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
QFileInfo fi(fileName); QFileInfo fi(fileName);
QDir fileDir(fi.path()); QDir fileDir(fi.path());

View file

@ -150,31 +150,6 @@ void SettingsCache::translateLegacySettings()
} }
} }
QString SettingsCache::getSafeConfigPath(QString configEntry, QString defaultPath) const
{
QString tmp = settings->value(configEntry).toString();
// if the config settings is empty or refers to a not-existing folder,
// ensure that the defaut path exists and return it
if (tmp.isEmpty() || !QDir(tmp).exists()) {
if (!QDir().mkpath(defaultPath)) {
qCInfo(SettingsCacheLog) << "[SettingsCache] Could not create folder:" << defaultPath;
}
tmp = defaultPath;
}
return tmp;
}
QString SettingsCache::getSafeConfigFilePath(QString configEntry, QString defaultPath) const
{
QString tmp = settings->value(configEntry).toString();
// if the config settings is empty or refers to a not-existing file,
// return the default Path
if (!QFile::exists(tmp) || tmp.isEmpty()) {
tmp = std::move(defaultPath);
}
return tmp;
}
SettingsCache::SettingsCache() SettingsCache::SettingsCache()
{ {
// first, figure out if we are running in portable mode // first, figure out if we are running in portable mode
@ -188,6 +163,8 @@ SettingsCache::SettingsCache()
QString settingsPath = getSettingsPath(); QString settingsPath = getSettingsPath();
settings = new QSettings(settingsPath + "global.ini", QSettings::IniFormat, this); settings = new QSettings(settingsPath + "global.ini", QSettings::IniFormat, this);
pathsSettings = new PathSettings(settingsPath, this);
pathsSettings->load(getDataPath(), getCachePath());
shortcutsSettings = new ShortcutsSettings(settingsPath, this); shortcutsSettings = new ShortcutsSettings(settingsPath, this);
cardDatabaseSettings = new CardDatabaseSettings(settingsPath, this); cardDatabaseSettings = new CardDatabaseSettings(settingsPath, this);
serversSettings = new ServersSettings(settingsPath, this); serversSettings = new ServersSettings(settingsPath, this);
@ -247,8 +224,6 @@ SettingsCache::SettingsCache()
seenTips.append(tipNumber.toInt()); seenTips.append(tipNumber.toInt());
} }
loadPaths();
themeName = settings->value("theme/name").toString(); themeName = settings->value("theme/name").toString();
homeTabBackgroundSource = settings->value("home/background", "themed").toString(); homeTabBackgroundSource = settings->value("home/background", "themed").toString();
@ -552,72 +527,6 @@ void SettingsCache::setSeenTips(const QList<int> &_seenTips)
settings->setValue("tipOfDay/seenTips", storedTipList); settings->setValue("tipOfDay/seenTips", storedTipList);
} }
void SettingsCache::setDeckPath(const QString &_deckPath)
{
deckPath = _deckPath;
settings->setValue("paths/decks", deckPath);
}
void SettingsCache::setFiltersPath(const QString &_filtersPath)
{
filtersPath = _filtersPath;
settings->setValue("paths/filters", filtersPath);
}
void SettingsCache::setReplaysPath(const QString &_replaysPath)
{
replaysPath = _replaysPath;
settings->setValue("paths/replays", replaysPath);
}
void SettingsCache::setThemesPath(const QString &_themesPath)
{
themesPath = _themesPath;
settings->setValue("paths/themes", themesPath);
emit themeChanged();
}
void SettingsCache::setCustomCardDatabasePath(const QString &_customCardDatabasePath)
{
customCardDatabasePath = _customCardDatabasePath;
settings->setValue("paths/customsets", customCardDatabasePath);
emit cardDatabasePathChanged();
}
void SettingsCache::setPicsPath(const QString &_picsPath)
{
picsPath = _picsPath;
settings->setValue("paths/pics", picsPath);
// get a new value for customPicsPath, currently derived from picsPath
if (picsPath.endsWith("/")) {
customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "CUSTOM/");
} else {
customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "/CUSTOM/");
}
emit picsPathChanged();
}
void SettingsCache::setCardDatabasePath(const QString &_cardDatabasePath)
{
cardDatabasePath = _cardDatabasePath;
settings->setValue("paths/carddatabase", cardDatabasePath);
emit cardDatabasePathChanged();
}
void SettingsCache::setSpoilerDatabasePath(const QString &_spoilerDatabasePath)
{
spoilerDatabasePath = _spoilerDatabasePath;
settings->setValue("paths/spoilerdatabase", spoilerDatabasePath);
emit cardDatabasePathChanged();
}
void SettingsCache::setTokenDatabasePath(const QString &_tokenDatabasePath)
{
tokenDatabasePath = _tokenDatabasePath;
settings->setValue("paths/tokendatabase", tokenDatabasePath);
emit cardDatabasePathChanged();
}
void SettingsCache::setThemeName(const QString &_themeName) void SettingsCache::setThemeName(const QString &_themeName)
{ {
themeName = _themeName; themeName = _themeName;
@ -1402,43 +1311,6 @@ void SettingsCache::setShowSubtypeSelectionTally(QT_STATE_CHANGED_T _showSubtype
settings->setValue("interface/showsubtypeselectiontally", showSubtypeSelectionTally); settings->setValue("interface/showsubtypeselectiontally", showSubtypeSelectionTally);
} }
void SettingsCache::loadPaths()
{
QString dataPath = getDataPath();
deckPath = getSafeConfigPath("paths/decks", dataPath + "/decks/");
filtersPath = getSafeConfigPath("paths/filters", dataPath + "/filters/");
replaysPath = getSafeConfigPath("paths/replays", dataPath + "/replays/");
themesPath = getSafeConfigPath("paths/themes", dataPath + "/themes/");
picsPath = getSafeConfigPath("paths/pics", dataPath + "/pics/");
redirectCachePath = getSafeConfigPath("paths/redirects", getCachePath() + "/redirects/");
// this has never been exposed as an user-configurable setting
if (picsPath.endsWith("/")) {
customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "CUSTOM/");
} else {
customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "/CUSTOM/");
}
customCardDatabasePath = getSafeConfigPath("paths/customsets", dataPath + "/customsets/");
cardDatabasePath = getSafeConfigFilePath("paths/carddatabase", dataPath + "/cards.xml");
tokenDatabasePath = getSafeConfigFilePath("paths/tokendatabase", dataPath + "/tokens.xml");
spoilerDatabasePath = getSafeConfigFilePath("paths/spoilerdatabase", dataPath + "/spoiler.xml");
}
void SettingsCache::resetPaths()
{
QStringList databasePaths{customCardDatabasePath, cardDatabasePath, spoilerDatabasePath, tokenDatabasePath};
QString picsPath_ = picsPath;
settings->remove("paths"); // removes all keys in paths/*
loadPaths();
if (databasePaths !=
QStringList{customCardDatabasePath, cardDatabasePath, spoilerDatabasePath, tokenDatabasePath}) {
emit cardDatabasePathChanged();
}
if (picsPath_ != picsPath) {
emit picsPathChanged();
}
}
CardCounterSettings &SettingsCache::cardCounters() const CardCounterSettings &SettingsCache::cardCounters() const
{ {
return *cardCounterSettings; return *cardCounterSettings;

View file

@ -24,6 +24,7 @@
#include <libcockatrice/settings/game_filters_settings.h> #include <libcockatrice/settings/game_filters_settings.h>
#include <libcockatrice/settings/layouts_settings.h> #include <libcockatrice/settings/layouts_settings.h>
#include <libcockatrice/settings/message_settings.h> #include <libcockatrice/settings/message_settings.h>
#include <libcockatrice/settings/path_settings.h>
#include <libcockatrice/settings/recents_settings.h> #include <libcockatrice/settings/recents_settings.h>
#include <libcockatrice/settings/servers_settings.h> #include <libcockatrice/settings/servers_settings.h>
#include <libcockatrice/utility/macros.h> #include <libcockatrice/utility/macros.h>
@ -135,7 +136,7 @@ inline QStringList defaultTags = {
class QSettings; class QSettings;
class CardCounterSettings; class CardCounterSettings;
class SettingsCache : public ICardDatabasePathProvider, public INetworkSettingsProvider class SettingsCache : public QObject, public INetworkSettingsProvider
{ {
Q_OBJECT Q_OBJECT
@ -211,10 +212,10 @@ private:
CardOverrideSettings *cardOverrideSettings; CardOverrideSettings *cardOverrideSettings;
DebugSettings *debugSettings; DebugSettings *debugSettings;
CardCounterSettings *cardCounterSettings; CardCounterSettings *cardCounterSettings;
PathSettings *pathsSettings;
QString lang; QString lang;
QString deckPath, filtersPath, replaysPath, picsPath, redirectCachePath, customPicsPath, cardDatabasePath, QString themeName, homeTabBackgroundSource;
customCardDatabasePath, themesPath, spoilerDatabasePath, tokenDatabasePath, themeName, homeTabBackgroundSource;
bool tabVisualDeckStorageOpen, tabServerOpen, tabAccountOpen, tabDeckStorageOpen, tabReplaysOpen, tabAdminOpen, bool tabVisualDeckStorageOpen, tabServerOpen, tabAccountOpen, tabDeckStorageOpen, tabReplaysOpen, tabAdminOpen,
tabLogOpen; tabLogOpen;
bool checkUpdatesOnStartup; bool checkUpdatesOnStartup;
@ -339,9 +340,6 @@ private:
int keepalive; int keepalive;
int timeout; int timeout;
void translateLegacySettings(); void translateLegacySettings();
[[nodiscard]] QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
[[nodiscard]] QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
void loadPaths();
bool rememberGameSettings; bool rememberGameSettings;
// Local game settings (separate from server game settings in game/*) // Local game settings (separate from server game settings in game/*)
@ -367,50 +365,6 @@ public:
{ {
return lang; return lang;
} }
[[nodiscard]] QString getDeckPath() const
{
return deckPath;
}
[[nodiscard]] QString getFiltersPath() const
{
return filtersPath;
}
[[nodiscard]] QString getReplaysPath() const
{
return replaysPath;
}
[[nodiscard]] QString getThemesPath() const
{
return themesPath;
}
[[nodiscard]] QString getPicsPath() const
{
return picsPath;
}
[[nodiscard]] QString getRedirectCachePath() const
{
return redirectCachePath;
}
[[nodiscard]] QString getCustomPicsPath() const
{
return customPicsPath;
}
[[nodiscard]] QString getCustomCardDatabasePath() const override
{
return customCardDatabasePath;
}
[[nodiscard]] QString getCardDatabasePath() const override
{
return cardDatabasePath;
}
[[nodiscard]] QString getSpoilerCardDatabasePath() const override
{
return spoilerDatabasePath;
}
[[nodiscard]] QString getTokenDatabasePath() const override
{
return tokenDatabasePath;
}
[[nodiscard]] QString getThemeName() const [[nodiscard]] QString getThemeName() const
{ {
return themeName; return themeName;
@ -985,6 +939,10 @@ public:
{ {
return keepGameChatFocus; return keepGameChatFocus;
} }
[[nodiscard]] PathSettings &paths() const
{
return *pathsSettings;
}
[[nodiscard]] ShortcutsSettings &shortcuts() const [[nodiscard]] ShortcutsSettings &shortcuts() const
{ {
return *shortcutsSettings; return *shortcutsSettings;
@ -1049,15 +1007,6 @@ public slots:
void setLang(const QString &_lang); void setLang(const QString &_lang);
void setShowTipsOnStartup(bool _showTipsOnStartup); void setShowTipsOnStartup(bool _showTipsOnStartup);
void setSeenTips(const QList<int> &_seenTips); void setSeenTips(const QList<int> &_seenTips);
void setDeckPath(const QString &_deckPath);
void setFiltersPath(const QString &_filtersPath);
void setReplaysPath(const QString &_replaysPath);
void setThemesPath(const QString &_themesPath);
void setCustomCardDatabasePath(const QString &_customCardDatabasePath);
void setPicsPath(const QString &_picsPath);
void setCardDatabasePath(const QString &_cardDatabasePath);
void setSpoilerDatabasePath(const QString &_spoilerDatabasePath);
void setTokenDatabasePath(const QString &_tokenDatabasePath);
void setThemeName(const QString &_themeName); void setThemeName(const QString &_themeName);
void setHomeTabBackgroundSource(const QString &_backgroundSource); void setHomeTabBackgroundSource(const QString &_backgroundSource);
void setHomeTabBackgroundShuffleFrequency(int _frequency); void setHomeTabBackgroundShuffleFrequency(int _frequency);

View file

@ -189,7 +189,7 @@ void CardPictureLoader::saveCardImageToLocalStorage(const ExactCard &card, const
return; return;
} }
const QString picsRoot = SettingsCache::instance().getPicsPath(); const QString picsRoot = SettingsCache::instance().paths().getPicsPath();
CardPictureLoaderLocalSchemes::NamingScheme scheme = CardPictureLoaderLocalSchemes::NamingScheme scheme =
SettingsCache::instance().getLocalCardImageStorageNamingScheme(); SettingsCache::instance().getLocalCardImageStorageNamingScheme();
@ -306,7 +306,7 @@ void CardPictureLoader::picsPathChanged()
bool CardPictureLoader::hasCustomArt() bool CardPictureLoader::hasCustomArt()
{ {
auto picsPath = SettingsCache::instance().getPicsPath(); auto picsPath = SettingsCache::instance().paths().getPicsPath();
QDirIterator it(picsPath, QDir::Dirs | QDir::NoDotAndDotDot); QDirIterator it(picsPath, QDir::Dirs | QDir::NoDotAndDotDot);
// Check if there is at least one non-directory file in the pics path, other // Check if there is at least one non-directory file in the pics path, other

View file

@ -11,8 +11,8 @@
static constexpr int REFRESH_INTERVAL_MS = 10 * 1000; static constexpr int REFRESH_INTERVAL_MS = 10 * 1000;
CardPictureLoaderLocal::CardPictureLoaderLocal(QObject *parent) CardPictureLoaderLocal::CardPictureLoaderLocal(QObject *parent)
: QObject(parent), picsPath(SettingsCache::instance().getPicsPath()), : QObject(parent), picsPath(SettingsCache::instance().paths().getPicsPath()),
customPicsPath(SettingsCache::instance().getCustomPicsPath()) customPicsPath(SettingsCache::instance().paths().getCustomPicsPath())
{ {
// Hook up signals to settings // Hook up signals to settings
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this, connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this,
@ -127,6 +127,6 @@ QImage CardPictureLoaderLocal::tryLoadCardImageFromDisk(const QString &setName,
void CardPictureLoaderLocal::picsPathChanged() void CardPictureLoaderLocal::picsPathChanged()
{ {
picsPath = SettingsCache::instance().getPicsPath(); picsPath = SettingsCache::instance().paths().getPicsPath();
customPicsPath = SettingsCache::instance().getCustomPicsPath(); customPicsPath = SettingsCache::instance().paths().getCustomPicsPath();
} }

View file

@ -39,7 +39,7 @@ CardPictureLoaderWorker::CardPictureLoaderWorker()
// We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache // We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy); networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
cacheFilePath = SettingsCache::instance().getRedirectCachePath() + REDIRECT_CACHE_FILENAME; cacheFilePath = SettingsCache::instance().paths().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
loadRedirectCache(); loadRedirectCache();
cleanStaleEntries(); cleanStaleEntries();

View file

@ -143,7 +143,7 @@ QStringMap &ThemeManager::getAvailableThemes()
availableThemes.clear(); availableThemes.clear();
// load themes from user profile dir // load themes from user profile dir
dir.setPath(SettingsCache::instance().getThemesPath()); dir.setPath(SettingsCache::instance().paths().getThemesPath());
// add default value // add default value
availableThemes.insert(NONE_THEME_NAME, dir.absoluteFilePath("Default")); availableThemes.insert(NONE_THEME_NAME, dir.absoluteFilePath("Default"));

View file

@ -7,7 +7,7 @@ DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck"))
{ {
QString startingDir = SettingsCache::instance().recents().getLatestDeckDirPath(); QString startingDir = SettingsCache::instance().recents().getLatestDeckDirPath();
if (startingDir.isEmpty()) { if (startingDir.isEmpty()) {
startingDir = SettingsCache::instance().getDeckPath(); startingDir = SettingsCache::instance().paths().getDeckPath();
} }
setDirectory(startingDir); setDirectory(startingDir);

View file

@ -205,7 +205,8 @@ void DlgSettings::closeEvent(QCloseEvent *event)
} }
} }
if (!QDir(SettingsCache::instance().getDeckPath()).exists() || SettingsCache::instance().getDeckPath().isEmpty()) { if (!QDir(SettingsCache::instance().paths().getDeckPath()).exists() ||
SettingsCache::instance().paths().getDeckPath().isEmpty()) {
//! \todo Prompt to create the deck directory. //! \todo Prompt to create the deck directory.
if (QMessageBox::critical( if (QMessageBox::critical(
this, tr("Error"), this, tr("Error"),
@ -216,7 +217,8 @@ void DlgSettings::closeEvent(QCloseEvent *event)
} }
} }
if (!QDir(SettingsCache::instance().getPicsPath()).exists() || SettingsCache::instance().getPicsPath().isEmpty()) { if (!QDir(SettingsCache::instance().paths().getPicsPath()).exists() ||
SettingsCache::instance().paths().getPicsPath().isEmpty()) {
//! \todo Prompt to create the pictures directory. //! \todo Prompt to create the pictures directory.
if (QMessageBox::critical(this, tr("Error"), if (QMessageBox::critical(this, tr("Error"),
tr("The path to your card pictures directory is invalid. Would you like to go back " tr("The path to your card pictures directory is invalid. Would you like to go back "

View file

@ -88,7 +88,7 @@ void HomeWidget::initializeBackgroundFromSource()
void HomeWidget::loadBackgroundSourceDeck() void HomeWidget::loadBackgroundSourceDeck()
{ {
std::optional<LoadedDeck> deckOpt = DeckLoader::loadFromFile( std::optional<LoadedDeck> deckOpt = DeckLoader::loadFromFile(
SettingsCache::instance().getDeckPath() + "background.cod", DeckFileFormat::Cockatrice, false); SettingsCache::instance().paths().getDeckPath() + "background.cod", DeckFileFormat::Cockatrice, false);
backgroundSourceDeck = deckOpt.has_value() ? deckOpt.value().deckList : DeckList(); backgroundSourceDeck = deckOpt.has_value() ? deckOpt.value().deckList : DeckList();
} }

View file

@ -319,7 +319,7 @@ void AppearanceSettingsPage::themeBoxChanged(int index)
void AppearanceSettingsPage::openThemeLocation() void AppearanceSettingsPage::openThemeLocation()
{ {
QString dir = SettingsCache::instance().getThemesPath(); QString dir = SettingsCache::instance().paths().getThemesPath();
QDir dirDir = dir; QDir dirDir = dir;
dirDir.cdUp(); dirDir.cdUp();
// open if dir exists, create if parent dir does exist // open if dir exists, create if parent dir does exist

View file

@ -27,7 +27,7 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
mcDownloadSpoilersCheckBox.setChecked(SettingsCache::instance().getDownloadSpoilersStatus()); mcDownloadSpoilersCheckBox.setChecked(SettingsCache::instance().getDownloadSpoilersStatus());
mpSpoilerSavePathLineEdit = new QLineEdit(SettingsCache::instance().getSpoilerCardDatabasePath()); mpSpoilerSavePathLineEdit = new QLineEdit(SettingsCache::instance().paths().getSpoilerCardDatabasePath());
mpSpoilerSavePathLineEdit->setReadOnly(true); mpSpoilerSavePathLineEdit->setReadOnly(true);
mpSpoilerPathButton = new QPushButton("..."); mpSpoilerPathButton = new QPushButton("...");
connect(mpSpoilerPathButton, &QPushButton::clicked, this, &DeckEditorSettingsPage::spoilerPathButtonClicked); connect(mpSpoilerPathButton, &QPushButton::clicked, this, &DeckEditorSettingsPage::spoilerPathButtonClicked);
@ -183,7 +183,7 @@ void DeckEditorSettingsPage::unlockSettings()
QString DeckEditorSettingsPage::getLastUpdateTime() QString DeckEditorSettingsPage::getLastUpdateTime()
{ {
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath(); QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
QFileInfo fi(fileName); QFileInfo fi(fileName);
QDir fileDir(fi.path()); QDir fileDir(fi.path());
QFile file(fileName); QFile file(fileName);
@ -203,7 +203,7 @@ void DeckEditorSettingsPage::spoilerPathButtonClicked()
} }
mpSpoilerSavePathLineEdit->setText(lsPath + "/spoiler.xml"); mpSpoilerSavePathLineEdit->setText(lsPath + "/spoiler.xml");
SettingsCache::instance().setSpoilerDatabasePath(lsPath + "/spoiler.xml"); SettingsCache::instance().paths().setSpoilerDatabasePath(lsPath + "/spoiler.xml");
} }
void DeckEditorSettingsPage::setSpoilersEnabled(bool anInput) void DeckEditorSettingsPage::setSpoilersEnabled(bool anInput)

View file

@ -123,38 +123,38 @@ GeneralSettingsPage::GeneralSettingsPage()
startupGroupBox->setLayout(startupGrid); startupGroupBox->setLayout(startupGrid);
// paths settings // paths settings
deckPathEdit = new QLineEdit(settings.getDeckPath()); deckPathEdit = new QLineEdit(settings.paths().getDeckPath());
deckPathEdit->setReadOnly(true); deckPathEdit->setReadOnly(true);
auto *deckPathButton = new QPushButton("..."); auto *deckPathButton = new QPushButton("...");
connect(deckPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::deckPathButtonClicked); connect(deckPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::deckPathButtonClicked);
filtersPathEdit = new QLineEdit(settings.getFiltersPath()); filtersPathEdit = new QLineEdit(settings.paths().getFiltersPath());
filtersPathEdit->setReadOnly(true); filtersPathEdit->setReadOnly(true);
auto *filtersPathButton = new QPushButton("..."); auto *filtersPathButton = new QPushButton("...");
connect(filtersPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::filtersPathButtonClicked); connect(filtersPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::filtersPathButtonClicked);
replaysPathEdit = new QLineEdit(settings.getReplaysPath()); replaysPathEdit = new QLineEdit(settings.paths().getReplaysPath());
replaysPathEdit->setReadOnly(true); replaysPathEdit->setReadOnly(true);
auto *replaysPathButton = new QPushButton("..."); auto *replaysPathButton = new QPushButton("...");
connect(replaysPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::replaysPathButtonClicked); connect(replaysPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::replaysPathButtonClicked);
picsPathEdit = new QLineEdit(settings.getPicsPath()); picsPathEdit = new QLineEdit(settings.paths().getPicsPath());
picsPathEdit->setReadOnly(true); picsPathEdit->setReadOnly(true);
auto *picsPathButton = new QPushButton("..."); auto *picsPathButton = new QPushButton("...");
connect(picsPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::picsPathButtonClicked); connect(picsPathButton, &QPushButton::clicked, this, &GeneralSettingsPage::picsPathButtonClicked);
cardDatabasePathEdit = new QLineEdit(settings.getCardDatabasePath()); cardDatabasePathEdit = new QLineEdit(settings.paths().getCardDatabasePath());
cardDatabasePathEdit->setReadOnly(true); cardDatabasePathEdit->setReadOnly(true);
auto *cardDatabasePathButton = new QPushButton("..."); auto *cardDatabasePathButton = new QPushButton("...");
connect(cardDatabasePathButton, &QPushButton::clicked, this, &GeneralSettingsPage::cardDatabasePathButtonClicked); connect(cardDatabasePathButton, &QPushButton::clicked, this, &GeneralSettingsPage::cardDatabasePathButtonClicked);
customCardDatabasePathEdit = new QLineEdit(settings.getCustomCardDatabasePath()); customCardDatabasePathEdit = new QLineEdit(settings.paths().getCustomCardDatabasePath());
customCardDatabasePathEdit->setReadOnly(true); customCardDatabasePathEdit->setReadOnly(true);
auto *customCardDatabasePathButton = new QPushButton("..."); auto *customCardDatabasePathButton = new QPushButton("...");
connect(customCardDatabasePathButton, &QPushButton::clicked, this, connect(customCardDatabasePathButton, &QPushButton::clicked, this,
&GeneralSettingsPage::customCardDatabaseButtonClicked); &GeneralSettingsPage::customCardDatabaseButtonClicked);
tokenDatabasePathEdit = new QLineEdit(settings.getTokenDatabasePath()); tokenDatabasePathEdit = new QLineEdit(settings.paths().getTokenDatabasePath());
tokenDatabasePathEdit->setReadOnly(true); tokenDatabasePathEdit->setReadOnly(true);
auto *tokenDatabasePathButton = new QPushButton("..."); auto *tokenDatabasePathButton = new QPushButton("...");
connect(tokenDatabasePathButton, &QPushButton::clicked, this, &GeneralSettingsPage::tokenDatabasePathButtonClicked); connect(tokenDatabasePathButton, &QPushButton::clicked, this, &GeneralSettingsPage::tokenDatabasePathButtonClicked);
@ -264,7 +264,7 @@ void GeneralSettingsPage::deckPathButtonClicked()
} }
deckPathEdit->setText(path); deckPathEdit->setText(path);
SettingsCache::instance().setDeckPath(path); SettingsCache::instance().paths().setDeckPath(path);
} }
void GeneralSettingsPage::filtersPathButtonClicked() void GeneralSettingsPage::filtersPathButtonClicked()
@ -275,7 +275,7 @@ void GeneralSettingsPage::filtersPathButtonClicked()
} }
filtersPathEdit->setText(path); filtersPathEdit->setText(path);
SettingsCache::instance().setFiltersPath(path); SettingsCache::instance().paths().setFiltersPath(path);
} }
void GeneralSettingsPage::replaysPathButtonClicked() void GeneralSettingsPage::replaysPathButtonClicked()
@ -286,7 +286,7 @@ void GeneralSettingsPage::replaysPathButtonClicked()
} }
replaysPathEdit->setText(path); replaysPathEdit->setText(path);
SettingsCache::instance().setReplaysPath(path); SettingsCache::instance().paths().setReplaysPath(path);
} }
void GeneralSettingsPage::picsPathButtonClicked() void GeneralSettingsPage::picsPathButtonClicked()
@ -297,7 +297,7 @@ void GeneralSettingsPage::picsPathButtonClicked()
} }
picsPathEdit->setText(path); picsPathEdit->setText(path);
SettingsCache::instance().setPicsPath(path); SettingsCache::instance().paths().setPicsPath(path);
} }
void GeneralSettingsPage::cardDatabasePathButtonClicked() void GeneralSettingsPage::cardDatabasePathButtonClicked()
@ -308,7 +308,7 @@ void GeneralSettingsPage::cardDatabasePathButtonClicked()
} }
cardDatabasePathEdit->setText(path); cardDatabasePathEdit->setText(path);
SettingsCache::instance().setCardDatabasePath(path); SettingsCache::instance().paths().setCardDatabasePath(path);
} }
void GeneralSettingsPage::customCardDatabaseButtonClicked() void GeneralSettingsPage::customCardDatabaseButtonClicked()
@ -319,7 +319,7 @@ void GeneralSettingsPage::customCardDatabaseButtonClicked()
} }
customCardDatabasePathEdit->setText(path); customCardDatabasePathEdit->setText(path);
SettingsCache::instance().setCustomCardDatabasePath(path); SettingsCache::instance().paths().setCustomCardDatabasePath(path);
} }
void GeneralSettingsPage::tokenDatabasePathButtonClicked() void GeneralSettingsPage::tokenDatabasePathButtonClicked()
@ -330,19 +330,19 @@ void GeneralSettingsPage::tokenDatabasePathButtonClicked()
} }
tokenDatabasePathEdit->setText(path); tokenDatabasePathEdit->setText(path);
SettingsCache::instance().setTokenDatabasePath(path); SettingsCache::instance().paths().setTokenDatabasePath(path);
} }
void GeneralSettingsPage::resetAllPathsClicked() void GeneralSettingsPage::resetAllPathsClicked()
{ {
SettingsCache &settings = SettingsCache::instance(); SettingsCache &settings = SettingsCache::instance();
settings.resetPaths(); settings.paths().reset(settings.getDataPath(), settings.getCachePath());
deckPathEdit->setText(settings.getDeckPath()); deckPathEdit->setText(settings.paths().getDeckPath());
replaysPathEdit->setText(settings.getReplaysPath()); replaysPathEdit->setText(settings.paths().getReplaysPath());
picsPathEdit->setText(settings.getPicsPath()); picsPathEdit->setText(settings.paths().getPicsPath());
cardDatabasePathEdit->setText(settings.getCardDatabasePath()); cardDatabasePathEdit->setText(settings.paths().getCardDatabasePath());
customCardDatabasePathEdit->setText(settings.getCustomCardDatabasePath()); customCardDatabasePathEdit->setText(settings.paths().getCustomCardDatabasePath());
tokenDatabasePathEdit->setText(settings.getTokenDatabasePath()); tokenDatabasePathEdit->setText(settings.paths().getTokenDatabasePath());
allPathsResetLabel->setVisible(true); allPathsResetLabel->setVisible(true);
} }

View file

@ -180,7 +180,7 @@ void StorageSettingsPage::clearDownloadedPicsButtonClicked()
void StorageSettingsPage::clearImageBackupsButtonClicked() void StorageSettingsPage::clearImageBackupsButtonClicked()
{ {
QString picsPath = SettingsCache::instance().getPicsPath() + "/downloadedPics"; QString picsPath = SettingsCache::instance().paths().getPicsPath() + "/downloadedPics";
QDir dir(picsPath); QDir dir(picsPath);
bool success = dir.removeRecursively(); bool success = dir.removeRecursively();

View file

@ -350,7 +350,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
DeckList deckList = deckStateManager->getDeckList(); DeckList deckList = deckStateManager->getDeckList();
QFileDialog dialog(this, tr("Save deck")); QFileDialog dialog(this, tr("Save deck"));
dialog.setDirectory(SettingsCache::instance().getDeckPath()); dialog.setDirectory(SettingsCache::instance().paths().getDeckPath());
dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setDefaultSuffix("cod"); dialog.setDefaultSuffix("cod");
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS); dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);

View file

@ -36,7 +36,7 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
: Tab(_tabSupervisor), client(_client) : Tab(_tabSupervisor), client(_client)
{ {
localDirModel = new QFileSystemModel(this); localDirModel = new QFileSystemModel(this);
localDirModel->setRootPath(SettingsCache::instance().getDeckPath()); localDirModel->setRootPath(SettingsCache::instance().paths().getDeckPath());
localDirModel->sort(0, Qt::AscendingOrder); localDirModel->sort(0, Qt::AscendingOrder);
localDirView = new QTreeView; localDirView = new QTreeView;

View file

@ -59,7 +59,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
QGroupBox *TabReplays::createLeftLayout() QGroupBox *TabReplays::createLeftLayout()
{ {
localDirModel = new QFileSystemModel(this); localDirModel = new QFileSystemModel(this);
localDirModel->setRootPath(SettingsCache::instance().getReplaysPath()); localDirModel->setRootPath(SettingsCache::instance().paths().getReplaysPath());
localDirModel->sort(0, Qt::AscendingOrder); localDirModel->sort(0, Qt::AscendingOrder);
localDirView = new QTreeView; localDirView = new QTreeView;

View file

@ -61,7 +61,7 @@ void VisualDatabaseDisplayFilterSaveLoadWidget::saveFilter()
return; return;
} }
QString filePath = SettingsCache::instance().getFiltersPath() + QDir::separator() + filename + ".json"; QString filePath = SettingsCache::instance().paths().getFiltersPath() + QDir::separator() + filename + ".json";
// Serialize the filter model to JSON // Serialize the filter model to JSON
QJsonArray filtersArray; QJsonArray filtersArray;
@ -86,7 +86,7 @@ void VisualDatabaseDisplayFilterSaveLoadWidget::saveFilter()
void VisualDatabaseDisplayFilterSaveLoadWidget::loadFilter(const QString &filename) void VisualDatabaseDisplayFilterSaveLoadWidget::loadFilter(const QString &filename)
{ {
QString filePath = SettingsCache::instance().getFiltersPath() + QDir::separator() + filename; QString filePath = SettingsCache::instance().paths().getFiltersPath() + QDir::separator() + filename;
QFile file(filePath); QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
@ -156,7 +156,7 @@ void VisualDatabaseDisplayFilterSaveLoadWidget::refreshFilterList()
fileListWidget->clearLayout(); fileListWidget->clearLayout();
fileButtons.clear(); fileButtons.clear();
QDir dir(SettingsCache::instance().getFiltersPath()); QDir dir(SettingsCache::instance().paths().getFiltersPath());
allFilterFiles = dir.entryList({"*.json"}, QDir::Files, QDir::Name); allFilterFiles = dir.entryList({"*.json"}, QDir::Files, QDir::Name);
applySearchFilter(searchInput->text()); applySearchFilter(searchInput->text());

View file

@ -68,7 +68,7 @@ void FilterDisplayWidget::deleteFilter()
QMessageBox::Yes | QMessageBox::No); QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) { if (reply == QMessageBox::Yes) {
// If confirmed, delete the filter // If confirmed, delete the filter
QString filePath = SettingsCache::instance().getFiltersPath() + QDir::separator() + filterFilename; QString filePath = SettingsCache::instance().paths().getFiltersPath() + QDir::separator() + filterFilename;
QFile file(filePath); QFile file(filePath);
if (file.remove()) { if (file.remove()) {
emit filterDeleted(filterFilename); // Emit signal for deletion emit filterDeleted(filterFilename); // Emit signal for deletion

View file

@ -74,7 +74,7 @@ static QStringList getAllFiles(const QString &filePath)
*/ */
static QStringList findAllKnownTags() static QStringList findAllKnownTags()
{ {
QStringList allFiles = getAllFiles(SettingsCache::instance().getDeckPath()); QStringList allFiles = getAllFiles(SettingsCache::instance().paths().getDeckPath());
QStringList knownTags; QStringList knownTags;
for (const QString &file : allFiles) { for (const QString &file : allFiles) {

View file

@ -43,7 +43,7 @@ VisualDeckStorageFolderDisplayWidget::VisualDeckStorageFolderDisplayWidget(
void VisualDeckStorageFolderDisplayWidget::refreshUi() void VisualDeckStorageFolderDisplayWidget::refreshUi()
{ {
QString bannerText = tr("Deck Storage"); QString bannerText = tr("Deck Storage");
QString deckPath = SettingsCache::instance().getDeckPath(); QString deckPath = SettingsCache::instance().paths().getDeckPath();
if (filePath != deckPath) { if (filePath != deckPath) {
QString relativePath = filePath; QString relativePath = filePath;

View file

@ -60,7 +60,7 @@ QString VisualDeckStorageSearchWidget::getSearchText()
*/ */
static QString toRelativeFilepath(const QString &filePath) static QString toRelativeFilepath(const QString &filePath)
{ {
QString deckPath = SettingsCache::instance().getDeckPath(); QString deckPath = SettingsCache::instance().paths().getDeckPath();
if (filePath.startsWith(deckPath)) { if (filePath.startsWith(deckPath)) {
return filePath.mid(deckPath.length()); return filePath.mid(deckPath.length());
} }

View file

@ -142,8 +142,8 @@ void VisualDeckStorageWidget::reapplySortAndFilters()
void VisualDeckStorageWidget::createRootFolderWidget() void VisualDeckStorageWidget::createRootFolderWidget()
{ {
folderWidget = new VisualDeckStorageFolderDisplayWidget(this, this, SettingsCache::instance().getDeckPath(), false, folderWidget = new VisualDeckStorageFolderDisplayWidget(this, this, SettingsCache::instance().paths().getDeckPath(),
quickSettingsWidget->getShowFolders()); false, quickSettingsWidget->getShowFolders());
scrollArea->setWidget(folderWidget); // this automatically destroys the old folderWidget scrollArea->setWidget(folderWidget); // this automatically destroys the old folderWidget
scrollArea->widget()->setMaximumWidth(scrollArea->viewport()->width()); scrollArea->widget()->setMaximumWidth(scrollArea->viewport()->width());

View file

@ -177,7 +177,7 @@ void MainWindow::startLocalGame(const LocalGameOptions &options)
void MainWindow::actWatchReplay() void MainWindow::actWatchReplay()
{ {
QFileDialog dlg(this, tr("Load replay")); QFileDialog dlg(this, tr("Load replay"));
dlg.setDirectory(SettingsCache::instance().getReplaysPath()); dlg.setDirectory(SettingsCache::instance().paths().getReplaysPath());
dlg.setNameFilters(QStringList() << QObject::tr("Cockatrice replays (*.cor)")); dlg.setNameFilters(QStringList() << QObject::tr("Cockatrice replays (*.cor)"));
if (!dlg.exec()) { if (!dlg.exec()) {
return; return;
@ -1004,13 +1004,13 @@ void MainWindow::refreshShortcuts()
void MainWindow::actOpenCustomFolder() void MainWindow::actOpenCustomFolder()
{ {
QString dir = SettingsCache::instance().getCustomPicsPath(); QString dir = SettingsCache::instance().paths().getCustomPicsPath();
QDesktopServices::openUrl(QUrl::fromLocalFile(dir)); QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
} }
void MainWindow::actOpenCustomsetsFolder() void MainWindow::actOpenCustomsetsFolder()
{ {
QString dir = SettingsCache::instance().getCustomCardDatabasePath(); QString dir = SettingsCache::instance().paths().getCustomCardDatabasePath();
QDesktopServices::openUrl(QUrl::fromLocalFile(dir)); QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
} }
@ -1035,7 +1035,7 @@ void MainWindow::actAddCustomSet()
return; return;
} }
QDir dir = SettingsCache::instance().getCustomCardDatabasePath(); QDir dir = SettingsCache::instance().paths().getCustomCardDatabasePath();
int nextPrefix = getNextCustomSetPrefix(dir); int nextPrefix = getNextCustomSetPrefix(dir);
bool res; bool res;

View file

@ -250,7 +250,7 @@ int main(int argc, char *argv[])
// Dependency Injections // Dependency Injections
CardDatabaseManager::setCardPreferenceProvider(new SettingsCardPreferenceProvider()); CardDatabaseManager::setCardPreferenceProvider(new SettingsCardPreferenceProvider());
CardDatabaseManager::setCardDatabasePathProvider(&SettingsCache::instance()); CardDatabaseManager::setCardDatabasePathProvider(&SettingsCache::instance().paths());
CardDatabaseManager::setCardSetPriorityController(SettingsCache::instance().cardDatabase()); CardDatabaseManager::setCardSetPriorityController(SettingsCache::instance().cardDatabase());
qCInfo(MainLog) << "Starting main program"; qCInfo(MainLog) << "Starting main program";

View file

@ -27,9 +27,11 @@ CardDatabaseLoader::CardDatabaseLoader(QObject *parent,
connect(p, &ICardDatabaseParser::addFormat, database, &CardDatabase::addFormat, Qt::DirectConnection); connect(p, &ICardDatabaseParser::addFormat, database, &CardDatabase::addFormat, Qt::DirectConnection);
} }
// TODO: PathSettings can't double inherit from a QObject ICardDatabasePathProvider and a QObject SettingsManager.
// ICardDatabasePathProvider was only a QObject for this single signal.
// when SettingsCache's path changes, trigger reloads // when SettingsCache's path changes, trigger reloads
connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this, /*connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this,
&CardDatabaseLoader::loadCardDatabases); &CardDatabaseLoader::loadCardDatabases);*/
} }
CardDatabaseLoader::~CardDatabaseLoader() CardDatabaseLoader::~CardDatabaseLoader()

View file

@ -4,6 +4,7 @@
#include <QBasicMutex> #include <QBasicMutex>
#include <QList> #include <QList>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QObject>
#include <libcockatrice/interfaces/interface_card_database_path_provider.h> #include <libcockatrice/interfaces/interface_card_database_path_provider.h>
#include <libcockatrice/interfaces/interface_card_preference_provider.h> #include <libcockatrice/interfaces/interface_card_preference_provider.h>
#include <libcockatrice/interfaces/interface_card_set_priority_controller.h> #include <libcockatrice/interfaces/interface_card_set_priority_controller.h>

View file

@ -1,10 +1,8 @@
#ifndef COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H #ifndef COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H
#define COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H #define COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H
#include <QObject>
class ICardDatabasePathProvider : public QObject class ICardDatabasePathProvider
{ {
Q_OBJECT
public: public:
virtual ~ICardDatabasePathProvider() = default; virtual ~ICardDatabasePathProvider() = default;
@ -13,9 +11,6 @@ public:
[[nodiscard]] virtual QString getCustomCardDatabasePath() const = 0; [[nodiscard]] virtual QString getCustomCardDatabasePath() const = 0;
[[nodiscard]] virtual QString getTokenDatabasePath() const = 0; [[nodiscard]] virtual QString getTokenDatabasePath() const = 0;
[[nodiscard]] virtual QString getSpoilerCardDatabasePath() const = 0; [[nodiscard]] virtual QString getSpoilerCardDatabasePath() const = 0;
signals:
void cardDatabasePathChanged();
}; };
#endif // COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H #endif // COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H

View file

@ -34,6 +34,8 @@ add_library(
libcockatrice/settings/recents_settings.cpp libcockatrice/settings/recents_settings.cpp
libcockatrice/settings/servers_settings.cpp libcockatrice/settings/servers_settings.cpp
libcockatrice/settings/settings_manager.cpp libcockatrice/settings/settings_manager.cpp
libcockatrice/settings/path_settings.cpp
libcockatrice/settings/path_settings.h
) )
target_include_directories( target_include_directories(

View file

@ -0,0 +1,163 @@
#include "path_settings.h"
#include <QDir>
#include <QFile>
PathSettings::PathSettings(const QString &settingPath, QObject *parent)
: SettingsManager(settingPath + "global.ini", "paths", QString(), parent)
{
}
QString PathSettings::getSafeConfigPath(const QString &configEntry, const QString &defaultPath) const
{
QString tmp = getValue(configEntry).toString();
// if the config settings is empty or refers to a not-existing folder,
// ensure that the default path exists and return it
if (tmp.isEmpty() || !QDir(tmp).exists()) {
if (!QDir().mkpath(defaultPath)) {
qCInfo(PathSettingsLog) << "[PathSettings] Could not create folder:" << defaultPath;
}
tmp = defaultPath;
}
return tmp;
}
QString PathSettings::getSafeConfigFilePath(const QString &configEntry, const QString &defaultPath) const
{
QString tmp = getValue(configEntry).toString();
// if the config settings is empty or refers to a not-existing file,
// return the default path
if (tmp.isEmpty() || !QFile::exists(tmp)) {
tmp = defaultPath;
}
return tmp;
}
void PathSettings::recomputeCustomPicsPath()
{
// this has never been exposed as a user-configurable setting
if (picsPath.endsWith("/")) {
customPicsPath = getSafeConfigPath("custompics", picsPath + "CUSTOM/");
} else {
customPicsPath = getSafeConfigPath("custompics", picsPath + "/CUSTOM/");
}
}
void PathSettings::load(const QString &dataPath, const QString &cachePath)
{
deckPath = getSafeConfigPath("decks", dataPath + "/decks/");
filtersPath = getSafeConfigPath("filters", dataPath + "/filters/");
replaysPath = getSafeConfigPath("replays", dataPath + "/replays/");
themesPath = getSafeConfigPath("themes", dataPath + "/themes/");
picsPath = getSafeConfigPath("pics", dataPath + "/pics/");
redirectCachePath = getSafeConfigPath("redirects", cachePath + "/redirects/");
recomputeCustomPicsPath();
customCardDatabasePath = getSafeConfigPath("customsets", dataPath + "/customsets/");
cardDatabasePath = getSafeConfigFilePath("carddatabase", dataPath + "/cards.xml");
tokenDatabasePath = getSafeConfigFilePath("tokendatabase", dataPath + "/tokens.xml");
spoilerDatabasePath = getSafeConfigFilePath("spoilerdatabase", dataPath + "/spoiler.xml");
}
void PathSettings::reset(const QString &dataPath, const QString &cachePath)
{
auto settings = getSettings();
settings.beginGroup("paths");
settings.remove(""); // removes all keys in Path/*
settings.endGroup();
load(dataPath, cachePath);
}
/*void SettingsCache::loadPaths()
{
QString dataPath = getDataPath();
deckPath = getSafeConfigPath("paths/decks", dataPath + "/decks/");
filtersPath = getSafeConfigPath("paths/filters", dataPath + "/filters/");
replaysPath = getSafeConfigPath("paths/replays", dataPath + "/replays/");
themesPath = getSafeConfigPath("paths/themes", dataPath + "/themes/");
picsPath = getSafeConfigPath("paths/pics", dataPath + "/pics/");
redirectCachePath = getSafeConfigPath("paths/redirects", getCachePath() + "/redirects/");
// this has never been exposed as an user-configurable setting
if (picsPath.endsWith("/")) {
customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "CUSTOM/");
} else {
customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "/CUSTOM/");
}
customCardDatabasePath = getSafeConfigPath("paths/customsets", dataPath + "/customsets/");
cardDatabasePath = getSafeConfigFilePath("paths/carddatabase", dataPath + "/cards.xml");
tokenDatabasePath = getSafeConfigFilePath("paths/tokendatabase", dataPath + "/tokens.xml");
spoilerDatabasePath = getSafeConfigFilePath("paths/spoilerdatabase", dataPath + "/spoiler.xml");
}
void SettingsCache::resetPaths()
{
QStringList databasePaths{customCardDatabasePath, cardDatabasePath, spoilerDatabasePath, tokenDatabasePath};
QString picsPath_ = picsPath;
settings->remove("paths"); // removes all keys in paths/
loadPaths();
if (databasePaths !=
QStringList{customCardDatabasePath, cardDatabasePath, spoilerDatabasePath, tokenDatabasePath}) {
emit cardDatabasePathChanged();
}
if (picsPath_ != picsPath) {
emit picsPathChanged();
}
}*/
void PathSettings::setDeckPath(const QString &_deckPath)
{
deckPath = _deckPath;
setValue(deckPath, "decks");
}
void PathSettings::setFiltersPath(const QString &_filtersPath)
{
filtersPath = _filtersPath;
setValue(filtersPath, "filters");
}
void PathSettings::setReplaysPath(const QString &_replaysPath)
{
replaysPath = _replaysPath;
setValue(replaysPath, "replays");
}
void PathSettings::setThemesPath(const QString &_themesPath)
{
themesPath = _themesPath;
setValue(themesPath, "themes");
}
void PathSettings::setPicsPath(const QString &_picsPath)
{
picsPath = _picsPath;
setValue(picsPath, "pics");
// get a new value for customPicsPath, currently derived from picsPath
recomputeCustomPicsPath();
}
void PathSettings::setCustomCardDatabasePath(const QString &_customCardDatabasePath)
{
customCardDatabasePath = _customCardDatabasePath;
setValue(customCardDatabasePath, "customsets");
}
void PathSettings::setCardDatabasePath(const QString &_cardDatabasePath)
{
cardDatabasePath = _cardDatabasePath;
setValue(cardDatabasePath, "carddatabase");
}
void PathSettings::setSpoilerDatabasePath(const QString &_spoilerDatabasePath)
{
spoilerDatabasePath = _spoilerDatabasePath;
setValue(spoilerDatabasePath, "spoilerdatabase");
}
void PathSettings::setTokenDatabasePath(const QString &_tokenDatabasePath)
{
tokenDatabasePath = _tokenDatabasePath;
setValue(tokenDatabasePath, "tokendatabase");
}

View file

@ -0,0 +1,111 @@
#ifndef COCKATRICE_PATH_SETTINGS_H
#define COCKATRICE_PATH_SETTINGS_H
/**
* @file path_settings.h
* @ingroup Settings
*/
//! \todo Document this file.
#include "settings_manager.h"
#include <QLoggingCategory>
#include <QString>
#include <libcockatrice/interfaces/interface_card_database_path_provider.h>
inline Q_LOGGING_CATEGORY(PathSettingsLog, "path_settings");
/**
* Owns every user-configurable filesystem path used by the client (decks, filters,
* replays, themes, pictures, card databases, and the redirect cache).
*
* Backed by the "paths" group of the existing global.ini, so extracting this class out
* of SettingsCache is a pure code-organization change: no stored user data moves.
*/
class PathSettings : public SettingsManager, public ICardDatabasePathProvider
{
Q_OBJECT
signals:
void cardDatabasePathChanged();
public:
explicit PathSettings(const QString &settingPath, QObject *parent = nullptr);
[[nodiscard]] QString getDeckPath() const
{
return deckPath;
}
[[nodiscard]] QString getFiltersPath() const
{
return filtersPath;
}
[[nodiscard]] QString getReplaysPath() const
{
return replaysPath;
}
[[nodiscard]] QString getThemesPath() const
{
return themesPath;
}
[[nodiscard]] QString getPicsPath() const
{
return picsPath;
}
[[nodiscard]] QString getRedirectCachePath() const
{
return redirectCachePath;
}
[[nodiscard]] QString getCustomPicsPath() const
{
return customPicsPath;
}
[[nodiscard]] QString getCustomCardDatabasePath() const override
{
return customCardDatabasePath;
}
[[nodiscard]] QString getCardDatabasePath() const override
{
return cardDatabasePath;
}
[[nodiscard]] QString getSpoilerCardDatabasePath() const override
{
return spoilerDatabasePath;
}
[[nodiscard]] QString getTokenDatabasePath() const override
{
return tokenDatabasePath;
}
void setDeckPath(const QString &_deckPath);
void setFiltersPath(const QString &_filtersPath);
void setReplaysPath(const QString &_replaysPath);
void setThemesPath(const QString &_themesPath);
void setPicsPath(const QString &_picsPath);
void setCustomCardDatabasePath(const QString &_customCardDatabasePath);
void setCardDatabasePath(const QString &_cardDatabasePath);
void setSpoilerDatabasePath(const QString &_spoilerDatabasePath);
void setTokenDatabasePath(const QString &_tokenDatabasePath);
/**
* (Re)computes every path from defaults rooted at dataPath/cachePath, honoring any
* user overrides already stored in settings. Must be called once after construction.
*/
void load(const QString &dataPath, const QString &cachePath);
/**
* Clears all stored path overrides and reloads defaults rooted at dataPath/cachePath.
*/
void reset(const QString &dataPath, const QString &cachePath);
private:
QString deckPath, filtersPath, replaysPath, picsPath, redirectCachePath, customPicsPath, cardDatabasePath,
customCardDatabasePath, themesPath, spoilerDatabasePath, tokenDatabasePath;
[[nodiscard]] QString getSafeConfigPath(const QString &configEntry, const QString &defaultPath) const;
[[nodiscard]] QString getSafeConfigFilePath(const QString &configEntry, const QString &defaultPath) const;
void recomputeCustomPicsPath();
};
#endif // COCKATRICE_PATH_SETTINGS_H

View file

@ -581,7 +581,7 @@ void SaveSetsPage::retranslateUi()
saveLabel->setText(tr("Press \"Save\" to store the imported cards in the Cockatrice database.")); saveLabel->setText(tr("Press \"Save\" to store the imported cards in the Cockatrice database."));
pathLabel->setText(tr("The card database will be saved at the following location:") + "<br>" + pathLabel->setText(tr("The card database will be saved at the following location:") + "<br>" +
SettingsCache::instance().getCardDatabasePath()); SettingsCache::instance().paths().getCardDatabasePath());
defaultPathCheckBox->setText(tr("Save to a custom path (not recommended)")); defaultPathCheckBox->setText(tr("Save to a custom path (not recommended)"));
setButtonText(QWizard::NextButton, tr("&Save")); setButtonText(QWizard::NextButton, tr("&Save"));
@ -601,7 +601,7 @@ void SaveSetsPage::updateTotalProgress(int cardsImported, int /* setIndex */, co
bool SaveSetsPage::validatePage() bool SaveSetsPage::validatePage()
{ {
QString defaultPath = SettingsCache::instance().getCardDatabasePath(); QString defaultPath = SettingsCache::instance().paths().getCardDatabasePath();
QString windowName = tr("Save card database"); QString windowName = tr("Save card database");
QString fileType = tr("XML; card database (*.xml)"); QString fileType = tr("XML; card database (*.xml)");
@ -663,7 +663,7 @@ QString LoadTokensPage::getCustomUrlSettingsKey()
QString LoadTokensPage::getDefaultSavePath() QString LoadTokensPage::getDefaultSavePath()
{ {
return SettingsCache::instance().getTokenDatabasePath(); return SettingsCache::instance().paths().getTokenDatabasePath();
} }
QString LoadTokensPage::getWindowTitle() QString LoadTokensPage::getWindowTitle()
@ -692,7 +692,7 @@ void LoadTokensPage::retranslateUi()
fileButton->setText(tr("Choose file...")); fileButton->setText(tr("Choose file..."));
pathLabel->setText(tr("The token database will be saved at the following location:") + "<br>" + pathLabel->setText(tr("The token database will be saved at the following location:") + "<br>" +
SettingsCache::instance().getTokenDatabasePath()); SettingsCache::instance().paths().getTokenDatabasePath());
defaultPathCheckBox->setText(tr("Save to a custom path (not recommended)")); defaultPathCheckBox->setText(tr("Save to a custom path (not recommended)"));
} }
@ -708,7 +708,7 @@ QString LoadSpoilersPage::getCustomUrlSettingsKey()
QString LoadSpoilersPage::getDefaultSavePath() QString LoadSpoilersPage::getDefaultSavePath()
{ {
return SettingsCache::instance().getTokenDatabasePath(); return SettingsCache::instance().paths().getTokenDatabasePath();
} }
QString LoadSpoilersPage::getWindowTitle() QString LoadSpoilersPage::getWindowTitle()
@ -737,6 +737,6 @@ void LoadSpoilersPage::retranslateUi()
fileButton->setText(tr("Choose file...")); fileButton->setText(tr("Choose file..."));
pathLabel->setText(tr("The spoiler database will be saved at the following location:") + "<br>" + pathLabel->setText(tr("The spoiler database will be saved at the following location:") + "<br>" +
SettingsCache::instance().getSpoilerCardDatabasePath()); SettingsCache::instance().paths().getSpoilerCardDatabasePath());
defaultPathCheckBox->setText(tr("Save to a custom path (not recommended)")); defaultPathCheckBox->setText(tr("Save to a custom path (not recommended)"));
} }