add button to open themes location to settings (#4289)

* add button to open themes location to settings

botton creates directory if it doesn't exist yet
themes path is no longer hardcoded but included in settings
themes now default to None  the default theme is no longer required
themes set to None  will not look for empty directories anymore
this is backwards compatible
users with a nonexistant theme (Default) set will get the new None  theme

* remove default theme from install instructions
This commit is contained in:
ebbit1q 2021-03-21 18:11:34 +01:00 committed by GitHub
parent c5fac2ee35
commit 07ea2d4334
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 81 additions and 28 deletions

View file

@ -15,6 +15,7 @@
#include <QCloseEvent> #include <QCloseEvent>
#include <QComboBox> #include <QComboBox>
#include <QDebug> #include <QDebug>
#include <QDesktopServices>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QFileDialog> #include <QFileDialog>
@ -291,10 +292,12 @@ AppearanceSettingsPage::AppearanceSettingsPage()
} }
connect(&themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themeBoxChanged(int))); connect(&themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themeBoxChanged(int)));
connect(&openThemeButton, SIGNAL(clicked()), this, SLOT(openThemeLocation()));
auto *themeGrid = new QGridLayout; auto *themeGrid = new QGridLayout;
themeGrid->addWidget(&themeLabel, 0, 0); themeGrid->addWidget(&themeLabel, 0, 0);
themeGrid->addWidget(&themeBox, 0, 1); themeGrid->addWidget(&themeBox, 0, 1);
themeGrid->addWidget(&openThemeButton, 1, 1);
themeGroupBox = new QGroupBox; themeGroupBox = new QGroupBox;
themeGroupBox->setLayout(themeGrid); themeGroupBox->setLayout(themeGrid);
@ -370,10 +373,24 @@ void AppearanceSettingsPage::themeBoxChanged(int index)
SettingsCache::instance().setThemeName(themeDirs.at(index)); SettingsCache::instance().setThemeName(themeDirs.at(index));
} }
void AppearanceSettingsPage::openThemeLocation()
{
QString dir = SettingsCache::instance().getThemesPath();
QDir dirDir = dir;
dirDir.cdUp();
// open if dir exists, create if parent dir does exist
if (dirDir.exists() && dirDir.mkpath(dir)) {
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
} else {
QMessageBox::critical(this, tr("Error"), tr("Could not create themes directory at '%1'.").arg(dir));
}
}
void AppearanceSettingsPage::retranslateUi() void AppearanceSettingsPage::retranslateUi()
{ {
themeGroupBox->setTitle(tr("Theme settings")); themeGroupBox->setTitle(tr("Theme settings"));
themeLabel.setText(tr("Current theme:")); themeLabel.setText(tr("Current theme:"));
openThemeButton.setText(tr("Open themes folder"));
cardsGroupBox->setTitle(tr("Card rendering")); cardsGroupBox->setTitle(tr("Card rendering"));
displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture")); displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture"));

View file

@ -79,10 +79,12 @@ class AppearanceSettingsPage : public AbstractSettingsPage
Q_OBJECT Q_OBJECT
private slots: private slots:
void themeBoxChanged(int index); void themeBoxChanged(int index);
void openThemeLocation();
private: private:
QLabel themeLabel; QLabel themeLabel;
QComboBox themeBox; QComboBox themeBox;
QPushButton openThemeButton;
QLabel minPlayersForMultiColumnLayoutLabel; QLabel minPlayersForMultiColumnLayoutLabel;
QLabel maxFontSizeForCardsLabel; QLabel maxFontSizeForCardsLabel;
QCheckBox displayCardNamesCheckBox; QCheckBox displayCardNamesCheckBox;

View file

