qBittorrent
RSSWidget Class Reference

#include <rsswidget.h>

Inheritance diagram for RSSWidget:
Collaboration diagram for RSSWidget:

Public Slots

void deleteSelectedItems ()
 
void updateRefreshInterval (int val) const
 

Signals

void unreadCountUpdated (int count)
 

Public Member Functions

 RSSWidget (QWidget *parent)
 
 ~RSSWidget ()
 

Private Slots

void on_newFeedButton_clicked ()
 
void refreshAllFeeds ()
 
void on_markReadButton_clicked ()
 
void displayRSSListMenu (const QPoint &)
 
void displayItemsListMenu (const QPoint &)
 
void renameSelectedRSSItem ()
 
void refreshSelectedItems ()
 
void copySelectedFeedsURL ()
 
void handleCurrentFeedItemChanged (QTreeWidgetItem *currentItem)
 
void handleCurrentArticleItemChanged (QListWidgetItem *currentItem, QListWidgetItem *previousItem)
 
void openSelectedArticlesUrls ()
 
void downloadSelectedTorrents ()
 
void saveSlidersPosition ()
 
void restoreSlidersPosition ()
 
void askNewFolder ()
 
void saveFoldersOpenState ()
 
void loadFoldersOpenState ()
 
void on_rssDownloaderBtn_clicked ()
 
void handleSessionProcessingStateChanged (bool enabled)
 
void handleUnreadCountChanged ()
 

Private Attributes

Ui::RSSWidget * m_ui
 
ArticleListWidgetm_articleListWidget
 
FeedListWidgetm_feedListWidget
 

Detailed Description

Definition at line 46 of file rsswidget.h.

Constructor & Destructor Documentation

◆ RSSWidget()

RSSWidget::RSSWidget ( QWidget *  parent)

Definition at line 58 of file rsswidget.cpp.

