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 @@
toolbareditor.h
1
+ + HelpSpoiler + QWidget +
helpspoiler.h
+ 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();