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
3 changes: 1 addition & 2 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
spinnerFrame(0),
platformStyle(_platformStyle)
{
GUIUtil::loadStyleSheet(this);

QSettings settings;
if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
// Restore failed (perhaps missing setting), center the window
Expand Down Expand Up @@ -844,6 +842,7 @@ void BitcoinGUI::optionsClicked()

OptionsDialog dlg(this, enableWallet);
dlg.setModel(clientModel->getOptionsModel());
connect(&dlg, &OptionsDialog::themeChanged, [=]() { GUIUtil::loadTheme(); });
dlg.exec();
}

Expand Down
2 changes: 2 additions & 0 deletions src/qt/dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)
{
window = new BitcoinGUI(platformStyle, networkStyle, 0);

GUIUtil::loadTheme(window);

pollShutdownTimer = new QTimer(window);
connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
}
Expand Down
72 changes: 52 additions & 20 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ static std::set<QWidget*> setFixedPitchFontUpdates;
// Contains all widgets where a non-default fontsize has been seet with GUIUtil::setFont
static std::map<QWidget*, int> mapFontSizeUpdates;

#ifdef Q_OS_MAC
// Contains all widgets where the macOS focus rect has been disabled.
static std::set<QWidget*> setRectsDisabled;
#endif

static const std::map<ThemedColor, QColor> themedColors = {
{ ThemedColor::DEFAULT, QColor(85, 85, 85) },
{ ThemedColor::UNCONFIRMED, QColor(128, 128, 128) },
Expand Down Expand Up @@ -1025,7 +1030,12 @@ const std::vector<QString> listThemes()
return vecThemes;
}

void loadStyleSheet(QWidget* widget, bool fDebugWidget)
const QString getDefaultTheme()
{
return defaultTheme;
}

