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()
{
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath();
QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
QFileInfo fi(fileName);
QDir fileDir(fi.path());
QFile file(fileName);
@ -126,7 +126,7 @@ void SpoilerBackgroundUpdater::actCheckIfSpoilerSeasonEnabled()
bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
{
QString fileName = SettingsCache::instance().getSpoilerCardDatabasePath();
QString fileName = SettingsCache::instance().paths().getSpoilerCardDatabasePath();
QFileInfo fi(fileName);
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()
{
// first, figure out if we are running in portable mode
@ -188,6 +163,8 @@ SettingsCache::SettingsCache()
QString settingsPath = getSettingsPath();
settings = new QSettings(settingsPath + "global.ini", QSettings::IniFormat, this);
pathsSettings = new PathSettings(settingsPath, this);
pathsSettings->load(getDataPath(), getCachePath());
shortcutsSettings = new ShortcutsSettings(settingsPath, this);
cardDatabaseSettings = new CardDatabaseSettings(settingsPath, this);
serversSettings = new ServersSettings(settingsPath, this);
@ -247,8 +224,6 @@ SettingsCache::SettingsCache()
seenTips.append(tipNumber.toInt());
}
loadPaths();
themeName = settings->value("theme/name").toString();
homeTabBackgroundSource = settings->value("home/background", "themed").toString();
@ -552,72 +527,6 @@ void SettingsCache::setSeenTips(const QList<int> &_seenTips)
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)
{
themeName = _themeName;
@ -1402,43 +1311,6 @@ void SettingsCache::setShowSubtypeSelectionTally(QT_STATE_CHANGED_T _showSubtype
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
{
return *cardCounterSettings;

View file

@ -24,6 +24,7 @@
#include <libcockatrice/settings/game_filters_settings.h>
#include <libcockatrice/settings/layouts_settings.h>
#include <libcockatrice/settings/message_settings.h>
#include <libcockatrice/settings/path_settings.h>
#include <libcockatrice/settings/recents_settings.h>
#include <libcockatrice/settings/servers_settings.h>
#include <libcockatrice/utility/macros.h>
@ -135,7 +136,7 @@ inline QStringList defaultTags = {
class QSettings;
class CardCounterSettings;
class SettingsCache : public ICardDatabasePathProvider, public INetworkSettingsProvider
class SettingsCache : public QObject, public INetworkSettingsProvider
{
Q_OBJECT
@ -211,10 +212,10 @@ private:
CardOverrideSettings *cardOverrideSettings;
DebugSettings *debugSettings;
CardCounterSettings *cardCounterSettings;
PathSettings *pathsSettings;
QString lang;
QString deckPath, filtersPath, replaysPath, picsPath, redirectCachePath, customPicsPath, cardDatabasePath,
customCardDatabasePath, themesPath, spoilerDatabasePath, tokenDatabasePath, themeName, homeTabBackgroundSource;
QString themeName, homeTabBackgroundSource;
bool tabVisualDeckStorageOpen, tabServerOpen, tabAccountOpen, tabDeckStorageOpen, tabReplaysOpen, tabAdminOpen,
tabLogOpen;
bool checkUpdatesOnStartup;
@ -339,9 +340,6 @@ private:
int keepalive;
int timeout;
void translateLegacySettings();
[[nodiscard]] QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
[[nodiscard]] QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
void loadPaths();
bool rememberGameSettings;
// Local game settings (separate from server game settings in game/*)
@ -367,50 +365,6 @@ public:
{
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
{
return themeName;
@ -985,6 +939,10 @@ public:
{
return keepGameChatFocus;
}
[[nodiscard]] PathSettings &paths() const
{
return *pathsSettings;
}
[[nodiscard]] ShortcutsSettings &shortcuts() const
{
return *shortcutsSettings;
@ -1049,15 +1007,6 @@ public slots:
void setLang(const QString &_lang);
void setShowTipsOnStartup(bool _showTipsOnStartup);
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 setHomeTabBackgroundSource(const QString &_backgroundSource);
void setHomeTabBackgroundShuffleFrequency(int _frequency);
@ -1183,4 +1132,4 @@ public slots:
void setShowTotalSelectionCount(QT_STATE_CHANGED_T _showTotalSelectionCount);
void setShowSubtypeSelectionTally(QT_STATE_CHANGED_T _showSubtypeSelectionTally);
};
#endif
#endif

View file

@ -189,7 +189,7 @@ void CardPictureLoader::saveCardImageToLocalStorage(const ExactCard &card, const
return;
}
const QString picsRoot = SettingsCache::instance().getPicsPath();
const QString picsRoot = SettingsCache::instance().paths().getPicsPath();
CardPictureLoaderLocalSchemes::NamingScheme scheme =
SettingsCache::instance().getLocalCardImageStorageNamingScheme();
@ -306,7 +306,7 @@ void CardPictureLoader::picsPathChanged()
bool CardPictureLoader::hasCustomArt()
{
auto picsPath = SettingsCache::instance().getPicsPath();
auto picsPath = SettingsCache::instance().paths().getPicsPath();
QDirIterator it(picsPath, QDir::Dirs | QDir::NoDotAndDotDot);
// 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;
CardPictureLoaderLocal::CardPictureLoaderLocal(QObject *parent)
: QObject(parent), picsPath(SettingsCache::instance().getPicsPath()),
customPicsPath(SettingsCache::instance().getCustomPicsPath())
: QObject(parent), picsPath(SettingsCache::instance().paths().getPicsPath()),
customPicsPath(SettingsCache::instance().paths().getCustomPicsPath())
{
// Hook up signals to settings
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this,
@ -127,6 +127,6 @@ QImage CardPictureLoaderLocal::tryLoadCardImageFromDisk(const QString &setName,
void CardPictureLoaderLocal::picsPathChanged()
{
picsPath = SettingsCache::instance().getPicsPath();
customPicsPath = SettingsCache::instance().getCustomPicsPath();
picsPath = SettingsCache::instance().paths().getPicsPath();
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
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
cacheFilePath = SettingsCache::instance().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
cacheFilePath = SettingsCache::instance().paths().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
loadRedirectCache();
cleanStaleEntries();

View file

@ -143,7 +143,7 @@ QStringMap &ThemeManager::getAvailableThemes()
availableThemes.clear();
// load themes from user profile dir
dir.setPath(SettingsCache::instance().getThemesPath());
dir.setPath(SettingsCache::instance().paths().getThemesPath());
// add default value
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();
if (startingDir.isEmpty()) {
startingDir = SettingsCache::instance().getDeckPath();
startingDir = SettingsCache::instance().paths().getDeckPath();
}
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.
if (QMessageBox::critical(
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.
if (QMessageBox::critical(this, tr("Error"),
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()
{
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();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -61,7 +61,7 @@ void VisualDatabaseDisplayFilterSaveLoadWidget::saveFilter()
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
QJsonArray filtersArray;
@ -86,7 +86,7 @@ void VisualDatabaseDisplayFilterSaveLoadWidget::saveFilter()
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);
if (!file.open(QIODevice::ReadOnly)) {
@ -156,7 +156,7 @@ void VisualDatabaseDisplayFilterSaveLoadWidget::refreshFilterList()
fileListWidget->clearLayout();
fileButtons.clear();
QDir dir(SettingsCache::instance().getFiltersPath());
QDir dir(SettingsCache::instance().paths().getFiltersPath());
allFilterFiles = dir.entryList({"*.json"}, QDir::Files, QDir::Name);
applySearchFilter(searchInput->text());

View file

@ -68,7 +68,7 @@ void FilterDisplayWidget::deleteFilter()
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
// 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);
if (file.remove()) {
emit filterDeleted(filterFilename); // Emit signal for deletion

View file

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

View file

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

View file

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

View file

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

View file

@ -177,7 +177,7 @@ void MainWindow::startLocalGame(const LocalGameOptions &options)
void MainWindow::actWatchReplay()
{
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)"));
if (!dlg.exec()) {
return;
@ -1004,13 +1004,13 @@ void MainWindow::refreshShortcuts()
void MainWindow::actOpenCustomFolder()
{
QString dir = SettingsCache::instance().getCustomPicsPath();
QString dir = SettingsCache::instance().paths().getCustomPicsPath();
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
}
void MainWindow::actOpenCustomsetsFolder()
{
QString dir = SettingsCache::instance().getCustomCardDatabasePath();
QString dir = SettingsCache::instance().paths().getCustomCardDatabasePath();
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
}
@ -1035,7 +1035,7 @@ void MainWindow::actAddCustomSet()
return;
}
QDir dir = SettingsCache::instance().getCustomCardDatabasePath();
QDir dir = SettingsCache::instance().paths().getCustomCardDatabasePath();
int nextPrefix = getNextCustomSetPrefix(dir);
bool res;

View file

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

View file

@ -27,9 +27,11 @@ CardDatabaseLoader::CardDatabaseLoader(QObject *parent,
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
connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this,
&CardDatabaseLoader::loadCardDatabases);
/*connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this,
&CardDatabaseLoader::loadCardDatabases);*/
}
CardDatabaseLoader::~CardDatabaseLoader()

View file

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

View file

@ -1,10 +1,8 @@
#ifndef 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:
virtual ~ICardDatabasePathProvider() = default;
@ -13,9 +11,6 @@ public:
[[nodiscard]] virtual QString getCustomCardDatabasePath() const = 0;
[[nodiscard]] virtual QString getTokenDatabasePath() const = 0;
[[nodiscard]] virtual QString getSpoilerCardDatabasePath() const = 0;
signals:
void cardDatabasePathChanged();
};
#endif // COCKATRICE_INTERFACE_CARD_DATABASE_PATH_PROVIDER_H

View file

@ -34,6 +34,8 @@ add_library(
libcockatrice/settings/recents_settings.cpp
libcockatrice/settings/servers_settings.cpp
libcockatrice/settings/settings_manager.cpp
libcockatrice/settings/path_settings.cpp
libcockatrice/settings/path_settings.h
)
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."));
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)"));
setButtonText(QWizard::NextButton, tr("&Save"));
@ -601,7 +601,7 @@ void SaveSetsPage::updateTotalProgress(int cardsImported, int /* setIndex */, co
bool SaveSetsPage::validatePage()
{
QString defaultPath = SettingsCache::instance().getCardDatabasePath();
QString defaultPath = SettingsCache::instance().paths().getCardDatabasePath();
QString windowName = tr("Save card database");
QString fileType = tr("XML; card database (*.xml)");
@ -663,7 +663,7 @@ QString LoadTokensPage::getCustomUrlSettingsKey()
QString LoadTokensPage::getDefaultSavePath()
{
return SettingsCache::instance().getTokenDatabasePath();
return SettingsCache::instance().paths().getTokenDatabasePath();
}
QString LoadTokensPage::getWindowTitle()
@ -692,7 +692,7 @@ void LoadTokensPage::retranslateUi()
fileButton->setText(tr("Choose file..."));
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)"));
}
@ -708,7 +708,7 @@ QString LoadSpoilersPage::getCustomUrlSettingsKey()
QString LoadSpoilersPage::getDefaultSavePath()
{
return SettingsCache::instance().getTokenDatabasePath();
return SettingsCache::instance().paths().getTokenDatabasePath();
}
QString LoadSpoilersPage::getWindowTitle()
@ -737,6 +737,6 @@ void LoadSpoilersPage::retranslateUi()
fileButton->setText(tr("Choose file..."));
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)"));
}