qt: Add -custom-css-dir commmand line parameter (#3557)

* qt: Change themes path from ":themes" to ":css"

Required for the introduction of a custom css directory which will
happen with the follow-up commits.

* qt: Renamed trad.css to traditional.css

* qt: Add -custom-css-dir startup parameter

This allows to load a custom directory as css directory.

The custom directory currently needs to have the files:

- general.css
- dark.css
- light.css
- traditional.css
- scrollbars.css
This commit is contained in:
dustinface 2020-07-12 21:32:04 +02:00 committed by GitHub
parent fcd3029090
commit 41eceb8dd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 113 additions and 30 deletions

View File

@ -353,7 +353,7 @@ RES_CSS = \
qt/res/css/general.css \
qt/res/css/light.css \
qt/res/css/scrollbars.css \
qt/res/css/trad.css
qt/res/css/traditional.css
RES_FONTS = \
qt/res/fonts/Montserrat/Montserrat-Black.otf \

View File

@ -740,6 +740,41 @@ int main(int argc, char *argv[])
}
GUIUtil::setFontScale(nScale);
}
// Validate/set custom css directory
if (gArgs.IsArgSet("-custom-css-dir")) {
fs::path customDir = fs::path(gArgs.GetArg("-custom-css-dir", ""));
QString strCustomDir = QString::fromStdString(customDir.string());
std::vector<QString> vecRequiredFiles = GUIUtil::listStyleSheets();
QString strFile;
if (!fs::is_directory(customDir)) {
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error: Invalid -custom-css-dir path.") + "\n\n" + strCustomDir);
return EXIT_FAILURE;
}
for (auto itCustomDir = fs::directory_iterator(customDir); itCustomDir != fs::directory_iterator(); ++itCustomDir) {
if (fs::is_regular_file(*itCustomDir) && itCustomDir->path().extension() == ".css") {
strFile = QString::fromStdString(itCustomDir->path().filename().string());
auto itFile = std::find(vecRequiredFiles.begin(), vecRequiredFiles.end(), strFile);
if (itFile != vecRequiredFiles.end()) {
vecRequiredFiles.erase(itFile);
}
}
}
if (vecRequiredFiles.size()) {
QString strMissingFiles;
for (const auto& strMissingFile : vecRequiredFiles) {
strMissingFiles += strMissingFile + "\n";
}
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error: %1 CSS file(s) missing in -custom-css-dir path.").arg(vecRequiredFiles.size()) + "\n\n" + strMissingFiles);
return EXIT_FAILURE;
}
GUIUtil::setStyleSheetDirectory(strCustomDir);
}
// Subscribe to global signals from core
uiInterface.InitMessage.connect(InitMessage);

View File

@ -57,6 +57,9 @@
<qresource prefix="/css">
<file alias="general">res/css/general.css</file>
<file alias="scrollbars">res/css/scrollbars.css</file>
<file alias="Dark">res/css/dark.css</file>
<file alias="Light">res/css/light.css</file>
<file alias="Traditional">res/css/traditional.css</file>
</qresource>
<qresource prefix="/fonts">
<file alias="Montserrat-Black">res/fonts/Montserrat/Montserrat-Black.otf</file>
@ -78,11 +81,6 @@
<file alias="Montserrat-Thin">res/fonts/Montserrat/Montserrat-Thin.otf</file>
<file alias="Montserrat-ThinItalic">res/fonts/Montserrat/Montserrat-ThinItalic.otf</file>
</qresource>
<qresource prefix="/themes">
<file alias="Dark">res/css/dark.css</file>
<file alias="Light">res/css/light.css</file>
<file alias="Traditional">res/css/trad.css</file>
</qresource>
<qresource prefix="/images">
<file alias="arrow_down_normal">res/images/arrow_down_normal.png</file>
<file alias="arrow_down_hover">res/images/arrow_down_hover.png</file>

View File