59  : QWidget(parent)
60  , m_ui(new Ui::RSSWidget)
61 {
62  m_ui->setupUi(this);
63 
64  // Icons
65  m_ui->actionCopyFeedURL->setIcon(UIThemeManager::instance()->getIcon("edit-copy"));
66  m_ui->actionDelete->setIcon(UIThemeManager::instance()->getIcon("edit-delete"));
67  m_ui->actionDownloadTorrent->setIcon(UIThemeManager::instance()->getIcon("download"));
68  m_ui->actionMarkItemsRead->setIcon(UIThemeManager::instance()->getIcon("mail-mark-read"));
69  m_ui->actionNewFolder->setIcon(UIThemeManager::instance()->getIcon("folder-new"));
70  m_ui->actionNewSubscription->setIcon(UIThemeManager::instance()->getIcon("list-add"));
71  m_ui->actionOpenNewsURL->setIcon(UIThemeManager::instance()->getIcon("application-x-mswinurl"));
72  m_ui->actionRename->setIcon(UIThemeManager::instance()->getIcon("edit-rename"));
73  m_ui->actionUpdate->setIcon(UIThemeManager::instance()->getIcon("view-refresh"));
74  m_ui->actionUpdateAllFeeds->setIcon(UIThemeManager::instance()->getIcon("view-refresh"));
75 #ifndef Q_OS_MACOS
76  m_ui->newFeedButton->setIcon(UIThemeManager::instance()->getIcon("list-add"));
77  m_ui->markReadButton->setIcon(UIThemeManager::instance()->getIcon("mail-mark-read"));
78  m_ui->updateAllButton->setIcon(UIThemeManager::instance()->getIcon("view-refresh"));
79  m_ui->rssDownloaderBtn->setIcon(UIThemeManager::instance()->getIcon("download"));
80 #endif
81 
82  m_articleListWidget = new ArticleListWidget(m_ui->splitterMain);
83  m_ui->splitterMain->insertWidget(0, m_articleListWidget);
84  connect(m_articleListWidget, &ArticleListWidget::customContextMenuRequested, this, &RSSWidget::displayItemsListMenu);
85  connect(m_articleListWidget, &ArticleListWidget::currentItemChanged, this, &RSSWidget::handleCurrentArticleItemChanged);
86  connect(m_articleListWidget, &ArticleListWidget::itemDoubleClicked, this, &RSSWidget::downloadSelectedTorrents);
87 
88  m_feedListWidget = new FeedListWidget(m_ui->splitterSide);
89  m_ui->splitterSide->insertWidget(0, m_feedListWidget);
90  connect(m_feedListWidget, &QAbstractItemView::doubleClicked, this, &RSSWidget::renameSelectedRSSItem);
91  connect(m_feedListWidget, &QTreeWidget::currentItemChanged, this, &RSSWidget::handleCurrentFeedItemChanged);
92  connect(m_feedListWidget, &QWidget::customContextMenuRequested, this, &RSSWidget::displayRSSListMenu);
95 
96  const auto *editHotkey = new QShortcut(Qt::Key_F2, m_feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
97  connect(editHotkey, &QShortcut::activated, this, &RSSWidget::renameSelectedRSSItem);
98  const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
99  connect(deleteHotkey, &QShortcut::activated, this, &RSSWidget::deleteSelectedItems);
100 
101  // Feeds list actions
102  connect(m_ui->actionDelete, &QAction::triggered, this, &RSSWidget::deleteSelectedItems);
103  connect(m_ui->actionRename, &QAction::triggered, this, &RSSWidget::renameSelectedRSSItem);
104  connect(m_ui->actionUpdate, &QAction::triggered, this, &RSSWidget::refreshSelectedItems);
105  connect(m_ui->actionNewFolder, &QAction::triggered, this, &RSSWidget::askNewFolder);
106  connect(m_ui->actionNewSubscription, &QAction::triggered, this, &RSSWidget::on_newFeedButton_clicked);
107  connect(m_ui->actionUpdateAllFeeds, &QAction::triggered, this, &RSSWidget::refreshAllFeeds);
108  connect(m_ui->updateAllButton, &QAbstractButton::clicked, this, &RSSWidget::refreshAllFeeds);
109  connect(m_ui->actionCopyFeedURL, &QAction::triggered, this, &RSSWidget::copySelectedFeedsURL);
110  connect(m_ui->actionMarkItemsRead, &QAction::triggered, this, &RSSWidget::on_markReadButton_clicked);
111 
112  // News list actions
113  connect(m_ui->actionOpenNewsURL, &QAction::triggered, this, &RSSWidget::openSelectedArticlesUrls);
114  connect(m_ui->actionDownloadTorrent, &QAction::triggered, this, &RSSWidget::downloadSelectedTorrents);
115 
116  // Restore sliders position
118  // Bind saveSliders slots
119  connect(m_ui->splitterMain, &QSplitter::splitterMoved, this, &RSSWidget::saveSlidersPosition);
120  connect(m_ui->splitterSide, &QSplitter::splitterMoved, this, &RSSWidget::saveSlidersPosition);
121 
122  if (RSS::Session::instance()->isProcessingEnabled())
123  m_ui->labelWarn->hide();
128 }
QTreeWidgetItem * stickyUnreadItem() const
void unreadCountChanged(Item *item=nullptr)
static Session * instance()
void processingStateChanged(bool enabled)
void refreshAllFeeds()
Definition: rsswidget.cpp:353
FeedListWidget * m_feedListWidget
Definition: rsswidget.h:86
void displayRSSListMenu(const QPoint &)
Definition: rsswidget.cpp:143
void on_newFeedButton_clicked()
Definition: rsswidget.cpp:262
ArticleListWidget * m_articleListWidget
Definition: rsswidget.h:85
void saveSlidersPosition()
Definition: rsswidget.cpp:530
void askNewFolder()
Definition: rsswidget.cpp:224
void handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QListWidgetItem *previousItem)
Definition: rsswidget.cpp:465
void copySelectedFeedsURL()
Definition: rsswidget.cpp:437
void openSelectedArticlesUrls()
Definition: rsswidget.cpp:379
void displayItemsListMenu(const QPoint &)
Definition: rsswidget.cpp:195
void refreshSelectedItems()
Definition: rsswidget.cpp:423
void handleCurrentFeedItemChanged(QTreeWidgetItem *currentItem)
Definition: rsswidget.cpp:448
void on_markReadButton_clicked()
Definition: rsswidget.cpp:454
void handleUnreadCountChanged()
Definition: rsswidget.cpp:566
void renameSelectedRSSItem()
Definition: rsswidget.cpp:394
void restoreSlidersPosition()
Definition: rsswidget.cpp:538
void loadFoldersOpenState()
Definition: rsswidget.cpp:322
void deleteSelectedItems()
Definition: rsswidget.cpp:303
void handleSessionProcessingStateChanged(bool enabled)
Definition: rsswidget.cpp:561
void downloadSelectedTorrents()
Definition: rsswidget.cpp:358
Ui::RSSWidget * m_ui
Definition: rsswidget.h:84
static UIThemeManager * instance()

