use direct enums in metadata.xml, allow for custom dynamcic colors in lists for selected items

This commit is contained in:
Martin Rotter 2021-11-19 08:31:09 +01:00
parent a286d67779
commit f1baf56dcf
13 changed files with 93 additions and 45 deletions

View File

@ -26,7 +26,7 @@
<url type="donation">https://github.com/sponsors/martinrotter</url> <url type="donation">https://github.com/sponsors/martinrotter</url>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="4.0.4" date="2021-11-18"/> <release version="4.0.4" date="2021-11-19"/>
</releases> </releases>
<content_rating type="oars-1.0"> <content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">none</content_attribute> <content_attribute id="violence-cartoon">none</content_attribute>

View File

@ -4,8 +4,10 @@
<name>Martin Rotter</name> <name>Martin Rotter</name>
</author> </author>
<palette> <palette>
<color key="1">#7ae2ff</color> <color key="FgInteresting">#3A4EE4</color>
<color key="2">#f08f84</color> <color key="FgSelectedInteresting">#ff66cc</color>
<color key="3">#77dd77</color> <color key="FgError">#4EE43A</color>
<color key="FgSelectedError">#ff99ff</color>
<color key="Allright">#00ff99</color>
</palette> </palette>
</skin> </skin>

View File

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8"?>
<skin version="0.01"> <skin version="0.01">
<author> <author>
<name>Maki Blackwell</name> <name>Maki Blackwell</name>
</author> </author>
<palette> <palette>
<color key="1">#3A4EE4</color> <color key="FgInteresting">#3A4EE4</color>
<color key="2">#E43A4E</color> <color key="FgSelectedInteresting">#ff66cc</color>
<color key="3">#4EE43A</color> <color key="FgError">#4EE43A</color>
<color key="FgSelectedError">#ff99ff</color>
<color key="Allright">#00ff99</color>
</palette> </palette>
</skin> </skin>

View File

@ -10,8 +10,10 @@
Specifically, they are taken from enumeration "PaletteColors". Specifically, they are taken from enumeration "PaletteColors".
--> -->
<color key="1">#00BFFF</color> <color key="FgInteresting">#3A4EE4</color>
<color key="2">#FF0000</color> <color key="FgSelectedInteresting">#ff66cc</color>
<color key="3">#32CD32</color> <color key="FgError">#4EE43A</color>
<color key="FgSelectedError">#ff99ff</color>
<color key="Allright">#00ff99</color>
</palette> </palette>
</skin> </skin>

View File

@ -4,8 +4,10 @@
<name>Martin Rotter</name> <name>Martin Rotter</name>
</author> </author>
<palette> <palette>
<color key="1">#4861f0</color> <color key="FgInteresting">#3A4EE4</color>
<color key="2">#d93636</color> <color key="FgSelectedInteresting">#ff66cc</color>
<color key="3">#77dd77</color> <color key="FgError">#4EE43A</color>
<color key="FgSelectedError">#ff99ff</color>
<color key="Allright">#00ff99</color>
</palette> </palette>
</skin> </skin>

View File

@ -39,11 +39,11 @@ QVariant MessagesForFiltersModel::data(const QModelIndex& index, int role) const
if (m_filteringDecisions.contains(index.row())) { if (m_filteringDecisions.contains(index.row())) {
switch (m_filteringDecisions.value(index.row())) { switch (m_filteringDecisions.value(index.row())) {
case MessageObject::FilteringAction::Accept: case MessageObject::FilteringAction::Accept:
return qApp->skins()->currentSkin().m_colorPalette[Skin::PaletteColors::Allright]; return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::Allright];
case MessageObject::FilteringAction::Ignore: case MessageObject::FilteringAction::Ignore:
case MessageObject::FilteringAction::Purge: case MessageObject::FilteringAction::Purge:
return qApp->skins()->currentSkin().m_colorPalette[Skin::PaletteColors::Error]; return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgError];
default: default:
break; break;

View File

@ -386,19 +386,28 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
} }
case Qt::ItemDataRole::ForegroundRole: case Qt::ItemDataRole::ForegroundRole:
case HIGHLIGHTED_FOREGROUND_TITLE_ROLE:
switch (m_messageHighlighter) { switch (m_messageHighlighter) {
case MessageHighlighter::HighlightImportant: { case MessageHighlighter::HighlightImportant: {
QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX); QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX);
QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important); 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[Skin::PaletteColors::Highlight] : QVariant(); return dta.toInt() == 1
? qApp->skins()->currentSkin().m_colorPalette[role == Qt::ItemDataRole::ForegroundRole
? SkinEnums::PaletteColors::FgInteresting
: SkinEnums::PaletteColors::FgSelectedInteresting]
: QVariant();
} }
case MessageHighlighter::HighlightUnread: { case MessageHighlighter::HighlightUnread: {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX); QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read); 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[Skin::PaletteColors::Highlight] : QVariant(); return dta.toInt() == 0
? qApp->skins()->currentSkin().m_colorPalette[role == Qt::ItemDataRole::ForegroundRole
? SkinEnums::PaletteColors::FgInteresting
: SkinEnums::PaletteColors::FgSelectedInteresting]
: QVariant();
} }
case MessageHighlighter::NoHighlighting: case MessageHighlighter::NoHighlighting:

