Skip to content

Commit

Permalink
Fix tab order in RSS widget
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocobo1 authored Dec 17, 2024
1 parent 1c82eb3 commit 34c8849
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 72 deletions.
129 changes: 62 additions & 67 deletions src/gui/rss/rsswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,19 @@ RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
m_ui->rssDownloaderBtn->setIcon(UIThemeManager::instance()->getIcon(u"downloading"_s, u"download"_s));
#endif

m_articleListWidget = new ArticleListWidget(m_ui->splitterMain);
m_ui->splitterMain->insertWidget(0, m_articleListWidget);
connect(m_articleListWidget, &ArticleListWidget::customContextMenuRequested, this, &RSSWidget::displayItemsListMenu);
connect(m_articleListWidget, &ArticleListWidget::currentItemChanged, this, &RSSWidget::handleCurrentArticleItemChanged);
connect(m_articleListWidget, &ArticleListWidget::itemDoubleClicked, this, &RSSWidget::downloadSelectedTorrents);

m_feedListWidget = new FeedListWidget(m_ui->splitterSide);
m_ui->splitterSide->insertWidget(0, m_feedListWidget);
connect(m_feedListWidget, &QAbstractItemView::doubleClicked, this, &RSSWidget::renameSelectedRSSItem);
connect(m_feedListWidget, &QTreeWidget::currentItemChanged, this, &RSSWidget::handleCurrentFeedItemChanged);
connect(m_feedListWidget, &QWidget::customContextMenuRequested, this, &RSSWidget::displayRSSListMenu);
connect(m_ui->articleListWidget, &ArticleListWidget::customContextMenuRequested, this, &RSSWidget::displayItemsListMenu);
connect(m_ui->articleListWidget, &ArticleListWidget::currentItemChanged, this, &RSSWidget::handleCurrentArticleItemChanged);
connect(m_ui->articleListWidget, &ArticleListWidget::itemDoubleClicked, this, &RSSWidget::downloadSelectedTorrents);

connect(m_ui->feedListWidget, &QAbstractItemView::doubleClicked, this, &RSSWidget::renameSelectedRSSItem);
connect(m_ui->feedListWidget, &QTreeWidget::currentItemChanged, this, &RSSWidget::handleCurrentFeedItemChanged);
connect(m_ui->feedListWidget, &QWidget::customContextMenuRequested, this, &RSSWidget::displayRSSListMenu);
loadFoldersOpenState();
m_feedListWidget->setCurrentItem(m_feedListWidget->stickyUnreadItem());
m_ui->feedListWidget->setCurrentItem(m_ui->feedListWidget->stickyUnreadItem());