References askNewFolder(), copySelectedFeedsURL(), deleteSelectedItems(), displayItemsListMenu(), displayRSSListMenu(), downloadSelectedTorrents(), handleCurrentArticleItemChanged(), handleCurrentFeedItemChanged(), handleSessionProcessingStateChanged(), handleUnreadCountChanged(), RSS::Session::instance(), UIThemeManager::instance(), loadFoldersOpenState(), m_articleListWidget, m_feedListWidget, m_ui, on_markReadButton_clicked(), on_newFeedButton_clicked(), openSelectedArticlesUrls(), RSS::Session::processingStateChanged(), refreshAllFeeds(), refreshSelectedItems(), renameSelectedRSSItem(), restoreSlidersPosition(), saveSlidersPosition(), FeedListWidget::stickyUnreadItem(), and RSS::Item::unreadCountChanged().

Here is the call graph for this function:

◆ ~RSSWidget()

RSSWidget::~RSSWidget ( )

Definition at line 130 of file rsswidget.cpp.

131 {
132  // we need it here to properly mark latest article
133  // as read without having additional code
134  m_articleListWidget->clear();
135 
137 
138  delete m_feedListWidget;
139  delete m_ui;
140 }
void saveFoldersOpenState()
Definition: rsswidget.cpp:345

References m_articleListWidget, m_feedListWidget, m_ui, and saveFoldersOpenState().

Here is the call graph for this function:

Member Function Documentation

◆ askNewFolder

void RSSWidget::askNewFolder ( )
privateslot

Definition at line 224 of file rsswidget.cpp.

225 {
226  bool ok = false;
227  QString newName = AutoExpandableDialog::getText(
228  this, tr("Please choose a folder name"), tr("Folder name:"), QLineEdit::Normal
229  , tr("New folder"), &ok);
230  if (!ok) return;
231 
232  newName = newName.trimmed();
233  if (newName.isEmpty()) return;
234 
235  // Determine destination folder for new item
236  QTreeWidgetItem *destItem = nullptr;
237  QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
238  if (!selectedItems.empty())
239  {
240  destItem = selectedItems.first();
241  if (!m_feedListWidget->isFolder(destItem))
242  destItem = destItem->parent();
243  }
244  // Consider the case where the user clicked on Unread item
245  RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem()))
247  : qobject_cast<RSS::Folder *>(m_feedListWidget->getRSSItem(destItem)));
248 
249  const QString newFolderPath = RSS::Item::joinPath(rssDestFolder->path(), newName);
250  const nonstd::expected<void, QString> result = RSS::Session::instance()->addFolder(newFolderPath);
251  if (!result)
252  QMessageBox::warning(this, "qBittorrent", result.error(), QMessageBox::Ok);
253 
254  // Expand destination folder to display new feed
255  if (destItem && (destItem != m_feedListWidget->stickyUnreadItem()))
256  destItem->setExpanded(true);
257  // As new RSS items are added synchronously, we can do the following here.
259 }
static QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode=QLineEdit::Normal, const QString &text={}, bool *ok=nullptr, bool excludeExtension=false, Qt::InputMethodHints inputMethodHints=Qt::ImhNone)
bool isFolder(QTreeWidgetItem *item) const
RSS::Item * getRSSItem(QTreeWidgetItem *item) const
QTreeWidgetItem * mapRSSItem(RSS::Item *rssItem) 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 > addFolder(const QString &path)
Folder * rootFolder() const
Item * itemByPath(const QString &path) const