@ -197,6 +197,7 @@ SettingsCache::SettingsCache()
deckPath = getSafeConfigPath("paths/decks", dataPath + "/decks/"); deckPath = getSafeConfigPath("paths/decks", dataPath + "/decks/");
replaysPath = getSafeConfigPath("paths/replays", dataPath + "/replays/"); replaysPath = getSafeConfigPath("paths/replays", dataPath + "/replays/");
themesPath = getSafeConfigPath("paths/themes", dataPath + "/themes/");
picsPath = getSafeConfigPath("paths/pics", dataPath + "/pics/"); picsPath = getSafeConfigPath("paths/pics", dataPath + "/pics/");
// this has never been exposed as an user-configurable setting // this has never been exposed as an user-configurable setting
if (picsPath.endsWith("/")) { if (picsPath.endsWith("/")) {
@ -388,6 +389,13 @@ void SettingsCache::setReplaysPath(const QString &_replaysPath)
settings->setValue("paths/replays", 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) void SettingsCache::setCustomCardDatabasePath(const QString &_customCardDatabasePath)
{ {
customCardDatabasePath = _customCardDatabasePath; customCardDatabasePath = _customCardDatabasePath;

View file

@ -66,7 +66,7 @@ private:
QByteArray mainWindowGeometry; QByteArray mainWindowGeometry;
QByteArray tokenDialogGeometry; QByteArray tokenDialogGeometry;
QString lang; QString lang;
QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, themesPath,
spoilerDatabasePath, tokenDatabasePath, themeName; spoilerDatabasePath, tokenDatabasePath, themeName;
bool notifyAboutUpdates; bool notifyAboutUpdates;
bool notifyAboutNewVersion; bool notifyAboutNewVersion;
@ -157,6 +157,10 @@ public:
{ {
return replaysPath; return replaysPath;
} }
QString getThemesPath() const
{
return themesPath;
}
QString getPicsPath() const QString getPicsPath() const
{ {
return picsPath; return picsPath;
@ -479,6 +483,7 @@ public slots:
void setSeenTips(const QList<int> &_seenTips); void setSeenTips(const QList<int> &_seenTips);
void setDeckPath(const QString &_deckPath); void setDeckPath(const QString &_deckPath);
void setReplaysPath(const QString &_replaysPath); void setReplaysPath(const QString &_replaysPath);
void setThemesPath(const QString &_themesPath);
void setCustomCardDatabasePath(const QString &_customCardDatabasePath); void setCustomCardDatabasePath(const QString &_customCardDatabasePath);
void setPicsPath(const QString &_picsPath); void setPicsPath(const QString &_picsPath);
void setCardDatabasePath(const QString &_cardDatabasePath); void setCardDatabasePath(const QString &_cardDatabasePath);

View file

@ -9,12 +9,17 @@
#include <QPixmapCache> #include <QPixmapCache>
#include <QStandardPaths> #include <QStandardPaths>
#define DEFAULT_THEME_NAME "Default" #define NONE_THEME_NAME "None "
#define STYLE_CSS_NAME "style.css" #define STYLE_CSS_NAME "style.css"
#define HANDZONE_BG_NAME "handzone" #define HANDZONE_BG_NAME "handzone"
#define PLAYERZONE_BG_NAME "playerzone" #define PLAYERZONE_BG_NAME "playerzone"
#define STACKZONE_BG_NAME "stackzone" #define STACKZONE_BG_NAME "stackzone"
#define TABLEZONE_BG_NAME "tablezone" #define TABLEZONE_BG_NAME "tablezone"
static const QColor HANDZONE_BG_DEFAULT = QColor(80, 100, 50);
static const QColor TABLEZONE_BG_DEFAULT = QColor(70, 50, 100);
static const QColor PLAYERZONE_BG_DEFAULT = QColor(200, 200, 200);
static const QColor STACKZONE_BG_DEFAULT = QColor(113, 43, 43);
static const QStringList DEFAULT_RESOURCE_PATHS = {":/resources"};
ThemeManager::ThemeManager(QObject *parent) : QObject(parent) ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
{ {
@ -28,7 +33,7 @@ void ThemeManager::ensureThemeDirectoryExists()
if (SettingsCache::instance().getThemeName().isEmpty() || if (SettingsCache::instance().getThemeName().isEmpty() ||
!getAvailableThemes().contains(SettingsCache::instance().getThemeName())) { !getAvailableThemes().contains(SettingsCache::instance().getThemeName())) {
qDebug() << "Theme name not set, setting default value"; qDebug() << "Theme name not set, setting default value";
SettingsCache::instance().setThemeName(DEFAULT_THEME_NAME); SettingsCache::instance().setThemeName(NONE_THEME_NAME);
} }
} }
@ -37,12 +42,16 @@ QStringMap &ThemeManager::getAvailableThemes()
QDir dir; QDir dir;
availableThemes.clear(); availableThemes.clear();
// load themes from user profile dir // add default value
dir.setPath(SettingsCache::instance().getDataPath() + "/themes"); availableThemes.insert(NONE_THEME_NAME, QString());
foreach (QString themeName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) { // load themes from user profile dir
if (!availableThemes.contains(themeName)) dir.setPath(SettingsCache::instance().getThemesPath());
for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
if (!availableThemes.contains(themeName)) {
availableThemes.insert(themeName, dir.absoluteFilePath(themeName)); availableThemes.insert(themeName, dir.absoluteFilePath(themeName));
}
} }
// load themes from cockatrice system dir // load themes from cockatrice system dir
@ -56,9 +65,10 @@ QStringMap &ThemeManager::getAvailableThemes()
#endif #endif
); );
foreach (QString themeName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) { for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
if (!availableThemes.contains(themeName)) if (!availableThemes.contains(themeName)) {
availableThemes.insert(themeName, dir.absoluteFilePath(themeName)); availableThemes.insert(themeName, dir.absoluteFilePath(themeName));
}
} }
return availableThemes; return availableThemes;
@ -97,26 +107,36 @@ void ThemeManager::themeChangedSlot()
QString themeName = SettingsCache::instance().getThemeName(); QString themeName = SettingsCache::instance().getThemeName();
qDebug() << "Theme changed:" << themeName; qDebug() << "Theme changed:" << themeName;
QDir dir = getAvailableThemes().value(themeName); QString dirPath = getAvailableThemes().value(themeName);
QDir dir = dirPath;
// css // css
if (dir.exists(STYLE_CSS_NAME)) if (!dirPath.isEmpty() && dir.exists(STYLE_CSS_NAME)) {
qApp->setStyleSheet("file:///" + dir.absoluteFilePath(STYLE_CSS_NAME)); qApp->setStyleSheet("file:///" + dir.absoluteFilePath(STYLE_CSS_NAME));
else } else {
qApp->setStyleSheet(""); qApp->setStyleSheet("");
}
// resources if (dirPath.isEmpty()) {
QStringList resources; // set default values
resources << dir.absolutePath() << ":/resources"; QDir::setSearchPaths("theme", DEFAULT_RESOURCE_PATHS);
QDir::setSearchPaths("theme", resources); handBgBrush = HANDZONE_BG_DEFAULT;
tableBgBrush = TABLEZONE_BG_DEFAULT;
playerBgBrush = PLAYERZONE_BG_DEFAULT;
stackBgBrush = STACKZONE_BG_DEFAULT;
} else {
// resources
QStringList resources;
resources << dir.absolutePath() << DEFAULT_RESOURCE_PATHS;
QDir::setSearchPaths("theme", resources);
// zones bg // zones bg
dir.cd("zones"); dir.cd("zones");
handBgBrush = loadBrush(HANDZONE_BG_NAME, QColor(80, 100, 50)); handBgBrush = loadBrush(HANDZONE_BG_NAME, HANDZONE_BG_DEFAULT);
tableBgBrush = loadBrush(TABLEZONE_BG_NAME, QColor(70, 50, 100)); tableBgBrush = loadBrush(TABLEZONE_BG_NAME, TABLEZONE_BG_DEFAULT);
playerBgBrush = loadBrush(PLAYERZONE_BG_NAME, QColor(200, 200, 200)); playerBgBrush = loadBrush(PLAYERZONE_BG_NAME, PLAYERZONE_BG_DEFAULT);
stackBgBrush = loadBrush(STACKZONE_BG_NAME, QColor(113, 43, 43)); stackBgBrush = loadBrush(STACKZONE_BG_NAME, STACKZONE_BG_DEFAULT);
}
tableBgBrushesCache.clear(); tableBgBrushesCache.clear();
stackBgBrushesCache.clear(); stackBgBrushesCache.clear();
playerBgBrushesCache.clear(); playerBgBrushesCache.clear();

View file

@ -3,7 +3,6 @@
# add themes subfolders # add themes subfolders
SET(defthemes SET(defthemes
Default
Fabric Fabric
Leather Leather
Plasma Plasma

View file

@ -1,4 +0,0 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View file

@ -96,6 +96,9 @@ void SettingsCache::setDeckPath(const QString &/* _deckPath */)
void SettingsCache::setReplaysPath(const QString &/* _replaysPath */) void SettingsCache::setReplaysPath(const QString &/* _replaysPath */)
{ {
} }
void SettingsCache::setThemesPath(const QString &/* _themesPath */)
{
}
void SettingsCache::setPicsPath(const QString &/* _picsPath */) void SettingsCache::setPicsPath(const QString &/* _picsPath */)
{ {
} }

View file

@ -100,6 +100,9 @@ void SettingsCache::setDeckPath(const QString &/* _deckPath */)
void SettingsCache::setReplaysPath(const QString &/* _replaysPath */) void SettingsCache::setReplaysPath(const QString &/* _replaysPath */)
{ {
} }
void SettingsCache::setThemesPath(const QString &/* _themesPath */)
{
}
void SettingsCache::setPicsPath(const QString &/* _picsPath */) void SettingsCache::setPicsPath(const QString &/* _picsPath */)
{ {
} }