qBittorrent
FeedListWidget Class Referencefinal

#include <feedlistwidget.h>

Inheritance diagram for FeedListWidget:
Collaboration diagram for FeedListWidget:

Public Member Functions

 FeedListWidget (QWidget *parent)
 
QTreeWidgetItem * stickyUnreadItem () const
 
QList< QTreeWidgetItem * > getAllOpenedFolders (QTreeWidgetItem *parent=nullptr) const
 
RSS::ItemgetRSSItem (QTreeWidgetItem *item) const
 
QTreeWidgetItem * mapRSSItem (RSS::Item *rssItem) const
 
QString itemPath (QTreeWidgetItem *item) const
 
bool isFeed (QTreeWidgetItem *item) const
 
bool isFolder (QTreeWidgetItem *item) const
 

Private Slots

void handleItemAdded (RSS::Item *rssItem)
 
void handleFeedStateChanged (RSS::Feed *feed)
 
void handleFeedIconLoaded (RSS::Feed *feed)
 
void handleItemUnreadCountChanged (RSS::Item *rssItem)
 
void handleItemPathChanged (RSS::Item *rssItem)
 
void handleItemAboutToBeRemoved (RSS::Item *rssItem)
 

Private Member Functions

void dragMoveEvent (QDragMoveEvent *event) override
 
void dropEvent (QDropEvent *event) override
 
QTreeWidgetItem * createItem (RSS::Item *rssItem, QTreeWidgetItem *parentItem=nullptr)
 
void fill (QTreeWidgetItem *parent, RSS::Folder *rssParent)
 

Private Attributes

QHash< RSS::Item *, QTreeWidgetItem * > m_rssToTreeItemMapping
 
QTreeWidgetItem * m_unreadStickyItem
 

Detailed Description

Definition at line 43 of file feedlistwidget.h.

Constructor & Destructor Documentation

◆ FeedListWidget()

FeedListWidget::FeedListWidget ( QWidget *  parent)
explicit

Definition at line 90 of file feedlistwidget.cpp.

91  : QTreeWidget(parent)
92 {
93  setContextMenuPolicy(Qt::CustomContextMenu);
94  setDragDropMode(QAbstractItemView::InternalMove);
95  setSelectionMode(QAbstractItemView::ExtendedSelection);
96  setColumnCount(1);
97  headerItem()->setText(0, tr("RSS feeds"));
98 
104 
105  m_rssToTreeItemMapping[RSS::Session::instance()->rootFolder()] = invisibleRootItem();
106 
107  m_unreadStickyItem = new FeedListItem(this);
108  m_unreadStickyItem->setData(0, Qt::UserRole, reinterpret_cast<quintptr>(RSS::Session::instance()->rootFolder()));
109  m_unreadStickyItem->setText(0, tr("Unread (%1)").arg(RSS::Session::instance()->rootFolder()->unreadCount()));
110  m_unreadStickyItem->setData(0, Qt::DecorationRole, UIThemeManager::instance()->getIcon("mail-folder-inbox"));
111  m_unreadStickyItem->setData(0, StickyItemTagRole, true);
112 
113 
115 
116  setSortingEnabled(false);
117  fill(nullptr, RSS::Session::instance()->rootFolder());
118  setSortingEnabled(true);
119 
120 // setCurrentItem(m_unreadStickyItem);
121 }
void handleItemUnreadCountChanged(RSS::Item *rssItem)
QHash< RSS::Item *, QTreeWidgetItem * > m_rssToTreeItemMapping
void handleFeedIconLoaded(RSS::Feed *feed)
void handleItemPathChanged(RSS::Item *rssItem)
QTreeWidgetItem * m_unreadStickyItem
void handleFeedStateChanged(RSS::Feed *feed)
void handleItemAdded(RSS::Item *rssItem)
void handleItemAboutToBeRemoved(RSS::Item *rssItem)
void fill(QTreeWidgetItem *parent, RSS::Folder *rssParent)
void unreadCountChanged(Item *item=nullptr)
static Session * instance()
void itemPathChanged(Item *item)
Folder * rootFolder() const
void feedStateChanged(Feed *feed)
void itemAdded(Item *item)
void feedIconLoaded(Feed *feed)
void itemAboutToBeRemoved(Item *item)
static UIThemeManager * instance()

References RSS::Session::feedIconLoaded(), RSS::Session::feedStateChanged(), fill(), handleFeedIconLoaded(), handleFeedStateChanged(), handleItemAboutToBeRemoved(), handleItemAdded(), handleItemPathChanged(), handleItemUnreadCountChanged(), RSS::Session::instance(), UIThemeManager::instance(), RSS::Session::itemAboutToBeRemoved(), RSS::Session::itemAdded(), RSS::Session::itemPathChanged(), m_rssToTreeItemMapping, m_unreadStickyItem, RSS::Session::rootFolder(), anonymous_namespace{feedlistwidget.cpp}::StickyItemTagRole, and RSS::Item::unreadCountChanged().