const auto *editHotkey = new QShortcut(Qt::Key_F2, m_feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
const auto *editHotkey = new QShortcut(Qt::Key_F2, m_ui->feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
connect(editHotkey, &QShortcut::activated, this, &RSSWidget::renameSelectedRSSItem);
const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_ui->feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
connect(deleteHotkey, &QShortcut::activated, this, &RSSWidget::deleteSelectedItems);

// Feeds list actions
Expand Down Expand Up @@ -134,25 +130,24 @@ RSSWidget::~RSSWidget()
{
// we need it here to properly mark latest article
// as read without having additional code
m_articleListWidget->clear();
m_ui->articleListWidget->clear();

saveFoldersOpenState();

delete m_feedListWidget;
delete m_ui;
}

// display a right-click menu
void RSSWidget::displayRSSListMenu(const QPoint &pos)
{
if (!m_feedListWidget->indexAt(pos).isValid())
if (!m_ui->feedListWidget->indexAt(pos).isValid())
// No item under the mouse, clear selection
m_feedListWidget->clearSelection();
m_ui->feedListWidget->clearSelection();

QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);

const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
const QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (!selectedItems.isEmpty())
{
menu->addAction(m_ui->actionUpdate);
Expand All @@ -162,14 +157,14 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos)
if (selectedItems.size() == 1)
{
QTreeWidgetItem *selectedItem = selectedItems.first();
if (selectedItem != m_feedListWidget->stickyUnreadItem())
if (selectedItem != m_ui->feedListWidget->stickyUnreadItem())
{
menu->addAction(m_ui->actionRename);
if (m_feedListWidget->isFeed(selectedItem))
if (m_ui->feedListWidget->isFeed(selectedItem))
menu->addAction(m_ui->actionEditFeedURL);
menu->addAction(m_ui->actionDelete);
menu->addSeparator();
if (m_feedListWidget->isFolder(selectedItem))
if (m_ui->feedListWidget->isFolder(selectedItem))
menu->addAction(m_ui->actionNewFolder);
}
}
Expand All @@ -181,7 +176,7 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos)

menu->addAction(m_ui->actionNewSubscription);

if (m_feedListWidget->isFeed(selectedItems.first()))
if (m_ui->feedListWidget->isFeed(selectedItems.first()))
{
menu->addSeparator();
menu->addAction(m_ui->actionCopyFeedURL);
Expand All @@ -202,7 +197,7 @@ void RSSWidget::displayItemsListMenu()
{
bool hasTorrent = false;
bool hasLink = false;
for (const QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
for (const QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
{
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
Q_ASSERT(article);
Expand Down Expand Up @@ -240,28 +235,28 @@ void RSSWidget::askNewFolder()

// Determine destination folder for new item
QTreeWidgetItem *destItem = nullptr;
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (!selectedItems.empty())
{
destItem = selectedItems.first();
if (!m_feedListWidget->isFolder(destItem))
if (!m_ui->feedListWidget->isFolder(destItem))
destItem = destItem->parent();
}
// Consider the case where the user clicked on Unread item
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem()))
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_ui->feedListWidget->stickyUnreadItem()))
? RSS::Session::instance()->rootFolder()
: qobject_cast<RSS::Folder *>(m_feedListWidget->getRSSItem(destItem)));
: qobject_cast<RSS::Folder *>(m_ui->feedListWidget->getRSSItem(destItem)));

const QString newFolderPath = RSS::Item::joinPath(rssDestFolder->path(), newName);
const nonstd::expected<void, QString> result = RSS::Session::instance()->addFolder(newFolderPath);
if (!result)
QMessageBox::warning(this, u"qBittorrent"_s, result.error(), QMessageBox::Ok);

// Expand destination folder to display new feed
if (destItem && (destItem != m_feedListWidget->stickyUnreadItem()))
if (destItem && (destItem != m_ui->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)));
m_ui->feedListWidget->setCurrentItem(m_ui->feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFolderPath)));
}

// add a stream by a button
Expand All @@ -281,17 +276,17 @@ void RSSWidget::on_newFeedButton_clicked()

// Determine destination folder for new item
QTreeWidgetItem *destItem = nullptr;
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (!selectedItems.empty())
{
destItem = selectedItems.first();
if (!m_feedListWidget->isFolder(destItem))
if (!m_ui->feedListWidget->isFolder(destItem))
destItem = destItem->parent();
}
// Consider the case where the user clicked on Unread item
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem()))
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_ui->feedListWidget->stickyUnreadItem()))
? RSS::Session::instance()->rootFolder()
: qobject_cast<RSS::Folder *>(m_feedListWidget->getRSSItem(destItem)));
: qobject_cast<RSS::Folder *>(m_ui->feedListWidget->getRSSItem(destItem)));

// NOTE: We still add feed using legacy way (with URL as feed name)
const QString newFeedPath = RSS::Item::joinPath(rssDestFolder->path(), newURL);
Expand All @@ -300,18 +295,18 @@ void RSSWidget::on_newFeedButton_clicked()
QMessageBox::warning(this, u"qBittorrent"_s, result.error(), QMessageBox::Ok);

// Expand destination folder to display new feed
if (destItem && (destItem != m_feedListWidget->stickyUnreadItem()))
if (destItem && (destItem != m_ui->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(newFeedPath)));
m_ui->feedListWidget->setCurrentItem(m_ui->feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFeedPath)));
}