View File

@ -46,6 +46,9 @@
#define MSG_SCORE_MAX 100.0 #define MSG_SCORE_MAX 100.0
#define MSG_SCORE_MIN 0.0 #define MSG_SCORE_MIN 0.0
#define LOWER_TITLE_ROLE 64
#define HIGHLIGHTED_FOREGROUND_TITLE_ROLE 128
#define SOUNDS_BUILTIN_DIRECTORY ":/sounds" #define SOUNDS_BUILTIN_DIRECTORY ":/sounds"
#define ARGUMENTS_LIST_SEPARATOR "\n" #define ARGUMENTS_LIST_SEPARATOR "\n"
#define IS_IN_ARRAY(offset, array) ((offset >= 0) && (offset < array.count())) #define IS_IN_ARRAY(offset, array) ((offset >= 0) && (offset < array.count()))
@ -57,7 +60,6 @@
#define SCRIPT_SOURCE_TYPE_REGEXP "^.+#.*$" #define SCRIPT_SOURCE_TYPE_REGEXP "^.+#.*$"
#define TEXT_TITLE_LIMIT 30 #define TEXT_TITLE_LIMIT 30
#define TEXT_TOOLTIP_LIMIT 50 #define TEXT_TOOLTIP_LIMIT 50
#define LOWER_TITLE_ROLE 64
#define RESELECT_MESSAGE_THRESSHOLD 500 #define RESELECT_MESSAGE_THRESSHOLD 500
#define ICON_SIZE_SETTINGS 16 #define ICON_SIZE_SETTINGS 16
#define TRAY_ICON_BUBBLE_TIMEOUT 20000 #define TRAY_ICON_BUBBLE_TIMEOUT 20000

View File