Here is the call graph for this function:

Member Function Documentation

◆ createItem()

QTreeWidgetItem * FeedListWidget::createItem ( RSS::Item rssItem,
QTreeWidgetItem *  parentItem = nullptr 
)
private

Definition at line 274 of file feedlistwidget.cpp.

275 {
276  auto *item = new FeedListItem;
277  item->setData(0, Qt::DisplayRole, QString::fromLatin1("%1 (%2)").arg(rssItem->name(), QString::number(rssItem->unreadCount())));
278  item->setData(0, Qt::UserRole, reinterpret_cast<quintptr>(rssItem));
279  m_rssToTreeItemMapping[rssItem] = item;
280 
281  QIcon icon;
282  if (auto feed = qobject_cast<RSS::Feed *>(rssItem))
283  icon = rssFeedIcon(feed);
284  else
285  icon = UIThemeManager::instance()->getIcon(QLatin1String("inode-directory"));
286  item->setData(0, Qt::DecorationRole, icon);
287 
289 
290  if (!parentItem || (parentItem == m_unreadStickyItem))
291  addTopLevelItem(item);
292  else
293  parentItem->addChild(item);
294 
295  return item;
296 }
QString name() const
Definition: rss_item.cpp:62
virtual int unreadCount() const =0
QIcon getIcon(const QString &iconId, const QString &fallback={}) const
QIcon rssFeedIcon(const RSS::Feed *feed)

References UIThemeManager::getIcon(), handleItemUnreadCountChanged(), UIThemeManager::instance(), m_rssToTreeItemMapping, m_unreadStickyItem, RSS::Item::name(), anonymous_namespace{feedlistwidget.cpp}::rssFeedIcon(), RSS::Item::unreadCount(), and RSS::Item::unreadCountChanged().

Referenced by fill(), and handleItemAdded().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dragMoveEvent()

void FeedListWidget::dragMoveEvent ( QDragMoveEvent *  event)
overrideprivate

Definition at line 239 of file feedlistwidget.cpp.

240 {
241  QTreeWidget::dragMoveEvent(event);
242 
243  QTreeWidgetItem *item = itemAt(event->pos());
244  // Prohibit dropping onto global unread counter
245  if (item == m_unreadStickyItem)
246  event->ignore();
247  // Prohibit dragging of global unread counter
248  else if (selectedItems().contains(m_unreadStickyItem))
249  event->ignore();
250  // Prohibit dropping onto feeds
251  else if (item && isFeed(item))
252  event->ignore();
253 }
bool isFeed(QTreeWidgetItem *item) const

References isFeed(), and m_unreadStickyItem.

Here is the call graph for this function:

◆ dropEvent()

void FeedListWidget::dropEvent ( QDropEvent *  event)
overrideprivate

Definition at line 255 of file feedlistwidget.cpp.