void RSSWidget::deleteSelectedItems()
{
const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
const QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (selectedItems.isEmpty())
return;
if ((selectedItems.size() == 1) && (selectedItems.first() == m_feedListWidget->stickyUnreadItem()))
if ((selectedItems.size() == 1) && (selectedItems.first() == m_ui->feedListWidget->stickyUnreadItem()))
return;

QMessageBox::StandardButton answer = QMessageBox::question(
Expand All @@ -321,8 +316,8 @@ void RSSWidget::deleteSelectedItems()
return;

for (QTreeWidgetItem *item : selectedItems)
if (item != m_feedListWidget->stickyUnreadItem())
RSS::Session::instance()->removeItem(m_feedListWidget->itemPath(item));
if (item != m_ui->feedListWidget->stickyUnreadItem())
RSS::Session::instance()->removeItem(m_ui->feedListWidget->itemPath(item));
}

void RSSWidget::loadFoldersOpenState()
Expand All @@ -333,11 +328,11 @@ void RSSWidget::loadFoldersOpenState()
QTreeWidgetItem *parent = nullptr;
for (const QString &name : asConst(varPath.split(u'\\')))
{
int nbChildren = (parent ? parent->childCount() : m_feedListWidget->topLevelItemCount());
int nbChildren = (parent ? parent->childCount() : m_ui->feedListWidget->topLevelItemCount());
for (int i = 0; i < nbChildren; ++i)
{
QTreeWidgetItem *child = (parent ? parent->child(i) : m_feedListWidget->topLevelItem(i));
if (m_feedListWidget->getRSSItem(child)->name() == name)
QTreeWidgetItem *child = (parent ? parent->child(i) : m_ui->feedListWidget->topLevelItem(i));
if (m_ui->feedListWidget->getRSSItem(child)->name() == name)
{
parent = child;
parent->setExpanded(true);
Expand All @@ -351,8 +346,8 @@ void RSSWidget::loadFoldersOpenState()
void RSSWidget::saveFoldersOpenState()
{
QStringList openedFolders;
for (QTreeWidgetItem *item : asConst(m_feedListWidget->getAllOpenedFolders()))
openedFolders << m_feedListWidget->itemPath(item);
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->getAllOpenedFolders()))
openedFolders << m_ui->feedListWidget->itemPath(item);
Preferences::instance()->setRssOpenFolders(openedFolders);
}

Expand All @@ -363,7 +358,7 @@ void RSSWidget::refreshAllFeeds()

void RSSWidget::downloadSelectedTorrents()
{
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
for (QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
{
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
Q_ASSERT(article);
Expand All @@ -378,7 +373,7 @@ void RSSWidget::downloadSelectedTorrents()
// open the url of the selected RSS articles in the Web browser
void RSSWidget::openSelectedArticlesUrls()
{
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
for (QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
{
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
Q_ASSERT(article);
Expand All @@ -393,14 +388,14 @@ void RSSWidget::openSelectedArticlesUrls()

void RSSWidget::renameSelectedRSSItem()
{
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (selectedItems.size() != 1) return;

QTreeWidgetItem *item = selectedItems.first();
if (item == m_feedListWidget->stickyUnreadItem())
if (item == m_ui->feedListWidget->stickyUnreadItem())
return;

RSS::Item *rssItem = m_feedListWidget->getRSSItem(item);
RSS::Item *rssItem = m_ui->feedListWidget->getRSSItem(item);
const QString parentPath = RSS::Item::parentPath(rssItem->path());
bool ok = false;
do
Expand All @@ -422,12 +417,12 @@ void RSSWidget::renameSelectedRSSItem()

void RSSWidget::editSelectedRSSFeedURL()
{
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (selectedItems.size() != 1)
return;

QTreeWidgetItem *item = selectedItems.first();
RSS::Feed *rssFeed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item));
RSS::Feed *rssFeed = qobject_cast<RSS::Feed *>(m_ui->feedListWidget->getRSSItem(item));
Q_ASSERT(rssFeed);
if (!rssFeed) [[unlikely]]
return;
Expand All @@ -445,41 +440,41 @@ void RSSWidget::editSelectedRSSFeedURL()

void RSSWidget::refreshSelectedItems()
{
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->selectedItems()))
{
if (item == m_feedListWidget->stickyUnreadItem())
if (item == m_ui->feedListWidget->stickyUnreadItem())
{
refreshAllFeeds();
return;
}

m_feedListWidget->getRSSItem(item)->refresh();
m_ui->feedListWidget->getRSSItem(item)->refresh();
}
}

void RSSWidget::copySelectedFeedsURL()
{
QStringList URLs;
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->selectedItems()))
{
if (auto *feed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item)))
if (auto *feed = qobject_cast<RSS::Feed *>(m_ui->feedListWidget->getRSSItem(item)))
URLs << feed->url();
}
qApp->clipboard()->setText(URLs.join(u'\n'));
}

void RSSWidget::handleCurrentFeedItemChanged(QTreeWidgetItem *currentItem)
{
m_articleListWidget->setRSSItem(m_feedListWidget->getRSSItem(currentItem)
, (currentItem == m_feedListWidget->stickyUnreadItem()));
m_ui->articleListWidget->setRSSItem(m_ui->feedListWidget->getRSSItem(currentItem)
, (currentItem == m_ui->feedListWidget->stickyUnreadItem()));
}

void RSSWidget::on_markReadButton_clicked()
{
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->selectedItems()))
{
m_feedListWidget->getRSSItem(item)->markAsRead();
if (item == m_feedListWidget->stickyUnreadItem())
m_ui->feedListWidget->getRSSItem(item)->markAsRead();
if (item == m_ui->feedListWidget->stickyUnreadItem())
break; // all items was read
}
}
Expand All @@ -491,15 +486,15 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL

if (previousItem)
{
auto *article = m_articleListWidget->getRSSArticle(previousItem);
auto *article = m_ui->articleListWidget->getRSSArticle(previousItem);
Q_ASSERT(article);
article->markAsRead();
}

if (!currentItem)
return;

auto *article = m_articleListWidget->getRSSArticle(currentItem);
auto *article = m_ui->articleListWidget->getRSSArticle(currentItem);
renderArticle(article);
}

Expand Down Expand Up @@ -548,10 +543,10 @@ bool RSSWidget::eventFilter(QObject *obj, QEvent *event)
{
if ((obj == m_ui->textBrowser) && (event->type() == QEvent::PaletteChange))
{
QListWidgetItem *currentItem = m_articleListWidget->currentItem();
QListWidgetItem *currentItem = m_ui->articleListWidget->currentItem();
if (currentItem)
{
const RSS::Article *article = m_articleListWidget->getRSSArticle(currentItem);
const RSS::Article *article = m_ui->articleListWidget->getRSSArticle(currentItem);
renderArticle(article);
}
}
Expand All @@ -572,7 +567,7 @@ void RSSWidget::renderArticle(const RSS::Article *article) const
u"<div style='background-color: \"%1\"; font-weight: bold; color: \"%2\";'>%3</div>"_s.arg(highlightedBaseColor, highlightedBaseTextColor, article->title());
if (article->date().isValid())
html += u"<div style='background-color: \"%1\";'><b>%2</b>%3</div>"_s.arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime()));
if (m_feedListWidget->currentItem() == m_feedListWidget->stickyUnreadItem())
if (m_ui->feedListWidget->currentItem() == m_ui->feedListWidget->stickyUnreadItem())
html += u"<div style='background-color: \"%1\";'><b>%2</b>%3</div>"_s.arg(alternateBaseColor, tr("Feed: "), article->feed()->title());
if (!article->author().isEmpty())
html += u"<div style='background-color: \"%1\";'><b>%2</b>%3</div>"_s.arg(alternateBaseColor, tr("Author: "), article->author());
Expand Down
5 changes: 0 additions & 5 deletions src/gui/rss/rsswidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@
class QListWidgetItem;
class QTreeWidgetItem;

class ArticleListWidget;
class FeedListWidget;

namespace RSS
{
class Article;
Expand Down Expand Up @@ -94,6 +91,4 @@ private slots:
void renderArticle(const RSS::Article *article) const;

Ui::RSSWidget *m_ui = nullptr;
ArticleListWidget *m_articleListWidget = nullptr;
FeedListWidget *m_feedListWidget = nullptr;
};
Loading

0 comments on commit 34c8849

Please sign in to comment.