diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml
index 20bf854da..b8e0d12dc 100644
--- a/resources/desktop/com.github.rssguard.appdata.xml
+++ b/resources/desktop/com.github.rssguard.appdata.xml
@@ -26,7 +26,7 @@
https://github.com/sponsors/martinrotter
-
+
none
diff --git a/src/librssguard/core/messagesforfiltersmodel.cpp b/src/librssguard/core/messagesforfiltersmodel.cpp
index f0c793ce2..ea32ac6b2 100644
--- a/src/librssguard/core/messagesforfiltersmodel.cpp
+++ b/src/librssguard/core/messagesforfiltersmodel.cpp
@@ -39,11 +39,11 @@ QVariant MessagesForFiltersModel::data(const QModelIndex& index, int role) const
if (m_filteringDecisions.contains(index.row())) {
switch (m_filteringDecisions.value(index.row())) {
case MessageObject::FilteringAction::Accept:
- return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::Allright];
+ return qApp->skins()->currentSkin().colorForModel(SkinEnums::PaletteColors::Allright);
case MessageObject::FilteringAction::Ignore:
case MessageObject::FilteringAction::Purge:
- return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgError];
+ return qApp->skins()->currentSkin().colorForModel(SkinEnums::PaletteColors::FgError);
default:
break;
diff --git a/src/librssguard/core/messagesmodel.cpp b/src/librssguard/core/messagesmodel.cpp
index c5c5f6c51..12d14a68f 100644
--- a/src/librssguard/core/messagesmodel.cpp
+++ b/src/librssguard/core/messagesmodel.cpp
@@ -396,9 +396,9 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important);
return dta.toInt() == 1
- ? qApp->skins()->currentSkin().m_colorPalette[role == Qt::ItemDataRole::ForegroundRole
+ ? qApp->skins()->currentSkin().colorForModel(role == Qt::ItemDataRole::ForegroundRole
? SkinEnums::PaletteColors::FgInteresting
- : SkinEnums::PaletteColors::FgSelectedInteresting]
+ : SkinEnums::PaletteColors::FgSelectedInteresting)
: QVariant();
}
@@ -407,9 +407,9 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read);
return dta.toInt() == 0
- ? qApp->skins()->currentSkin().m_colorPalette[role == Qt::ItemDataRole::ForegroundRole
+ ? qApp->skins()->currentSkin().colorForModel(role == Qt::ItemDataRole::ForegroundRole
? SkinEnums::PaletteColors::FgInteresting
- : SkinEnums::PaletteColors::FgSelectedInteresting]
+ : SkinEnums::PaletteColors::FgSelectedInteresting)
: QVariant();
}
diff --git a/src/librssguard/gui/messagebrowser.cpp b/src/librssguard/gui/messagebrowser.cpp
index 0295a50d6..59e560647 100644
--- a/src/librssguard/gui/messagebrowser.cpp
+++ b/src/librssguard/gui/messagebrowser.cpp
@@ -163,13 +163,17 @@ QString MessageBrowser::prepareHtmlForMessage(const Message& message) {
.replace(QL1C('\r'), QL1C('\n'))
.remove(QL1C('\n'));*/
+ // TODO: If FgInteresting not defined by the skin
+ // use current pallette/Highlight color perhaps.E
return QSL(""
""
"%1"
"").arg(html,
- qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgInteresting].name());
+ qApp->skins()->currentSkin()
+ .colorForModel(SkinEnums::PaletteColors::FgInteresting)
+ .value().name());
}
bool MessageBrowser::eventFilter(QObject* watched, QEvent* event) {
diff --git a/src/librssguard/gui/reusable/colortoolbutton.cpp b/src/librssguard/gui/reusable/colortoolbutton.cpp
index b264e0cf3..037555c05 100644
--- a/src/librssguard/gui/reusable/colortoolbutton.cpp
+++ b/src/librssguard/gui/reusable/colortoolbutton.cpp
@@ -29,8 +29,14 @@ QColor ColorToolButton::color() const {
}
void ColorToolButton::setColor(const QColor& color) {
+ bool changed = m_color != color;
+
m_color = color;
+ if (changed) {
+ emit colorChanged(m_color);
+ }
+
repaint();
}
diff --git a/src/librssguard/gui/settings/settingsdatabase.ui b/src/librssguard/gui/settings/settingsdatabase.ui
index 8ce64d3af..513b2181f 100644
--- a/src/librssguard/gui/settings/settingsdatabase.ui
+++ b/src/librssguard/gui/settings/settingsdatabase.ui
@@ -271,7 +271,6 @@ Authors of this application are NOT responsible for lost data.
m_stackedDatabaseDriver
m_checkUseTransactions
m_lblDataStorageWarning
- verticalSpacer
diff --git a/src/librssguard/gui/settings/settingsgui.cpp b/src/librssguard/gui/settings/settingsgui.cpp
index 9a5d4672c..6fc0d09ed 100644
--- a/src/librssguard/gui/settings/settingsgui.cpp
+++ b/src/librssguard/gui/settings/settingsgui.cpp
@@ -5,6 +5,8 @@
#include "core/feedsmodel.h"
#include "gui/dialogs/formmain.h"
#include "gui/feedmessageviewer.h"
+#include "gui/reusable/colortoolbutton.h"
+#include "gui/reusable/plaintoolbutton.h"
#include "gui/systemtrayicon.h"
#include "gui/tabwidget.h"
#include "gui/toolbars/feedstoolbar.h"
@@ -15,6 +17,8 @@
#include "miscellaneous/settings.h"
#include
+#include
+#include
#include
SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(settings, parent), m_ui(new Ui::SettingsGui) {
@@ -30,8 +34,12 @@ SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(se
<< /*: Version column of skin list. */ tr("Version")
<< tr("Author"));
+ m_ui->m_helpCustomSkinColors->setHelpText(tr("You can override some colors defined by your skin here. "
+ "Some colors are used dynamically throughout the application."), false);
+
// Setup skins.
m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
+
m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);
@@ -64,6 +72,8 @@ SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(se
connect(m_ui->m_cmbStyles, static_cast(&QComboBox::currentIndexChanged), this, &SettingsGui::dirtifySettings);
connect(m_ui->m_cmbSelectToolBar, static_cast(&QComboBox::currentIndexChanged), m_ui->m_stackedToolbars,
&QStackedWidget::setCurrentIndex);
+ connect(m_ui->m_gbCustomSkinColors, &QGroupBox::toggled, this, &SettingsGui::dirtifySettings);
+ connect(m_ui->m_gbCustomSkinColors, &QGroupBox::toggled, this, &SettingsGui::requireRestart);
}
SettingsGui::~SettingsGui() {
@@ -198,12 +208,74 @@ void SettingsGui::loadSettings() {
m_ui->m_editorFeedsToolbar->loadFromToolBar(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsToolBar());
m_ui->m_editorMessagesToolbar->loadFromToolBar(qApp->mainForm()->tabWidget()->feedMessageViewer()->messagesToolBar());
m_ui->m_editorStatusbar->loadFromToolBar(qApp->mainForm()->statusBar());
+
+ // Load custom colors.
+ m_ui->m_gbCustomSkinColors->setChecked(settings()->value(GROUP(CustomSkinColors),
+ SETTING(CustomSkinColors::Enabled)).toBool());
+
+ const QMetaObject& mo = SkinEnums::staticMetaObject;
+ QMetaEnum enumer = mo.enumerator(mo.indexOfEnumerator(QSL("PaletteColors").toLocal8Bit().constData()));
+
+ for (int i = 0, row = 0; i < enumer.keyCount(); i++, row++) {
+ SkinEnums::PaletteColors pal = SkinEnums::PaletteColors(enumer.value(i));
+
+ auto* clr_btn = new ColorToolButton(this);
+ auto* rst_btn = new PlainToolButton(this);
+
+ rst_btn->setToolTip(tr("Fetch color from activated skin"));
+ rst_btn->setIcon(qApp->icons()->fromTheme(QSL("edit-reset")));
+
+ QColor clr = settings()->value(GROUP(CustomSkinColors), enumer.key(i)).toString();
+
+ if (!clr.isValid()) {
+ clr = qApp->skins()->currentSkin().colorForModel(pal).value();
+ }
+
+ rst_btn->setObjectName(QString::number(enumer.value(i)));
+
+ connect(rst_btn, &PlainToolButton::clicked, this, &SettingsGui::resetCustomSkinColor);
+ connect(clr_btn, &ColorToolButton::colorChanged, this, &SettingsGui::dirtifySettings);
+ connect(clr_btn, &ColorToolButton::colorChanged, this, &SettingsGui::requireRestart);
+
+ clr_btn->setObjectName(QString::number(enumer.value(i)));
+ clr_btn->setColor(clr);
+
+ auto* lay = new QHBoxLayout(this);
+
+ lay->addWidget(clr_btn);
+ lay->addWidget(rst_btn);
+
+ m_ui->m_layoutCustomColors->setWidget(row, QFormLayout::ItemRole::LabelRole, new QLabel(enumer.key(i), this));
+ m_ui->m_layoutCustomColors->setLayout(row, QFormLayout::ItemRole::FieldRole, lay);
+
+ }
+
onEndLoadSettings();
}
+void SettingsGui::resetCustomSkinColor() {
+ auto* clr_btn = m_ui->m_gbCustomSkinColors->findChild(sender()->objectName());
+ SkinEnums::PaletteColors pal = SkinEnums::PaletteColors(sender()->objectName().toInt());
+
+ clr_btn->setColor(qApp->skins()->currentSkin().colorForModel(pal, true).value());
+}
+
void SettingsGui::saveSettings() {
onBeginSaveSettings();
+ // Save custom skin colors.
+ settings()->setValue(GROUP(CustomSkinColors), CustomSkinColors::Enabled, m_ui->m_gbCustomSkinColors->isChecked());
+
+ const QMetaObject& mo = SkinEnums::staticMetaObject;
+ QMetaEnum enumer = mo.enumerator(mo.indexOfEnumerator(QSL("PaletteColors").toLocal8Bit().constData()));
+ auto children = m_ui->m_gbCustomSkinColors->findChildren();
+
+ for (const ColorToolButton* clr : children) {
+ settings()->setValue(GROUP(CustomSkinColors),
+ enumer.valueToKey(clr->objectName().toInt()),
+ clr->color().name());
+ }
+
// Save toolbar.
settings()->setValue(GROUP(GUI), GUI::ToolbarStyle,
m_ui->m_cmbToolbarButtonStyle->itemData(m_ui->m_cmbToolbarButtonStyle->currentIndex()));
diff --git a/src/librssguard/gui/settings/settingsgui.h b/src/librssguard/gui/settings/settingsgui.h
index 1aded5405..fabce3322 100644
--- a/src/librssguard/gui/settings/settingsgui.h
+++ b/src/librssguard/gui/settings/settingsgui.h
@@ -23,6 +23,9 @@ class SettingsGui : public SettingsPanel {
// Does check of controls before dialog can be submitted.
bool eventFilter(QObject* obj, QEvent* e);
+ private slots:
+ void resetCustomSkinColor();
+
private:
Ui::SettingsGui* m_ui;
};
diff --git a/src/librssguard/gui/settings/settingsgui.ui b/src/librssguard/gui/settings/settingsgui.ui
index b29ae5669..4c5a8ca30 100644
--- a/src/librssguard/gui/settings/settingsgui.ui
+++ b/src/librssguard/gui/settings/settingsgui.ui
@@ -20,7 +20,7 @@
-
- 0
+ 1
@@ -109,6 +109,27 @@
+
+
+ Custom skin colors
+
+
+ -
+
+
+ -
+
+
+ Force custom skin colors
+
+
+ true
+
+
+
+
+
+
Tray area
@@ -374,6 +395,12 @@
1
+
+ HelpSpoiler
+ QWidget
+
+ 1
+
m_tabUi
diff --git a/src/librssguard/gui/webviewer.cpp b/src/librssguard/gui/webviewer.cpp
index 7e9e40454..85eb84a96 100644
--- a/src/librssguard/gui/webviewer.cpp
+++ b/src/librssguard/gui/webviewer.cpp
@@ -323,7 +323,8 @@ void WebViewer::onLinkHovered(const QString& url) {
{ url, url, QSystemTrayIcon::MessageIcon::NoIcon },
{ false, false, true });
- QToolTip::showText(QCursor::pos(), url, {}, {}, 6000);
+ // NOTE: Disable for now, not needed.
+ //QToolTip::showText(QCursor::pos(), url, {}, {}, 6000);
}
void WebViewer::openUrlWithExternalTool(ExternalTool tool, const QString& target_url) {
diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp
index ce4106095..d1b4dd89d 100644
--- a/src/librssguard/miscellaneous/settings.cpp
+++ b/src/librssguard/miscellaneous/settings.cpp
@@ -134,6 +134,12 @@ NON_CONST_DVALUE(QString) Messages::PreviewerFontStandardDef = QFont(QFont().fam
DKEY Messages::ListFont = "list_font";
+// Custom skin colors.
+DKEY CustomSkinColors::ID = "custom_skin_colors";
+
+DKEY CustomSkinColors::Enabled = "enabled";
+DVALUE(bool) CustomSkinColors::EnabledDef = false;
+
// GUI.
DKEY GUI::ID = "gui";
diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h
index f3b9d8432..502ca5dc4 100644
--- a/src/librssguard/miscellaneous/settings.h
+++ b/src/librssguard/miscellaneous/settings.h
@@ -152,6 +152,16 @@ namespace Messages {
KEY ListFont;
}
+// Custom skin colors.
+namespace CustomSkinColors {
+ KEY ID;
+
+ KEY Enabled;
+ VALUE(bool) EnabledDef;
+
+ KEY CustomSkinColors;
+}
+
// GUI.
namespace GUI {
KEY ID;
diff --git a/src/librssguard/miscellaneous/skinfactory.cpp b/src/librssguard/miscellaneous/skinfactory.cpp
index 7efb9c321..46ddfabd7 100644
--- a/src/librssguard/miscellaneous/skinfactory.cpp
+++ b/src/librssguard/miscellaneous/skinfactory.cpp
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include
#include
@@ -50,8 +51,17 @@ bool SkinFactory::isStyleGoodForDarkVariant(const QString& style_name) const {
void SkinFactory::loadSkinFromData(const Skin& skin) {
QString style_name = qApp->settings()->value(GROUP(GUI), SETTING(GUI::Style)).toString();
+ auto env = QProcessEnvironment::systemEnvironment();
+ QString over_style = env.value(QSL("QT_STYLE_OVERRIDE"));
- qApp->setStyle(style_name);
+ if (over_style.isEmpty()) {
+ qApp->setStyle(style_name);
+
+ qDebugNN << LOGSEC_GUI << "Setting style:" << QUOTE_W_SPACE_DOT(style_name);
+ }
+ else {
+ qDebugNN << LOGSEC_GUI << "Respecting forced style:" << QUOTE_W_SPACE_DOT(over_style);
+ }
if (isStyleGoodForDarkVariant(style_name) &&
qApp->settings()->value(GROUP(GUI), SETTING(GUI::ForceDarkFusion)).toBool()) {
@@ -317,3 +327,19 @@ QList SkinFactory::installedSkins() const {
uint qHash(const SkinEnums::PaletteColors& key) {
return uint(key);
}
+
+QVariant Skin::colorForModel(SkinEnums::PaletteColors type, bool ignore_custom_colors) const {
+ if (!ignore_custom_colors) {
+ const QMetaObject& mo = SkinEnums::staticMetaObject;
+ QMetaEnum enumer = mo.enumerator(mo.indexOfEnumerator(QSL("PaletteColors").toLocal8Bit().constData()));
+ QColor custom_clr = qApp->settings()->value(GROUP(CustomSkinColors), enumer.valueToKey(int(type))).toString();
+
+ if (custom_clr.isValid()) {
+ return custom_clr;
+ }
+ }
+
+ return m_colorPalette.contains(type)
+ ? m_colorPalette[type]
+ : QVariant();
+}
diff --git a/src/librssguard/miscellaneous/skinfactory.h b/src/librssguard/miscellaneous/skinfactory.h
index 882f018b1..0cd5a3e46 100644
--- a/src/librssguard/miscellaneous/skinfactory.h
+++ b/src/librssguard/miscellaneous/skinfactory.h
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
class SkinEnums : public QObject {
Q_OBJECT
@@ -46,6 +47,8 @@ struct RSSGUARD_DLLSPEC Skin {
QString m_layoutMarkup;
QString m_enclosureMarkup;
QHash m_colorPalette;
+
+ QVariant colorForModel(SkinEnums::PaletteColors type, bool ignore_custom_colors = false) const;
};
uint qHash(const SkinEnums::PaletteColors& key);
diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp
index 32ada58d0..1ec655171 100644
--- a/src/librssguard/services/abstract/feed.cpp
+++ b/src/librssguard/services/abstract/feed.cpp
@@ -56,13 +56,13 @@ QVariant Feed::data(int column, int role) const {
case HIGHLIGHTED_FOREGROUND_TITLE_ROLE:
switch (status()) {
case Status::NewMessages:
- return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgSelectedInteresting];
+ return qApp->skins()->currentSkin().colorForModel(SkinEnums::PaletteColors::FgSelectedInteresting);
case Status::NetworkError:
case Status::ParsingError:
case Status::AuthError:
case Status::OtherError:
- return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgSelectedError];
+ return qApp->skins()->currentSkin().colorForModel(SkinEnums::PaletteColors::FgSelectedError);
default:
return QVariant();
@@ -71,13 +71,13 @@ QVariant Feed::data(int column, int role) const {
case Qt::ItemDataRole::ForegroundRole:
switch (status()) {
case Status::NewMessages:
- return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgInteresting];
+ return qApp->skins()->currentSkin().colorForModel(SkinEnums::PaletteColors::FgInteresting);
case Status::NetworkError:
case Status::ParsingError:
case Status::AuthError:
case Status::OtherError:
- return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgError];
+ return qApp->skins()->currentSkin().colorForModel(SkinEnums::PaletteColors::FgError);
default:
return QVariant();