@ -169,7 +169,7 @@ QString MessageBrowser::prepareHtmlForMessage(const Message& message) {
"</style></head>" "</style></head>"
"<body>%1</body>" "<body>%1</body>"
"</html>").arg(html, "</html>").arg(html,
qApp->skins()->currentSkin().m_colorPalette[Skin::PaletteColors::Highlight].name()); qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgInteresting].name());
} }
bool MessageBrowser::eventFilter(QObject* watched, QEvent* event) { bool MessageBrowser::eventFilter(QObject* watched, QEvent* event) {

View File

@ -19,7 +19,7 @@ void StyledItemDelegateWithoutFocus::paint(QPainter* painter,
if ((item_option.state & QStyle::StateFlag::State_Selected) == QStyle::StateFlag::State_Selected && if ((item_option.state & QStyle::StateFlag::State_Selected) == QStyle::StateFlag::State_Selected &&
index.data(Qt::ItemDataRole::ForegroundRole).isValid()) { index.data(Qt::ItemDataRole::ForegroundRole).isValid()) {
item_option.palette.setColor(QPalette::ColorRole::HighlightedText, item_option.palette.setColor(QPalette::ColorRole::HighlightedText,
index.data(Qt::ItemDataRole::ForegroundRole).value<QColor>()); index.data(HIGHLIGHTED_FOREGROUND_TITLE_ROLE).value<QColor>());
} }
QStyledItemDelegate::paint(painter, item_option, index); QStyledItemDelegate::paint(painter, item_option, index);

View File

@ -8,6 +8,8 @@
#include <QDir> #include <QDir>
#include <QDomDocument> #include <QDomDocument>
#include <QDomElement> #include <QDomElement>
#include <QMetaEnum>
#include <QMetaObject>
#include <QStyleFactory> #include <QStyleFactory>
#include <QToolTip> #include <QToolTip>
@ -205,13 +207,15 @@ Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
skin.m_baseName = skin_name; skin.m_baseName = skin_name;
// Obtain color palette. // Obtain color palette.
QHash<Skin::PaletteColors, QColor> palette; QHash<SkinEnums::PaletteColors, QColor> palette;
QDomNodeList colors_of_palette = skin_node.namedItem(QSL("palette")).toElement().elementsByTagName(QSL("color")); QDomNodeList colors_of_palette = skin_node.namedItem(QSL("palette")).toElement().elementsByTagName(QSL("color"));
const QMetaObject& mo = SkinEnums::staticMetaObject;
QMetaEnum enumer = mo.enumerator(mo.indexOfEnumerator(QSL("PaletteColors").toLocal8Bit().constData()));
for (int i = 0; i < colors_of_palette.size(); i++) { for (int i = 0; i < colors_of_palette.size(); i++) {
QDomElement elem_clr = colors_of_palette.item(i).toElement(); QDomElement elem_clr = colors_of_palette.item(i).toElement();
QString en_val = elem_clr.attribute(QSL("key"));
Skin::PaletteColors key = Skin::PaletteColors(elem_clr.attribute(QSL("key")).toInt()); SkinEnums::PaletteColors key = SkinEnums::PaletteColors(enumer.keyToValue(en_val.toLatin1()));
QColor value = elem_clr.text(); QColor value = elem_clr.text();
if (value.isValid()) { if (value.isValid()) {
@ -310,6 +314,6 @@ QList<Skin> SkinFactory::installedSkins() const {
return skins; return skins;
} }
uint qHash(const Skin::PaletteColors& key) { uint qHash(const SkinEnums::PaletteColors& key) {
return uint(key); return uint(key);
} }

View File

@ -10,21 +10,31 @@
#include <QMetaType> #include <QMetaType>
#include <QStringList> #include <QStringList>
class SkinEnums : public QObject {
Q_OBJECT
public:
enum class PaletteColors {
// Paint foreground of some interesting items (feeds with new articles, etc.).
FgInteresting = 1,
// Paint foreground of some interesting items WHEN SELECTED (feeds with new articles, etc.).
FgSelectedInteresting = 2,
// Paint foreground of some errored items (feeds with error, etc.).
FgError = 4,
// Paint foreground of some errored items WHEN SELECTED (feeds with error, etc.).
FgSelectedError = 8,
// OK-ish color (background of list with test results of article filter).
Allright = 16
};
Q_ENUM(PaletteColors)
};
struct RSSGUARD_DLLSPEC Skin { struct RSSGUARD_DLLSPEC Skin {
enum class PaletteColors {
// Used to highlight foreground of some interesting articles.
Highlight = 1,
// Foreground color of errorneous entries.
Error = 2,
// OK-ish color.
Allright = 3,
// Foreground color when item is highlighted/selected.
HighlightedError = 4
};
QString m_baseName; QString m_baseName;
QString m_visibleName; QString m_visibleName;
QString m_author; QString m_author;
@ -35,10 +45,10 @@ struct RSSGUARD_DLLSPEC Skin {
QString m_enclosureImageMarkup; QString m_enclosureImageMarkup;
QString m_layoutMarkup; QString m_layoutMarkup;
QString m_enclosureMarkup; QString m_enclosureMarkup;
QHash<Skin::PaletteColors, QColor> m_colorPalette; QHash<SkinEnums::PaletteColors, QColor> m_colorPalette;
}; };
uint qHash(const Skin::PaletteColors& key); uint qHash(const SkinEnums::PaletteColors& key);
Q_DECLARE_METATYPE(Skin) Q_DECLARE_METATYPE(Skin)

View File

@ -53,16 +53,31 @@ QList<Message> Feed::undeletedMessages() const {
QVariant Feed::data(int column, int role) const { QVariant Feed::data(int column, int role) const {
switch (role) { switch (role) {
case Qt::ItemDataRole::ForegroundRole: case HIGHLIGHTED_FOREGROUND_TITLE_ROLE:
switch (status()) { switch (status()) {
case Status::NewMessages: case Status::NewMessages:
return qApp->skins()->currentSkin().m_colorPalette[Skin::PaletteColors::Highlight]; return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgSelectedInteresting];
case Status::NetworkError: case Status::NetworkError:
case Status::ParsingError: case Status::ParsingError:
case Status::AuthError: case Status::AuthError:
case Status::OtherError: case Status::OtherError:
return qApp->skins()->currentSkin().m_colorPalette[Skin::PaletteColors::Error]; return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgSelectedError];
default:
return QVariant();
}
case Qt::ItemDataRole::ForegroundRole:
switch (status()) {
case Status::NewMessages:
return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgInteresting];
case Status::NetworkError:
case Status::ParsingError:
case Status::AuthError:
case Status::OtherError:
return qApp->skins()->currentSkin().m_colorPalette[SkinEnums::PaletteColors::FgError];
default: default:
return QVariant(); return QVariant();