References RSS::Session::addFolder(), FeedListWidget::getRSSItem(), AutoExpandableDialog::getText(), RSS::Session::instance(), FeedListWidget::isFolder(), RSS::Session::itemByPath(), RSS::Item::joinPath(), m_feedListWidget, FeedListWidget::mapRSSItem(), RSS::Item::path(), RSS::Session::rootFolder(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ copySelectedFeedsURL

void RSSWidget::copySelectedFeedsURL ( )
privateslot

Definition at line 437 of file rsswidget.cpp.

438 {
439  QStringList URLs;
440  for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
441  {
442  if (auto feed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item)))
443  URLs << feed->url();
444  }
445  qApp->clipboard()->setText(URLs.join('\n'));
446 }
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42

References asConst(), FeedListWidget::getRSSItem(), and m_feedListWidget.

Referenced by RSSWidget().

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

◆ deleteSelectedItems

void RSSWidget::deleteSelectedItems ( )
slot

Definition at line 303 of file rsswidget.cpp.

304 {
305  const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
306  if (selectedItems.isEmpty())
307  return;
308  if ((selectedItems.size() == 1) && (selectedItems.first() == m_feedListWidget->stickyUnreadItem()))
309  return;
310 
311  QMessageBox::StandardButton answer = QMessageBox::question(
312  this, tr("Deletion confirmation"), tr("Are you sure you want to delete the selected RSS feeds?")
313  , QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
314  if (answer == QMessageBox::No)
315  return;
316 
317  for (QTreeWidgetItem *item : selectedItems)
318  if (item != m_feedListWidget->stickyUnreadItem())
320 }
QString itemPath(QTreeWidgetItem *item) const
nonstd::expected< void, QString > removeItem(const QString &itemPath)

References RSS::Session::instance(), FeedListWidget::itemPath(), m_feedListWidget, RSS::Session::removeItem(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ displayItemsListMenu

void RSSWidget::displayItemsListMenu ( const QPoint &  )
privateslot

Definition at line 195 of file rsswidget.cpp.

196 {
197  bool hasTorrent = false;
198  bool hasLink = false;
199  for (const QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
200  {
201  auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
202  Q_ASSERT(article);
203 
204  if (!article->torrentUrl().isEmpty())
205  hasTorrent = true;
206  if (!article->link().isEmpty())
207  hasLink = true;
208  if (hasTorrent && hasLink)
209  break;
210  }
211 
212  QMenu *myItemListMenu = new QMenu(this);
213  myItemListMenu->setAttribute(Qt::WA_DeleteOnClose);
214 
215  if (hasTorrent)
216  myItemListMenu->addAction(m_ui->actionDownloadTorrent);
217  if (hasLink)
218  myItemListMenu->addAction(m_ui->actionOpenNewsURL);
219 
220  if (!myItemListMenu->isEmpty())
221  myItemListMenu->popup(QCursor::pos());
222 }
Definition: rss_article.h:43

References asConst(), m_articleListWidget, and m_ui.

Referenced by RSSWidget().

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

◆ displayRSSListMenu

void RSSWidget::displayRSSListMenu ( const QPoint &  pos)
privateslot

Definition at line 143 of file rsswidget.cpp.

144 {
145  if (!m_feedListWidget->indexAt(pos).isValid())
146  // No item under the mouse, clear selection
147  m_feedListWidget->clearSelection();
148 
149  QMenu *menu = new QMenu(this);
150  menu->setAttribute(Qt::WA_DeleteOnClose);
151 
152  const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
153  if (!selectedItems.isEmpty())
154  {
155  menu->addAction(m_ui->actionUpdate);
156  menu->addAction(m_ui->actionMarkItemsRead);
157  menu->addSeparator();
158 
159  if (selectedItems.size() == 1)
160  {
161  if (selectedItems.first() != m_feedListWidget->stickyUnreadItem())
162  {
163  menu->addAction(m_ui->actionRename);
164  menu->addAction(m_ui->actionDelete);
165  menu->addSeparator();
166  if (m_feedListWidget->isFolder(selectedItems.first()))
167  menu->addAction(m_ui->actionNewFolder);
168  }
169  }
170  else
171  {
172  menu->addAction(m_ui->actionDelete);
173  menu->addSeparator();
174  }
175 
176  menu->addAction(m_ui->actionNewSubscription);
177 
178  if (m_feedListWidget->isFeed(selectedItems.first()))
179  {
180  menu->addSeparator();
181  menu->addAction(m_ui->actionCopyFeedURL);
182  }
183  }
184  else
185  {
186  menu->addAction(m_ui->actionNewSubscription);
187  menu->addAction(m_ui->actionNewFolder);
188  menu->addSeparator();
189  menu->addAction(m_ui->actionUpdateAllFeeds);
190  }
191 
192  menu->popup(QCursor::pos());
193 }
bool isFeed(QTreeWidgetItem *item) const

References FeedListWidget::isFeed(), FeedListWidget::isFolder(), m_feedListWidget, m_ui, and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ downloadSelectedTorrents

void RSSWidget::downloadSelectedTorrents ( )
privateslot

Definition at line 358 of file rsswidget.cpp.

359 {
360  for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
361  {
362  auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
363  Q_ASSERT(article);
364 
365  // Mark as read
366  article->markAsRead();
367 
368  if (!article->torrentUrl().isEmpty())
369  {
371  AddNewTorrentDialog::show(article->torrentUrl(), window());
372  else
373  BitTorrent::Session::instance()->addTorrent(article->torrentUrl());
374  }
375  }
376 }
static void show(const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
static Session * instance()
Definition: session.cpp:997
bool addTorrent(const QString &source, const AddTorrentParams &params=AddTorrentParams())
Definition: session.cpp:2007

References BitTorrent::Session::addTorrent(), asConst(), BitTorrent::Session::instance(), AddNewTorrentDialog::isEnabled(), m_articleListWidget, and AddNewTorrentDialog::show().

Referenced by RSSWidget().

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

◆ handleCurrentArticleItemChanged

void RSSWidget::handleCurrentArticleItemChanged ( QListWidgetItem *  currentItem,
QListWidgetItem *  previousItem 
)
privateslot

Definition at line 465 of file rsswidget.cpp.

466 {
467  m_ui->textBrowser->clear();
468 
469  if (previousItem)
470  {
471  auto article = m_articleListWidget->getRSSArticle(previousItem);
472  Q_ASSERT(article);
473  article->markAsRead();
474  }
475 
476  if (!currentItem) return;
477 
478  auto article = m_articleListWidget->getRSSArticle(currentItem);
479  Q_ASSERT(article);
480 
481  const QString highlightedBaseColor = m_ui->textBrowser->palette().color(QPalette::Highlight).name();
482  const QString highlightedBaseTextColor = m_ui->textBrowser->palette().color(QPalette::HighlightedText).name();
483  const QString alternateBaseColor = m_ui->textBrowser->palette().color(QPalette::AlternateBase).name();
484 
485  QString html =
486  QString::fromLatin1("<div style='border: 2px solid red; margin-left: 5px; margin-right: 5px; margin-bottom: 5px;'>") +
487  QString::fromLatin1("<div style='background-color: \"%1\"; font-weight: bold; color: \"%2\";'>%3</div>").arg(highlightedBaseColor, highlightedBaseTextColor, article->title());
488  if (article->date().isValid())
489  html += QString::fromLatin1("<div style='background-color: \"%1\";'><b>%2</b>%3</div>").arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime()));
490  if (!article->author().isEmpty())
491  html += QString::fromLatin1("<div style='background-color: \"%1\";'><b>%2</b>%3</div>").arg(alternateBaseColor, tr("Author: "), article->author());
492  html += "</div>"
493  "<div style='margin-left: 5px; margin-right: 5px;'>";
494  if (Qt::mightBeRichText(article->description()))
495  {
496  html += article->description();
497  }
498  else
499  {
500  QString description = article->description();
501  QRegularExpression rx;
502  // If description is plain text, replace BBCode tags with HTML and wrap everything in <pre></pre> so it looks nice
503  rx.setPatternOptions(QRegularExpression::InvertedGreedinessOption
504  | QRegularExpression::CaseInsensitiveOption);
505 
506  rx.setPattern("\\[img\\](.+)\\[/img\\]");
507  description = description.replace(rx, "<img src=\"\\1\">");
508 
509  rx.setPattern("\\[url=(\")?(.+)\\1\\]");
510  description = description.replace(rx, "<a href=\"\\2\">");
511  description = description.replace("[/url]", "</a>", Qt::CaseInsensitive);
512 
513  rx.setPattern("\\[(/)?([bius])\\]");
514  description = description.replace(rx, "<\\1\\2>");
515 
516  rx.setPattern("\\[color=(\")?(.+)\\1\\]");
517  description = description.replace(rx, "<span style=\"color:\\2\">");
518  description = description.replace("[/color]", "</span>", Qt::CaseInsensitive);
519 
520  rx.setPattern("\\[size=(\")?(.+)\\d\\1\\]");
521  description = description.replace(rx, "<span style=\"font-size:\\2px\">");
522  description = description.replace("[/size]", "</span>", Qt::CaseInsensitive);
523 
524  html += "<pre>" + description + "</pre>";
525  }
526  html += "</div>";
527  m_ui->textBrowser->setHtml(html);
528 }
RSS::Article * getRSSArticle(QListWidgetItem *item) const
QString toString(const lt::socket_type_t socketType)
Definition: session.cpp:183

References ArticleListWidget::getRSSArticle(), m_articleListWidget, m_ui, and anonymous_namespace{session.cpp}::toString().

Referenced by RSSWidget().

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

◆ handleCurrentFeedItemChanged

void RSSWidget::handleCurrentFeedItemChanged ( QTreeWidgetItem *  currentItem)
privateslot

Definition at line 448 of file rsswidget.cpp.

449 {
451  , (currentItem == m_feedListWidget->stickyUnreadItem()));
452 }
void setRSSItem(RSS::Item *rssItem, bool unreadOnly=false)

References FeedListWidget::getRSSItem(), m_articleListWidget, m_feedListWidget, ArticleListWidget::setRSSItem(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ handleSessionProcessingStateChanged

void RSSWidget::handleSessionProcessingStateChanged ( bool  enabled)
privateslot

Definition at line 561 of file rsswidget.cpp.

562 {
563  m_ui->labelWarn->setVisible(!enabled);
564 }

References m_ui.

Referenced by RSSWidget().

Here is the caller graph for this function:

◆ handleUnreadCountChanged

void RSSWidget::handleUnreadCountChanged ( )
privateslot

Definition at line 566 of file rsswidget.cpp.

567 {
568  emit unreadCountUpdated(RSS::Session::instance()->rootFolder()->unreadCount());
569 }
void unreadCountUpdated(int count)

References RSS::Session::instance(), and unreadCountUpdated().

Referenced by RSSWidget().

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

◆ loadFoldersOpenState

void RSSWidget::loadFoldersOpenState ( )
privateslot

Definition at line 322 of file rsswidget.cpp.

323 {
324  const QStringList openedFolders = Preferences::instance()->getRssOpenFolders();
325  for (const QString &varPath : openedFolders)
326  {
327  QTreeWidgetItem *parent = nullptr;
328  for (const QString &name : asConst(varPath.split('\\')))
329  {
330  int nbChildren = (parent ? parent->childCount() : m_feedListWidget->topLevelItemCount());
331  for (int i = 0; i < nbChildren; ++i)
332  {
333  QTreeWidgetItem *child = (parent ? parent->child(i) : m_feedListWidget->topLevelItem(i));
334  if (m_feedListWidget->getRSSItem(child)->name() == name)
335  {
336  parent = child;
337  parent->setExpanded(true);
338  break;
339  }
340  }
341  }
342  }
343 }
static Preferences * instance()
QStringList getRssOpenFolders() const
QString name() const
Definition: rss_item.cpp:62

References asConst(), FeedListWidget::getRSSItem(), Preferences::getRssOpenFolders(), Preferences::instance(), m_feedListWidget, and RSS::Item::name().

Referenced by RSSWidget().

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

◆ on_markReadButton_clicked

void RSSWidget::on_markReadButton_clicked ( )
privateslot

Definition at line 454 of file rsswidget.cpp.

455 {
456  for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
457  {
459  if (item == m_feedListWidget->stickyUnreadItem())
460  break; // all items was read
461  }
462 }
virtual void markAsRead()=0

References asConst(), FeedListWidget::getRSSItem(), m_feedListWidget, RSS::Item::markAsRead(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ on_newFeedButton_clicked

void RSSWidget::on_newFeedButton_clicked ( )
privateslot

Definition at line 262 of file rsswidget.cpp.

263 {
264  // Ask for feed URL
265  const QString clipText = qApp->clipboard()->text();
266  const QString defaultURL = Net::DownloadManager::hasSupportedScheme(clipText) ? clipText : "http://";
267 
268  bool ok = false;
269  QString newURL = AutoExpandableDialog::getText(
270  this, tr("Please type a RSS feed URL"), tr("Feed URL:"), QLineEdit::Normal, defaultURL, &ok);
271  if (!ok) return;
272 
273  newURL = newURL.trimmed();
274  if (newURL.isEmpty()) return;
275 
276  // Determine destination folder for new item
277  QTreeWidgetItem *destItem = nullptr;
278  QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
279  if (!selectedItems.empty())
280  {
281  destItem = selectedItems.first();
282  if (!m_feedListWidget->isFolder(destItem))
283  destItem = destItem->parent();
284  }
285  // Consider the case where the user clicked on Unread item
286  RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem()))
288  : qobject_cast<RSS::Folder *>(m_feedListWidget->getRSSItem(destItem)));
289 
290  // NOTE: We still add feed using legacy way (with URL as feed name)
291  const QString newFeedPath = RSS::Item::joinPath(rssDestFolder->path(), newURL);
292  const nonstd::expected<void, QString> result = RSS::Session::instance()->addFeed(newURL, newFeedPath);
293  if (!result)
294  QMessageBox::warning(this, "qBittorrent", result.error(), QMessageBox::Ok);
295 
296  // Expand destination folder to display new feed
297  if (destItem && (destItem != m_feedListWidget->stickyUnreadItem()))
298  destItem->setExpanded(true);
299  // As new RSS items are added synchronously, we can do the following here.
301 }
static bool hasSupportedScheme(const QString &url)
nonstd::expected< void, QString > addFeed(const QString &url, const QString &path)

