diff --git a/src/librssguard/core/messagesmodel.cpp b/src/librssguard/core/messagesmodel.cpp index 3ca8efe8f..bfb8b481b 100644 --- a/src/librssguard/core/messagesmodel.cpp +++ b/src/librssguard/core/messagesmodel.cpp @@ -18,11 +18,12 @@ MessagesModel::MessagesModel(QObject* parent) : QSqlQueryModel(parent), m_cache(new MessagesModelCache(this)), m_messageHighlighter(MessageHighlighter::NoHighlighting), - m_customDateFormat(QString()), m_selectedItem(nullptr), m_itemHeight(-1) { + m_customDateFormat(QString()), m_selectedItem(nullptr), m_itemHeight(-1), m_displayFeedIcons(false) { setupFonts(); setupIcons(); setupHeaderData(); updateDateFormat(); + updateFeedIconsDisplay(); loadMessages(nullptr); } @@ -156,6 +157,10 @@ void MessagesModel::updateDateFormat() { } } +void MessagesModel::updateFeedIconsDisplay() { + m_displayFeedIcons = qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayFeedIconsInList)).toBool(); +} + void MessagesModel::reloadWholeLayout() { emit layoutAboutToBeChanged(); emit layoutChanged(); @@ -261,7 +266,9 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { return author_name.isEmpty() ? QSL("-") : author_name; } - else if (index_column != MSG_DB_IMPORTANT_INDEX && index_column != MSG_DB_READ_INDEX && index_column != MSG_DB_HAS_ENCLOSURES) { + else if (index_column != MSG_DB_IMPORTANT_INDEX && + index_column != MSG_DB_READ_INDEX && + index_column != MSG_DB_HAS_ENCLOSURES) { return QSqlQueryModel::data(idx, role); } else { @@ -324,10 +331,22 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { const int index_column = idx.column(); if (index_column == 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); + if (m_displayFeedIcons && m_selectedItem != nullptr) { + QModelIndex idx_feedid = index(idx.row(), MSG_DB_FEED_CUSTOM_ID_INDEX); + QVariant dta = m_cache->containsData(idx_feedid.row()) + ? m_cache->data(idx_feedid) + : QSqlQueryModel::data(idx_feedid); + QString feed_custom_id = dta.toString(); + auto acc = m_selectedItem->getParentServiceRoot()->feedIconForMessage(feed_custom_id); - return dta.toInt() == 1 ? m_readIcon : m_unreadIcon; + return acc; + } + else { + 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); + + return dta.toInt() == 1 ? m_readIcon : m_unreadIcon; + } } else if (index_column == MSG_DB_IMPORTANT_INDEX) { QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX); diff --git a/src/librssguard/core/messagesmodel.h b/src/librssguard/core/messagesmodel.h index b7ef9149d..b886e373a 100644 --- a/src/librssguard/core/messagesmodel.h +++ b/src/librssguard/core/messagesmodel.h @@ -55,6 +55,7 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer { void setupFonts(); void updateDateFormat(); + void updateFeedIconsDisplay(); void reloadWholeLayout(); // SINGLE message manipulators. @@ -99,6 +100,7 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer { QIcon m_unreadIcon; QIcon m_enclosuresIcon; int m_itemHeight; + bool m_displayFeedIcons; }; Q_DECLARE_METATYPE(MessagesModel::MessageHighlighter) diff --git a/src/librssguard/gui/messagesview.cpp b/src/librssguard/gui/messagesview.cpp index 7f328c9ec..61f744d38 100644 --- a/src/librssguard/gui/messagesview.cpp +++ b/src/librssguard/gui/messagesview.cpp @@ -34,7 +34,7 @@ MessagesView::MessagesView(QWidget* parent) : QTreeView(parent), m_contextMenu(n createConnections(); setModel(m_proxyModel); setupAppearance(); - header()->setContextMenuPolicy(Qt::CustomContextMenu); + header()->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); connect(header(), &QHeaderView::customContextMenuRequested, this, [=](const QPoint& point) { TreeViewColumnsMenu mm(header()); mm.exec(header()->mapToGlobal(point)); diff --git a/src/librssguard/gui/settings/settingsfeedsmessages.cpp b/src/librssguard/gui/settings/settingsfeedsmessages.cpp index 8ef6e9ae9..75f105c49 100644 --- a/src/librssguard/gui/settings/settingsfeedsmessages.cpp +++ b/src/librssguard/gui/settings/settingsfeedsmessages.cpp @@ -40,6 +40,7 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdateOnlyUnfocused, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); + connect(m_ui->m_checkDisplayFeedIcons, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkMessagesDateTimeFormat, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkMessagesDateTimeFormat, &QCheckBox::toggled, m_ui->m_cmbMessagesDateTimeFormat, &QComboBox::setEnabled); @@ -125,6 +126,7 @@ void SettingsFeedsMessages::loadSettings() { m_ui->m_spinHeightRowsMessages->setValue(settings()->value(GROUP(GUI), SETTING(GUI::HeightRowMessages)).toInt()); m_ui->m_spinHeightRowsFeeds->setValue(settings()->value(GROUP(GUI), SETTING(GUI::HeightRowFeeds)).toInt()); + m_ui->m_checkDisplayFeedIcons->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::DisplayFeedIconsInList)).toBool()); m_ui->m_checkBringToForegroundAfterMsgOpened->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::BringAppToFrontAfterMessageOpenedExternally)).toBool()); m_ui->m_checkAutoUpdateNotification->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::EnableAutoUpdateNotification)).toBool()); @@ -183,6 +185,7 @@ void SettingsFeedsMessages::saveSettings() { settings()->setValue(GROUP(GUI), GUI::HeightRowMessages, m_ui->m_spinHeightRowsMessages->value()); settings()->setValue(GROUP(GUI), GUI::HeightRowFeeds, m_ui->m_spinHeightRowsFeeds->value()); + settings()->setValue(GROUP(Messages), Messages::DisplayFeedIconsInList, m_ui->m_checkDisplayFeedIcons->isChecked()); settings()->setValue(GROUP(Messages), Messages::BringAppToFrontAfterMessageOpenedExternally, m_ui->m_checkBringToForegroundAfterMsgOpened->isChecked()); settings()->setValue(GROUP(Feeds), Feeds::EnableAutoUpdateNotification, m_ui->m_checkAutoUpdateNotification->isChecked()); @@ -216,6 +219,7 @@ void SettingsFeedsMessages::saveSettings() { qApp->feedReader()->feedsModel()->reloadWholeLayout(); qApp->feedReader()->messagesModel()->updateDateFormat(); + qApp->feedReader()->messagesModel()->updateFeedIconsDisplay(); qApp->feedReader()->messagesModel()->reloadWholeLayout(); onEndSaveSettings(); diff --git a/src/librssguard/gui/settings/settingsfeedsmessages.ui b/src/librssguard/gui/settings/settingsfeedsmessages.ui index 0a7fa3427..112cc6f66 100644 --- a/src/librssguard/gui/settings/settingsfeedsmessages.ui +++ b/src/librssguard/gui/settings/settingsfeedsmessages.ui @@ -266,21 +266,21 @@ - + Bring application window to front once message is opened in external web browser - + Keep message selection in the middle of the message list viewport - + @@ -304,7 +304,7 @@ - + @@ -328,7 +328,7 @@ - + @@ -348,7 +348,7 @@ - + @@ -404,7 +404,7 @@ - + Qt::Vertical @@ -417,6 +417,13 @@ + + + + Display real icons of feeds in list of messages instead of read/unread icons + + + @@ -444,6 +451,7 @@ m_cmbCountsFeedList m_checkRemoveReadMessagesOnExit m_checkDisplayPlaceholders + m_checkDisplayFeedIcons m_checkBringToForegroundAfterMsgOpened m_checkKeppMessagesInTheMiddle m_spinHeightRowsMessages diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp index bc722bbc1..60d7c1fc7 100755 --- a/src/librssguard/miscellaneous/settings.cpp +++ b/src/librssguard/miscellaneous/settings.cpp @@ -91,6 +91,9 @@ DVALUE(char*) Messages::CustomDateFormatDef = ""; DKEY Messages::ClearReadOnExit = "clear_read_on_exit"; DVALUE(bool) Messages::ClearReadOnExitDef = false; +DKEY Messages::DisplayFeedIconsInList = "display_feed_icons_in_message_list"; +DVALUE(bool) Messages::DisplayFeedIconsInListDef = false; + DKEY Messages::BringAppToFrontAfterMessageOpenedExternally = "bring_app_to_front_after_msg_opened"; DVALUE(bool) Messages::BringAppToFrontAfterMessageOpenedExternallyDef = true; diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h index 0e9db8a8e..4227e1c74 100644 --- a/src/librssguard/miscellaneous/settings.h +++ b/src/librssguard/miscellaneous/settings.h @@ -112,6 +112,9 @@ namespace Messages { KEY ClearReadOnExit; VALUE(bool) ClearReadOnExitDef; + KEY DisplayFeedIconsInList; + VALUE(bool) DisplayFeedIconsInListDef; + KEY BringAppToFrontAfterMessageOpenedExternally; VALUE(bool) BringAppToFrontAfterMessageOpenedExternallyDef; diff --git a/src/librssguard/services/abstract/rootitem.cpp b/src/librssguard/services/abstract/rootitem.cpp index 35e1c18d8..93e2b48f3 100644 --- a/src/librssguard/services/abstract/rootitem.cpp +++ b/src/librssguard/services/abstract/rootitem.cpp @@ -303,6 +303,27 @@ QList RootItem::getSubTreeCategories() const { return children; } +RootItem* RootItem::getItemFromSubTree(std::function tester) const { + QList children; + QList traversable_items; + + traversable_items.append(const_cast(this)); + + // Iterate all nested items. + while (!traversable_items.isEmpty()) { + RootItem* active_item = traversable_items.takeFirst(); + + if (tester(active_item)) { + return active_item; + } + + children.append(active_item); + traversable_items.append(active_item->childItems()); + } + + return nullptr; +} + QHash RootItem::getHashedSubTreeCategories() const { QHash children; QList traversable_items; diff --git a/src/librssguard/services/abstract/rootitem.h b/src/librssguard/services/abstract/rootitem.h index c999f5395..6dcda96df 100644 --- a/src/librssguard/services/abstract/rootitem.h +++ b/src/librssguard/services/abstract/rootitem.h @@ -134,6 +134,8 @@ class RSSGUARD_DLLSPEC RootItem : public QObject { QList getSubTree(RootItem::Kind kind_of_item) const; QList getSubTreeCategories() const; + RootItem* getItemFromSubTree(std::function tester) const; + // Returns list of categories complemented by their own integer primary ID. QHash getHashedSubTreeCategories() const; diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 894a83c3f..dbacf4bbb 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -166,6 +166,20 @@ void ServiceRoot::completelyRemoveAllData() { requestReloadMessageList(true); } +QIcon ServiceRoot::feedIconForMessage(const QString& feed_custom_id) const { + QString low_id = feed_custom_id.toLower(); + RootItem* found_item = getItemFromSubTree([low_id](const RootItem* it) { + return it->kind() == RootItem::Kind::Feed && it->customId().toLower() == low_id; + }); + + if (found_item != nullptr) { + return found_item->icon(); + } + else { + return QIcon(); + } +} + void ServiceRoot::removeOldAccountFromDatabase(bool including_messages) { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index 5de0b8fca..706f9300c 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -167,6 +167,8 @@ class ServiceRoot : public RootItem { // and from model. void completelyRemoveAllData(); + QIcon feedIconForMessage(const QString& feed_custom_id) const; + // Removes all/read only messages from given underlying feeds. bool cleanFeeds(QList items, bool clean_read_only);