@ -80,12 +80,24 @@ void ForceActivation();
namespace GUIUtil {
// The default stylesheet directory
static const QString defaultStylesheetDirectory = ":css";
// The actual stylesheet directory
static QString stylesheetDirectory = defaultStylesheetDirectory;
// The name of the traditional theme
static const QString traditionalTheme = "Traditional";
// The theme to set by default if settings are missing or incorrect
static const QString defaultTheme = "Light";
// The prefix a theme name should have if we want to apply dark colors and styles to it
static const QString darkThemePrefix = "Dark";
// Mapping css file => theme.
static const std::map<QString, QString> mapStyleToTheme{
{"general.css", ""},
{"dark.css", "Dark"},
{"light.css", "Light"},
{"traditional.css", "Traditional"},
{"scrollbars.css", ""}
};
/** Font related default values. */
static const FontFamily defaultFontFamily = FontFamily::SystemDefault;
@ -971,48 +983,73 @@ void migrateQtSettings()
}
}
void setStyleSheetDirectory(const QString& path)
{
stylesheetDirectory = path;
}
bool isStyleSheetDirectoryCustom()
{
return stylesheetDirectory != defaultStylesheetDirectory;
}
const std::vector<QString> listStyleSheets()
{
std::vector<QString> vecStylesheets;
for (const auto& it : mapStyleToTheme) {
vecStylesheets.push_back(it.first);
}
return vecStylesheets;
}
const std::vector<QString> listThemes()
{
std::vector<QString> vecThemes;
for (const auto& it : mapStyleToTheme) {
if (!it.second.isEmpty()) {
vecThemes.push_back(it.second);
}
}
return vecThemes;
}
// Open CSS when configured
QString loadStyleSheet()
{
static std::unique_ptr<QString> stylesheet;
if (stylesheet.get() == nullptr) {
if (stylesheet == nullptr) {
stylesheet = std::make_unique<QString>();
QSettings settings;
QDir themes(":themes");
QDir themes(":css");
QString theme = settings.value("theme", "").toString();
// Make sure settings are pointing to an existent theme
if (theme.isEmpty() || !themes.exists(theme)) {
if (!isStyleSheetDirectoryCustom() && (theme.isEmpty() || !themes.exists(theme))) {
theme = defaultTheme;
settings.setValue("theme", theme);
}
auto loadFile = [&](const QString& name) {
QFile qFile(stylesheetDirectory + "/" + name + (isStyleSheetDirectoryCustom() ? ".css" : ""));
if (qFile.open(QFile::ReadOnly)) {
stylesheet->append(QLatin1String(qFile.readAll()));
}
};
// If light/dark theme is used load general styles first
if (dashThemeActive()) {
QFile qFileGeneral(":css/general");
if (qFileGeneral.open(QFile::ReadOnly)) {
stylesheet.get()->append(QLatin1String(qFileGeneral.readAll()));
}
loadFile("general");
#ifndef Q_OS_MAC
// Apply some styling to scrollbars
QFile qFileScrollbars(QString(":/css/scrollbars"));
if (qFileScrollbars.open(QFile::ReadOnly)) {
stylesheet.get()->append(QLatin1String(qFileScrollbars.readAll()));
}
loadFile("scrollbars");
#endif
}
QFile qFileTheme(":themes/" + theme);
if (qFileTheme.open(QFile::ReadOnly)) {
stylesheet.get()->append(QLatin1String(qFileTheme.readAll()));
}
loadFile(theme);
}
return *stylesheet.get();
return *stylesheet;
}
FontFamily fontFamilyFromString(const QString& strFamily)

View File

@ -230,6 +230,19 @@ namespace GUIUtil
/** Modify Qt network specific settings on migration */
void migrateQtSettings();
/** Change the stylesheet directory. This is used by
the parameter -custom-css-dir.*/
void setStyleSheetDirectory(const QString& path);
/** Check if a custom css directory has been set with -custom-css-dir */
bool isStyleSheetDirectoryCustom();
/** Return a list of all required css files */
const std::vector<QString> listStyleSheets();
/** Return a list of all theme css files */
const std::vector<QString> listThemes();
/** Load global CSS theme */
QString loadStyleSheet();

View File

@ -90,8 +90,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
}
/* Theme selector */
QDir themes(":themes");
for (const QString &entry : themes.entryList()) {
for (const QString& entry : GUIUtil::listThemes()) {
ui->theme->addItem(entry, QVariant(entry));
}

View File

@ -10,7 +10,7 @@ loaded and combined in `GUIUtil::loadStyleSheet()` in guitil.cpp.
Hierarchy:
* general.css - base layout: Loaded first if selected theme is not "Traditional" (trad.css)
* general.css - base layout: Loaded first if selected theme is not "Traditional" (traditional.css)
* scrollbars.css - custom scrollbars: Loaded second only for windows/linux if general.css is loaded
* <theme.css> - theme css file: Always loaded and loaded last.
@ -18,7 +18,7 @@ To replace <theme.css> there are currently the following themes available:
* Dark (dark.css)
* Light (light.css)
* Traditional (trad.css)
* Traditional (traditional.css)
NOTE: This file is only the base layout which is getting
shared between all full themes (e.g. Dark or Light). It may contain

View File

@ -17,7 +17,7 @@ Loaded in GUIUtil::loadStyleSheet() in guitil.cpp.
/* do not modify! section updated by update-css-files.py
<colors>
# Used colors in trad.css for commit 3bebd1a5c
# Used colors in traditional.css for commit 3bebd1a5c
#fff
#ccfafafa

View File

@ -88,6 +88,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, HelpMode helpMode) :
strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", strprintf("Allow self signed root certificates (default: %u)", DEFAULT_SELFSIGNED_ROOTCERTS));
}
strUsage += HelpMessageOpt("-choosedatadir", strprintf(tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR));
strUsage += HelpMessageOpt("-custom-css-dir", "Set a directory which contains custom css files. Those will be used as stylesheets for the UI.");
strUsage += HelpMessageOpt("-font-family", tr("Set the font family. Possible values: %1. (default: %2)").arg("SystemDefault, Montserrat").arg(GUIUtil::fontFamilyToString(GUIUtil::getFontFamilyDefault())).toStdString());
strUsage += HelpMessageOpt("-font-scale", tr("Set a scale factor which gets applied to the base font size. Possible range %1 (smallest fonts) to %2 (largest fonts). (default: %3)").arg(-100).arg(100).arg(GUIUtil::getFontScaleDefault()).toStdString());
strUsage += HelpMessageOpt("-font-weight-bold", tr("Set the font weight for bold texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::weightToArg(GUIUtil::getFontWeightBoldDefault())).toStdString());