256 {
257  QTreeWidgetItem *destFolderItem = itemAt(event->pos());
258  RSS::Folder *destFolder = (destFolderItem
259  ? static_cast<RSS::Folder *>(getRSSItem(destFolderItem))
261 
262  // move as much items as possible
263  for (QTreeWidgetItem *srcItem : asConst(selectedItems()))
264  {
265  auto rssItem = getRSSItem(srcItem);
266  RSS::Session::instance()->moveItem(rssItem, RSS::Item::joinPath(destFolder->path(), rssItem->name()));
267  }
268 
269  QTreeWidget::dropEvent(event);
270  if (destFolderItem)
271  destFolderItem->setExpanded(true);
272 }
RSS::Item * getRSSItem(QTreeWidgetItem *item) const
static QString joinPath(const QString &path1, const QString &path2)
Definition: rss_item.cpp:82
QString path() const
Definition: rss_item.cpp:57
nonstd::expected< void, QString > moveItem(const QString &itemPath, const QString &destPath)
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42

References asConst(), getRSSItem(), RSS::Session::instance(), RSS::Item::joinPath(), RSS::Session::moveItem(), RSS::Item::path(), and RSS::Session::rootFolder().

Here is the call graph for this function:

◆ fill()

void FeedListWidget::fill ( QTreeWidgetItem *  parent,
RSS::Folder rssParent 
)
private

Definition at line 298 of file feedlistwidget.cpp.

299 {
300  for (const auto rssItem : asConst(rssParent->items()))
301  {
302  QTreeWidgetItem *item = createItem(rssItem, parent);
303  // Recursive call if this is a folder.
304  if (auto folder = qobject_cast<RSS::Folder *>(rssItem))
305  fill(item, folder);
306  }
307 }
QTreeWidgetItem * createItem(RSS::Item *rssItem, QTreeWidgetItem *parentItem=nullptr)
QList< Item * > items() const
Definition: rss_folder.cpp:94

References asConst(), createItem(), and RSS::Folder::items().

Referenced by FeedListWidget().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getAllOpenedFolders()

QList< QTreeWidgetItem * > FeedListWidget::getAllOpenedFolders ( QTreeWidgetItem *  parent = nullptr) const

Definition at line 193 of file feedlistwidget.cpp.

194 {
195  QList<QTreeWidgetItem *> openedFolders;
196  int nbChildren = (parent ? parent->childCount() : topLevelItemCount());
197  for (int i = 0; i < nbChildren; ++i)
198  {
199  QTreeWidgetItem *item (parent ? parent->child(i) : topLevelItem(i));
200  if (isFolder(item) && item->isExpanded())
201  {
202  QList<QTreeWidgetItem *> openedSubfolders = getAllOpenedFolders(item);
203  if (!openedSubfolders.empty())
204  openedFolders << openedSubfolders;
205  else
206  openedFolders << item;
207  }
208  }
209  return openedFolders;
210 }
bool isFolder(QTreeWidgetItem *item) const
QList< QTreeWidgetItem * > getAllOpenedFolders(QTreeWidgetItem *parent=nullptr) const

References isFolder().

Referenced by RSSWidget::saveFoldersOpenState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getRSSItem()

RSS::Item * FeedListWidget::getRSSItem ( QTreeWidgetItem *  item) const

Definition at line 212 of file feedlistwidget.cpp.

213 {
214  if (!item) return nullptr;
215 
216  return reinterpret_cast<RSS::Item *>(item->data(0, Qt::UserRole).value<quintptr>());
217 }

Referenced by RSSWidget::askNewFolder(), RSSWidget::copySelectedFeedsURL(), dropEvent(), RSSWidget::handleCurrentFeedItemChanged(), isFeed(), isFolder(), itemPath(), RSSWidget::loadFoldersOpenState(), RSSWidget::on_markReadButton_clicked(), RSSWidget::on_newFeedButton_clicked(), RSSWidget::refreshSelectedItems(), and RSSWidget::renameSelectedRSSItem().

Here is the caller graph for this function:

◆ handleFeedIconLoaded

void FeedListWidget::handleFeedIconLoaded ( RSS::Feed feed)
privateslot

Definition at line 138 of file feedlistwidget.cpp.

139 {
140  if (!feed->isLoading() && !feed->hasError())
141  {
142  QTreeWidgetItem *item = m_rssToTreeItemMapping.value(feed);
143  Q_ASSERT(item);
144 
145  item->setData(0, Qt::DecorationRole, rssFeedIcon(feed));
146  }
147 }
bool isLoading() const
Definition: rss_feed.cpp:164
bool hasError() const
Definition: rss_feed.cpp:199

References RSS::Feed::hasError(), RSS::Feed::isLoading(), m_rssToTreeItemMapping, and anonymous_namespace{feedlistwidget.cpp}::rssFeedIcon().

Referenced by FeedListWidget().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleFeedStateChanged

void FeedListWidget::handleFeedStateChanged ( RSS::Feed feed)
privateslot

Definition at line 130 of file feedlistwidget.cpp.

131 {
132  QTreeWidgetItem *item = m_rssToTreeItemMapping.value(feed);
133  Q_ASSERT(item);
134 
135  item->setData(0, Qt::DecorationRole, rssFeedIcon(feed));
136 }

References m_rssToTreeItemMapping, and anonymous_namespace{feedlistwidget.cpp}::rssFeedIcon().

Referenced by FeedListWidget().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleItemAboutToBeRemoved

void FeedListWidget::handleItemAboutToBeRemoved ( RSS::Item rssItem)
privateslot

Definition at line 177 of file feedlistwidget.cpp.

178 {
179  rssItem->disconnect(this);
180  delete m_rssToTreeItemMapping.take(rssItem);
181 
182  // RSS Item is still valid in this slot so if it is the last
183  // item we should prevent Unread list populating
184  if (m_rssToTreeItemMapping.size() == 1)
185  setCurrentItem(nullptr);
186 }

References m_rssToTreeItemMapping.

Referenced by FeedListWidget().

Here is the caller graph for this function:

◆ handleItemAdded

void FeedListWidget::handleItemAdded ( RSS::Item rssItem)
privateslot

Definition at line 123 of file feedlistwidget.cpp.

124 {
125  auto parentItem = m_rssToTreeItemMapping.value(
126  RSS::Session::instance()->itemByPath(RSS::Item::parentPath(rssItem->path())));
127  createItem(rssItem, parentItem);
128 }
static QString parentPath(const QString &path)
Definition: rss_item.cpp:108

References createItem(), RSS::Session::instance(), m_rssToTreeItemMapping, RSS::Item::parentPath(), and RSS::Item::path().

Referenced by FeedListWidget().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleItemPathChanged

void FeedListWidget::handleItemPathChanged ( RSS::Item rssItem)
privateslot

Definition at line 163 of file feedlistwidget.cpp.

164 {
165  QTreeWidgetItem *item = mapRSSItem(rssItem);
166  Q_ASSERT(item);
167 
168  item->setData(0, Qt::DisplayRole, QString::fromLatin1("%1 (%2)").arg(rssItem->name(), QString::number(rssItem->unreadCount())));
169 
170  RSS::Item *parentRssItem = RSS::Session::instance()->itemByPath(RSS::Item::parentPath(rssItem->path()));
171  QTreeWidgetItem *parentItem = mapRSSItem(parentRssItem);
172  Q_ASSERT(parentItem);
173 
174  parentItem->addChild(item);
175 }
QTreeWidgetItem * mapRSSItem(RSS::Item *rssItem) const
Item * itemByPath(const QString &path) const

References RSS::Session::instance(), RSS::Session::itemByPath(), mapRSSItem(), RSS::Item::name(), RSS::Item::parentPath(), RSS::Item::path(), and RSS::Item::unreadCount().

Referenced by FeedListWidget().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleItemUnreadCountChanged

void FeedListWidget::handleItemUnreadCountChanged ( RSS::Item rssItem)
privateslot

Definition at line 149 of file feedlistwidget.cpp.

150 {
151  if (rssItem == RSS::Session::instance()->rootFolder())
152  {
153  m_unreadStickyItem->setText(0, tr("Unread (%1)").arg(RSS::Session::instance()->rootFolder()->unreadCount()));
154  }
155  else
156  {
157  QTreeWidgetItem *item = mapRSSItem(rssItem);
158  Q_ASSERT(item);
159  item->setData(0, Qt::DisplayRole, QString::fromLatin1("%1 (%2)").arg(rssItem->name(), QString::number(rssItem->unreadCount())));
160  }
161 }

References RSS::Session::instance(), m_unreadStickyItem, mapRSSItem(), RSS::Item::name(), and RSS::Item::unreadCount().

Referenced by createItem(), and FeedListWidget().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isFeed()

bool FeedListWidget::isFeed ( QTreeWidgetItem *  item) const

Definition at line 229 of file feedlistwidget.cpp.

230 {
231  return qobject_cast<RSS::Feed *>(getRSSItem(item));
232 }

References getRSSItem().

Referenced by RSSWidget::displayRSSListMenu(), and dragMoveEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isFolder()

bool FeedListWidget::isFolder ( QTreeWidgetItem *  item) const

Definition at line 234 of file feedlistwidget.cpp.

235 {
236  return qobject_cast<RSS::Folder *>(getRSSItem(item));
237 }

References getRSSItem().

Referenced by RSSWidget::askNewFolder(), RSSWidget::displayRSSListMenu(), getAllOpenedFolders(), and RSSWidget::on_newFeedButton_clicked().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ itemPath()

QString FeedListWidget::itemPath ( QTreeWidgetItem *  item) const

Definition at line 224 of file feedlistwidget.cpp.

225 {
226  return getRSSItem(item)->path();
227 }

References getRSSItem(), and RSS::Item::path().

Referenced by RSSWidget::deleteSelectedItems(), and RSSWidget::saveFoldersOpenState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mapRSSItem()

QTreeWidgetItem * FeedListWidget::mapRSSItem ( RSS::Item rssItem) const

Definition at line 219 of file feedlistwidget.cpp.

220 {
221  return m_rssToTreeItemMapping.value(rssItem);
222 }

References m_rssToTreeItemMapping.

Referenced by RSSWidget::askNewFolder(), handleItemPathChanged(), handleItemUnreadCountChanged(), and RSSWidget::on_newFeedButton_clicked().

Here is the caller graph for this function:

◆ stickyUnreadItem()

Member Data Documentation

◆ m_rssToTreeItemMapping

QHash<RSS::Item *, QTreeWidgetItem *> FeedListWidget::m_rssToTreeItemMapping
private

◆ m_unreadStickyItem

QTreeWidgetItem* FeedListWidget::m_unreadStickyItem
private

The documentation for this class was generated from the following files: