diff --git a/src/gui/rss/articlelistwidget.cpp b/src/gui/rss/articlelistwidget.cpp index f102f322a..bce26f1b4 100644 --- a/src/gui/rss/articlelistwidget.cpp +++ b/src/gui/rss/articlelistwidget.cpp @@ -38,6 +38,8 @@ ArticleListWidget::ArticleListWidget(QWidget *parent) { setContextMenuPolicy(Qt::CustomContextMenu); setSelectionMode(QAbstractItemView::ExtendedSelection); + + checkInvariant(); } RSS::Article *ArticleListWidget::getRSSArticle(QListWidgetItem *item) const @@ -55,28 +57,38 @@ void ArticleListWidget::setRSSItem(RSS::Item *rssItem, bool unreadOnly) { // Clear the list first clear(); + m_rssArticleToListItemMapping.clear(); if (m_rssItem) m_rssItem->disconnect(this); m_unreadOnly = unreadOnly; m_rssItem = rssItem; - if (!m_rssItem) return; + if (m_rssItem) { + connect(m_rssItem, &RSS::Item::newArticle, this, &ArticleListWidget::handleArticleAdded); + connect(m_rssItem, &RSS::Item::articleRead, this, &ArticleListWidget::handleArticleRead); + connect(m_rssItem, &RSS::Item::articleAboutToBeRemoved, this, &ArticleListWidget::handleArticleAboutToBeRemoved); - m_rssItem = rssItem; - connect(m_rssItem, &RSS::Item::newArticle, this, &ArticleListWidget::handleArticleAdded); - connect(m_rssItem, &RSS::Item::articleRead, this, &ArticleListWidget::handleArticleRead); - connect(m_rssItem, &RSS::Item::articleAboutToBeRemoved, this, &ArticleListWidget::handleArticleAboutToBeRemoved); - - foreach (auto article, rssItem->articles()) { - if (!(m_unreadOnly && article->isRead())) - addItem(createItem(article)); + foreach (auto article, rssItem->articles()) { + if (!(m_unreadOnly && article->isRead())) { + auto item = createItem(article); + addItem(item); + m_rssArticleToListItemMapping.insert(article, item); + } + } } + + checkInvariant(); } void ArticleListWidget::handleArticleAdded(RSS::Article *rssArticle) { - if (!(m_unreadOnly && rssArticle->isRead())) - addItem(createItem(rssArticle)); + if (!(m_unreadOnly && rssArticle->isRead())) { + auto item = createItem(rssArticle); + insertItem(0, item); + m_rssArticleToListItemMapping.insert(rssArticle, item); + } + + checkInvariant(); } void ArticleListWidget::handleArticleRead(RSS::Article *rssArticle) @@ -89,14 +101,22 @@ void ArticleListWidget::handleArticleRead(RSS::Article *rssArticle) item->setData(Qt::ForegroundRole, QColor("grey")); item->setData(Qt::DecorationRole, QIcon(":/icons/sphere.png")); } + + checkInvariant(); } void ArticleListWidget::handleArticleAboutToBeRemoved(RSS::Article *rssArticle) { delete m_rssArticleToListItemMapping.take(rssArticle); + checkInvariant(); } -QListWidgetItem *ArticleListWidget::createItem(RSS::Article *article) +void ArticleListWidget::checkInvariant() const +{ + Q_ASSERT(count() == m_rssArticleToListItemMapping.count()); +} + +QListWidgetItem *ArticleListWidget::createItem(RSS::Article *article) const { Q_ASSERT(article); QListWidgetItem *item = new QListWidgetItem; @@ -112,6 +132,5 @@ QListWidgetItem *ArticleListWidget::createItem(RSS::Article *article) item->setData(Qt::DecorationRole, QIcon(":/icons/sphere2.png")); } - m_rssArticleToListItemMapping.insert(article, item); return item; } diff --git a/src/gui/rss/articlelistwidget.h b/src/gui/rss/articlelistwidget.h index dec2fb90f..6c35892b0 100644 --- a/src/gui/rss/articlelistwidget.h +++ b/src/gui/rss/articlelistwidget.h @@ -56,7 +56,8 @@ private slots: void handleArticleAboutToBeRemoved(RSS::Article *rssArticle); private: - QListWidgetItem *createItem(RSS::Article *article); + void checkInvariant() const; + QListWidgetItem *createItem(RSS::Article *article) const; RSS::Item *m_rssItem = nullptr; bool m_unreadOnly = false; diff --git a/src/gui/rss/rsswidget.cpp b/src/gui/rss/rsswidget.cpp index 6ffdb33fd..05fab9438 100644 --- a/src/gui/rss/rsswidget.cpp +++ b/src/gui/rss/rsswidget.cpp @@ -224,7 +224,7 @@ void RSSWidget::askNewFolder() destItem = destItem->parent(); } // Consider the case where the user clicked on Unread item - RSS::Folder *rssDestFolder = ((destItem == m_feedListWidget->stickyUnreadItem()) + RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem())) ? RSS::Session::instance()->rootFolder() : qobject_cast(m_feedListWidget->getRSSItem(destItem))); @@ -234,7 +234,7 @@ void RSSWidget::askNewFolder() QMessageBox::warning(this, "qBittorrent", error, QMessageBox::Ok); // Expand destination folder to display new feed - if (destItem != m_feedListWidget->stickyUnreadItem()) + if (destItem && (destItem != m_feedListWidget->stickyUnreadItem())) destItem->setExpanded(true); // As new RSS items are added synchronously, we can do the following here. m_feedListWidget->setCurrentItem(m_feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFolderPath)));