void loadStyleSheet(QWidget* widget, bool fForceUpdate)
{
AssertLockNotHeld(cs_css);
LOCK(cs_css);
Expand All @@ -1036,7 +1046,7 @@ void loadStyleSheet(QWidget* widget, bool fDebugWidget)
bool fDebugCustomStyleSheets = gArgs.GetBoolArg("-debug-ui", false) && isStyleSheetDirectoryCustom();
bool fStyleSheetChanged = false;

if (stylesheet == nullptr || fDebugCustomStyleSheets) {
if (stylesheet == nullptr || fForceUpdate || fDebugCustomStyleSheets) {
auto hasModified = [](const std::vector<QString>& vecFiles) -> bool {
static std::map<const QString, QDateTime> mapLastModified;

Expand All @@ -1053,7 +1063,7 @@ void loadStyleSheet(QWidget* widget, bool fDebugWidget)
};

auto loadFiles = [&](const std::vector<QString>& vecFiles) -> bool {
if (fDebugCustomStyleSheets && !hasModified(vecFiles)) {
if (!fForceUpdate && fDebugCustomStyleSheets && !hasModified(vecFiles)) {
return false;
}

Expand Down Expand Up @@ -1086,29 +1096,27 @@ void loadStyleSheet(QWidget* widget, bool fDebugWidget)
fStyleSheetChanged = loadFiles(vecFiles);
}

bool fUpdateStyleSheet = fDebugCustomStyleSheets && fStyleSheetChanged;
bool fUpdateStyleSheet = fForceUpdate || (fDebugCustomStyleSheets && fStyleSheetChanged);

if (fDebugWidget) {
if (widget) {
setWidgets.insert(widget);
QWidgetList allWidgets = QApplication::allWidgets();
auto it = setWidgets.begin();
while (it != setWidgets.end()) {
if (!allWidgets.contains(*it)) {
it = setWidgets.erase(it);
continue;
}
if (fUpdateStyleSheet && *it != widget) {
(*it)->setStyleSheet(*stylesheet);
}
++it;
}
widget->setStyleSheet(*stylesheet);
}

if (widget) {
widget->setStyleSheet(*stylesheet);
QWidgetList allWidgets = QApplication::allWidgets();
auto it = setWidgets.begin();
while (it != setWidgets.end()) {
if (!allWidgets.contains(*it)) {
it = setWidgets.erase(it);
continue;
}
if (fUpdateStyleSheet && *it != widget) {
(*it)->setStyleSheet(*stylesheet);
}
++it;
}

if (!ShutdownRequested() && fDebugCustomStyleSheets) {
if (!ShutdownRequested() && fDebugCustomStyleSheets && !fForceUpdate) {
QTimer::singleShot(200, [] { loadStyleSheet(); });
}
}
Expand Down Expand Up @@ -1517,12 +1525,36 @@ bool dashThemeActive()
return theme != traditionalTheme;
}

void loadTheme(QWidget* widget, bool fForce)
{
loadStyleSheet(widget, fForce);
updateFonts();
updateMacFocusRects();
}

void disableMacFocusRect(const QWidget* w)
{
#ifdef Q_OS_MAC
for (const auto& c : w->findChildren<QWidget*>()) {
if (c->testAttribute(Qt::WA_MacShowFocusRect)) {
c->setAttribute(Qt::WA_MacShowFocusRect, !dashThemeActive());
setRectsDisabled.emplace(c);
}
}
#endif
}

void updateMacFocusRects()
{
#ifdef Q_OS_MAC
QWidgetList allWidgets = QApplication::allWidgets();
auto it = setRectsDisabled.begin();
while (it != setRectsDisabled.end()) {
if (allWidgets.contains(*it)) {
(*it)->setAttribute(Qt::WA_MacShowFocusRect, !dashThemeActive());
++it;
} else {
it = setRectsDisabled.erase(it);
}
}
#endif
Expand Down
17 changes: 13 additions & 4 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,13 @@ namespace GUIUtil
/** Return a list of all theme css files */
const std::vector<QString> listThemes();

/** Updates the widgets stylesheet and adds it to the list of ui debug elements
if fDebugWidget is true. Beeing on that list means the stylesheet of the
widget gets updated if the related css files has been changed if -debug-ui mode is active. */
void loadStyleSheet(QWidget* widget = nullptr, bool fDebugWidget = true);
/** Return the name of the default theme `*/
const QString getDefaultTheme();

/** Updates the widgets stylesheet and adds it to the list of ui debug elements.
Beeing on that list means the stylesheet of the widget gets updated if the
related css files has been changed if -debug-ui mode is active. */
void loadStyleSheet(QWidget* widget = nullptr, bool fForceUpdate = false);

enum class FontFamily {
SystemDefault,
Expand Down Expand Up @@ -335,10 +338,16 @@ namespace GUIUtil
/** Check if a dash specific theme is activated (light/dark).*/
bool dashThemeActive();

/** Load the theme and update all UI elements according to the appearance settings. */
void loadTheme(QWidget* widget = nullptr, bool fForce = true);

/** Disable the OS default focus rect for macOS because we have custom focus rects
* set in the css files */
void disableMacFocusRect(const QWidget* w);

/** Enable/Disable the macOS focus rects depending on the current theme. */
void updateMacFocusRects();

/* Convert QString to OS specific boost path through UTF-8 */
fs::path qstringToBoostPath(const QString &path);

Expand Down
18 changes: 17 additions & 1 deletion src/qt/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QIntValidator>
#include <QLocale>
#include <QMessageBox>
#include <QSettings>
#include <QTimer>

OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
Expand All @@ -36,6 +37,8 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
{
ui->setupUi(this);

previousTheme = GUIUtil::getActiveTheme();

GUIUtil::setFont({ui->statusLabel}, GUIUtil::FontWeight::Bold, 16);

GUIUtil::updateFonts();
Expand Down Expand Up @@ -104,6 +107,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
for (const QString& entry : GUIUtil::listThemes()) {
ui->theme->addItem(entry, QVariant(entry));
}
connect(ui->theme, SIGNAL(valueChanged()), this, SLOT(updateTheme()));

/* Language selector */
QDir translations(":translations");
Expand Down Expand Up @@ -188,7 +192,6 @@ void OptionsDialog::setModel(OptionsModel *_model)
connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
/* Display */
connect(ui->digits, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
connect(ui->theme, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));
}
Expand Down Expand Up @@ -293,6 +296,9 @@ void OptionsDialog::on_okButton_clicked()

void OptionsDialog::on_cancelButton_clicked()
{
if (previousTheme != GUIUtil::getActiveTheme()) {
updateTheme(previousTheme);
}
reject();
}

Expand Down Expand Up @@ -373,6 +379,16 @@ void OptionsDialog::updateDefaultProxyNets()
(strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false);
}

void OptionsDialog::updateTheme(const QString& theme)
{
QString newValue = theme.isEmpty() ? ui->theme->value().toString() : theme;
if (GUIUtil::getActiveTheme() != newValue) {
QSettings().setValue("theme", newValue);
QSettings().sync();
Q_EMIT themeChanged();
}
}

ProxyAddressValidator::ProxyAddressValidator(QObject *parent) :
QValidator(parent)
{
Expand Down
3 changes: 3 additions & 0 deletions src/qt/optionsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,18 @@ private Q_SLOTS:
void updateProxyValidationState();
/* query the networks, for which the default proxy is used */
void updateDefaultProxyNets();
void updateTheme(const QString& toTheme = QString());

Q_SIGNALS:
void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
void themeChanged();

private:
Ui::OptionsDialog *ui;
OptionsModel *model;
QDataWidgetMapper *mapper;
QButtonGroup pageButtons;
QString previousTheme;
};

#endif // BITCOIN_QT_OPTIONSDIALOG_H
8 changes: 3 additions & 5 deletions src/qt/optionsmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void OptionsModel::Init(bool resetSettings)
strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();

if (!settings.contains("theme"))
settings.setValue("theme", "");
settings.setValue("theme", GUIUtil::getDefaultTheme());

#ifdef ENABLE_WALLET
if (!settings.contains("fCoinControlFeatures"))
Expand Down Expand Up @@ -510,10 +510,8 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
break;
#endif // ENABLE_WALLET
case Theme:
if (settings.value("theme") != value) {
settings.setValue("theme", value);
setRestartRequired(true);
}
// Set in OptionsDialog::updateTheme slot now
// to allow instant theme changes.
break;
case Language:
if (settings.value("language") != value) {
Expand Down
10 changes: 10 additions & 0 deletions src/qt/rpcconsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,16 @@ void RPCConsole::hideEvent(QHideEvent *event)
clientModel->getPeerTableModel()->stopAutoRefresh();
}

void RPCConsole::changeEvent(QEvent* e)
{
if (e->type() == QEvent::StyleChange) {
clear();
ui->promptIcon->setHidden(GUIUtil::dashThemeActive());
}

QWidget::changeEvent(e);
}

void RPCConsole::showPeersTableContextMenu(const QPoint& point)
{
QModelIndex index = ui->peerWidget->indexAt(point);
Expand Down
1 change: 1 addition & 0 deletions src/qt/rpcconsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private Q_SLOTS:
void resizeEvent(QResizeEvent *event);
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);
void changeEvent(QEvent* e);
/** Show custom context menu on Peers tab */
void showPeersTableContextMenu(const QPoint& point);
/** Show custom context menu on Bans tab */
Expand Down
2 changes: 1 addition & 1 deletion src/qt/utilitydialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f):
{
setObjectName("ShutdownWindow");

GUIUtil::loadStyleSheet(this, false);
GUIUtil::loadStyleSheet(this);

QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(new QLabel(
Expand Down