Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
35 changes: 35 additions & 0 deletions src/qt/dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the double new line?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get a bit space before the list of missing files. Thanks for asking haven't tested that for a while and it now realised that i messed with it over the time, will force push soon.
Bildschirmfoto 2020-07-11 um 05 07 14

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);
Expand Down
8 changes: 3 additions & 5 deletions src/qt/dash.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down
75 changes: 56 additions & 19 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

// 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()));
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()) {
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)
Expand Down
13 changes: 13 additions & 0 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
3 changes: 1 addition & 2 deletions src/qt/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
4 changes: 2 additions & 2 deletions src/qt/res/css/general.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ 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.

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
Expand Down
2 changes: 1 addition & 1 deletion src/qt/res/css/trad.css → src/qt/res/css/traditional.css
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/qt/utilitydialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down