References RSS::Session::addFeed(), FeedListWidget::getRSSItem(), AutoExpandableDialog::getText(), Net::DownloadManager::hasSupportedScheme(), RSS::Session::instance(), FeedListWidget::isFolder(), RSS::Session::itemByPath(), RSS::Item::joinPath(), m_feedListWidget, FeedListWidget::mapRSSItem(), RSS::Item::path(), RSS::Session::rootFolder(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ on_rssDownloaderBtn_clicked

void RSSWidget::on_rssDownloaderBtn_clicked ( )
privateslot

Definition at line 554 of file rsswidget.cpp.

555 {
556  auto *downloader = new AutomatedRssDownloader(this);
557  downloader->setAttribute(Qt::WA_DeleteOnClose);
558  downloader->open();
559 }

◆ openSelectedArticlesUrls

void RSSWidget::openSelectedArticlesUrls ( )
privateslot

Definition at line 379 of file rsswidget.cpp.

380 {
381  for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
382  {
383  auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
384  Q_ASSERT(article);
385 
386  // Mark as read
387  article->markAsRead();
388 
389  if (!article->link().isEmpty())
390  QDesktopServices::openUrl(QUrl(article->link()));
391  }
392 }

References asConst(), and m_articleListWidget.

Referenced by RSSWidget().

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

◆ refreshAllFeeds

void RSSWidget::refreshAllFeeds ( )
privateslot

Definition at line 353 of file rsswidget.cpp.

354 {
356 }

References RSS::Session::instance(), and RSS::Session::refresh().

Referenced by refreshSelectedItems(), and RSSWidget().

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

◆ refreshSelectedItems

void RSSWidget::refreshSelectedItems ( )
privateslot

Definition at line 423 of file rsswidget.cpp.

424 {
425  for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
426  {
427  if (item == m_feedListWidget->stickyUnreadItem())
428  {
429  refreshAllFeeds();
430  return;
431  }
432 
434  }
435 }
virtual void refresh()=0

References asConst(), FeedListWidget::getRSSItem(), m_feedListWidget, RSS::Item::refresh(), refreshAllFeeds(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ renameSelectedRSSItem

void RSSWidget::renameSelectedRSSItem ( )
privateslot

Definition at line 394 of file rsswidget.cpp.

395 {
396  QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
397  if (selectedItems.size() != 1) return;
398 
399  QTreeWidgetItem *item = selectedItems.first();
400  if (item == m_feedListWidget->stickyUnreadItem())
401  return;
402 
403  RSS::Item *rssItem = m_feedListWidget->getRSSItem(item);
404  const QString parentPath = RSS::Item::parentPath(rssItem->path());
405  bool ok = false;
406  do
407  {
408  QString newName = AutoExpandableDialog::getText(
409  this, tr("Please choose a new name for this RSS feed"), tr("New feed name:")
410  , QLineEdit::Normal, rssItem->name(), &ok);
411  // Check if name is already taken
412  if (!ok) return;
413 
414  const nonstd::expected<void, QString> result = RSS::Session::instance()->moveItem(rssItem, RSS::Item::joinPath(parentPath, newName));
415  if (!result)
416  {
417  QMessageBox::warning(nullptr, tr("Rename failed"), result.error());
418  ok = false;
419  }
420  } while (!ok);
421 }
static QString parentPath(const QString &path)
Definition: rss_item.cpp:108
nonstd::expected< void, QString > moveItem(const QString &itemPath, const QString &destPath)

References FeedListWidget::getRSSItem(), AutoExpandableDialog::getText(), RSS::Session::instance(), RSS::Item::joinPath(), m_feedListWidget, RSS::Session::moveItem(), RSS::Item::name(), RSS::Item::parentPath(), RSS::Item::path(), and FeedListWidget::stickyUnreadItem().

Referenced by RSSWidget().

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

◆ restoreSlidersPosition

void RSSWidget::restoreSlidersPosition ( )
privateslot

Definition at line 538 of file rsswidget.cpp.

539 {
540  const Preferences *const pref = Preferences::instance();
541  const QByteArray stateSide = pref->getRssSideSplitterState();
542  if (!stateSide.isEmpty())
543  m_ui->splitterSide->restoreState(stateSide);
544  const QByteArray stateMain = pref->getRssMainSplitterState();
545  if (!stateMain.isEmpty())
546  m_ui->splitterMain->restoreState(stateMain);
547 }
QByteArray getRssMainSplitterState() const
QByteArray getRssSideSplitterState() const

References Preferences::getRssMainSplitterState(), Preferences::getRssSideSplitterState(), Preferences::instance(), and m_ui.

Referenced by RSSWidget().

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

◆ saveFoldersOpenState

void RSSWidget::saveFoldersOpenState ( )
privateslot

Definition at line 345 of file rsswidget.cpp.

346 {
347  QStringList openedFolders;
348  for (QTreeWidgetItem *item : asConst(m_feedListWidget->getAllOpenedFolders()))
349  openedFolders << m_feedListWidget->itemPath(item);
350  Preferences::instance()->setRssOpenFolders(openedFolders);
351 }
QList< QTreeWidgetItem * > getAllOpenedFolders(QTreeWidgetItem *parent=nullptr) const
void setRssOpenFolders(const QStringList &folders)

References asConst(), FeedListWidget::getAllOpenedFolders(), Preferences::instance(), FeedListWidget::itemPath(), m_feedListWidget, and Preferences::setRssOpenFolders().

Referenced by ~RSSWidget().

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

◆ saveSlidersPosition

void RSSWidget::saveSlidersPosition ( )
privateslot

Definition at line 530 of file rsswidget.cpp.

531 {
532  // Remember sliders positions
533  Preferences *const pref = Preferences::instance();
534  pref->setRssSideSplitterState(m_ui->splitterSide->saveState());
535  pref->setRssMainSplitterState(m_ui->splitterMain->saveState());
536 }
void setRssMainSplitterState(const QByteArray &state)
void setRssSideSplitterState(const QByteArray &state)

References Preferences::instance(), m_ui, Preferences::setRssMainSplitterState(), and Preferences::setRssSideSplitterState().

Referenced by RSSWidget().

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

◆ unreadCountUpdated

void RSSWidget::unreadCountUpdated ( int  count)
signal

Referenced by MainWindow::displayRSSTab(), and handleUnreadCountChanged().

Here is the caller graph for this function:

◆ updateRefreshInterval

void RSSWidget::updateRefreshInterval ( int  val) const
slot

Definition at line 549 of file rsswidget.cpp.

550 {
552 }
void setRefreshInterval(int refreshInterval)

References RSS::Session::instance(), and RSS::Session::setRefreshInterval().

Here is the call graph for this function:

Member Data Documentation

◆ m_articleListWidget

◆ m_feedListWidget

◆ m_ui


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