From 4b984b4fc0222ccceb8712db634d3f4bca33049a Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 1 Feb 2022 08:16:46 +0100 Subject: [PATCH] ability to open URL of article directly with keystroke --- .../desktop/com.github.rssguard.appdata.xml | 2 +- resources/rssguard.rc.in | 2 +- src/librssguard/gui/dialogs/formmain.cpp | 7 ++ src/librssguard/gui/dialogs/formmain.ui | 8 +- src/librssguard/gui/feedmessageviewer.cpp | 2 + src/librssguard/gui/messagebrowser.cpp | 108 +++++++++--------- src/librssguard/gui/messagebrowser.h | 4 + src/librssguard/gui/messagepreviewer.cpp | 9 ++ src/librssguard/gui/messagepreviewer.h | 1 + src/librssguard/gui/messagesview.cpp | 14 +++ src/librssguard/gui/messagesview.h | 1 + src/librssguard/gui/tabwidget.cpp | 1 + src/librssguard/network-web/downloader.cpp | 1 + 13 files changed, 106 insertions(+), 54 deletions(-) diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml index b5d780895..fe6409688 100644 --- a/resources/desktop/com.github.rssguard.appdata.xml +++ b/resources/desktop/com.github.rssguard.appdata.xml @@ -26,7 +26,7 @@ https://github.com/sponsors/martinrotter - + none diff --git a/resources/rssguard.rc.in b/resources/rssguard.rc.in index af3c95da8..a3328e838 100644 --- a/resources/rssguard.rc.in +++ b/resources/rssguard.rc.in @@ -29,7 +29,7 @@ BEGIN VALUE "LegalCopyright", "@APP_COPYRIGHT@" VALUE "OriginalFilename", "@CMAKE_PROJECT_NAME@.exe" VALUE "ProductName", "@APP_NAME@" - VALUE "ProductVersion","@CMAKE_PROJECT_VERSION@" + VALUE "ProductVersion","@CMAKE_PROJECT_VERSION@-@APP_REVISION@" END END diff --git a/src/librssguard/gui/dialogs/formmain.cpp b/src/librssguard/gui/dialogs/formmain.cpp index 67fd67aa7..490791de1 100644 --- a/src/librssguard/gui/dialogs/formmain.cpp +++ b/src/librssguard/gui/dialogs/formmain.cpp @@ -183,6 +183,7 @@ QList FormMain::allActions() const { actions << m_ui->m_actionSendMessageViaEmail; actions << m_ui->m_actionOpenSelectedSourceArticlesExternally; actions << m_ui->m_actionOpenSelectedMessagesInternally; + actions << m_ui->m_actionOpenSelectedMessagesInternallyNoTab; actions << m_ui->m_actionAlternateColorsInLists; actions << m_ui->m_actionMessagePreviewEnabled; actions << m_ui->m_actionMarkAllItemsRead; @@ -454,6 +455,7 @@ void FormMain::updateMessageButtonsAvailability() { m_ui->m_actionRestoreSelectedMessages->setEnabled(atleast_one_message_selected && bin_loaded); m_ui->m_actionMarkSelectedMessagesAsRead->setEnabled(atleast_one_message_selected); m_ui->m_actionMarkSelectedMessagesAsUnread->setEnabled(atleast_one_message_selected); + m_ui->m_actionOpenSelectedMessagesInternallyNoTab->setEnabled(one_message_selected); m_ui->m_actionOpenSelectedMessagesInternally->setEnabled(atleast_one_message_selected); m_ui->m_actionOpenSelectedSourceArticlesExternally->setEnabled(atleast_one_message_selected); m_ui->m_actionCopyUrlSelectedArticles->setEnabled(atleast_one_message_selected); @@ -581,6 +583,7 @@ void FormMain::setupIcons() { m_ui->m_actionSwitchImportanceOfSelectedMessages->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-important"))); m_ui->m_actionOpenSelectedSourceArticlesExternally->setIcon(icon_theme_factory->fromTheme(QSL("document-open"))); m_ui->m_actionOpenSelectedMessagesInternally->setIcon(icon_theme_factory->fromTheme(QSL("document-open"))); + m_ui->m_actionOpenSelectedMessagesInternallyNoTab->setIcon(icon_theme_factory->fromTheme(QSL("document-open"))); m_ui->m_actionSendMessageViaEmail->setIcon(icon_theme_factory->fromTheme(QSL("mail-send"))); m_ui->m_actionViewSelectedItemsNewspaperMode->setIcon(icon_theme_factory->fromTheme(QSL("format-justify-fill"))); m_ui->m_actionSelectNextItem->setIcon(icon_theme_factory->fromTheme(QSL("go-down"))); @@ -785,6 +788,10 @@ void FormMain::createConnections() { &QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::openSelectedSourceMessagesExternally); connect(m_ui->m_actionOpenSelectedMessagesInternally, &QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::openSelectedMessagesInternally); + + connect(m_ui->m_actionOpenSelectedMessagesInternallyNoTab, + &QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::openSelectedMessageUrl); + connect(m_ui->m_actionSendMessageViaEmail, &QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::sendSelectedMessageViaEmail); connect(m_ui->m_actionMarkAllItemsRead, diff --git a/src/librssguard/gui/dialogs/formmain.ui b/src/librssguard/gui/dialogs/formmain.ui index d3e211961..ecd059638 100644 --- a/src/librssguard/gui/dialogs/formmain.ui +++ b/src/librssguard/gui/dialogs/formmain.ui @@ -45,7 +45,7 @@ 0 0 1296 - 23 + 22 @@ -140,6 +140,7 @@ + @@ -847,6 +848,11 @@ &Copy URLs of selected articles + + + Open in internal browser (no new tab) + + diff --git a/src/librssguard/gui/feedmessageviewer.cpp b/src/librssguard/gui/feedmessageviewer.cpp index 795faf202..f149b06e8 100644 --- a/src/librssguard/gui/feedmessageviewer.cpp +++ b/src/librssguard/gui/feedmessageviewer.cpp @@ -52,6 +52,7 @@ FeedMessageViewer::FeedMessageViewer(QWidget* parent) : TabContent(parent), m_to m_messagesBrowser(new MessagePreviewer(false, this)) { initialize(); initializeViews(); + createConnections(); } @@ -262,6 +263,7 @@ void FeedMessageViewer::createConnections() { m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById); connect(m_messagesView, &MessagesView::currentMessageChanged, this, &FeedMessageViewer::displayMessage); + connect(m_messagesView, &MessagesView::openLinkMiniBrowser, m_messagesBrowser, &MessagePreviewer::loadUrl); // If user selects feeds, load their messages. connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem); diff --git a/src/librssguard/gui/messagebrowser.cpp b/src/librssguard/gui/messagebrowser.cpp index 59e560647..fcf8a56ff 100644 --- a/src/librssguard/gui/messagebrowser.cpp +++ b/src/librssguard/gui/messagebrowser.cpp @@ -40,57 +40,7 @@ MessageBrowser::MessageBrowser(bool should_resize_to_fit, QWidget* parent) } }); - connect(m_txtBrowser, &QTextBrowser::anchorClicked, [=](const QUrl& url) { - if (url.toString().startsWith(INTERNAL_URL_PASSATTACHMENT) && - m_root != nullptr && - m_root->getParentServiceRoot()->downloadAttachmentOnMyOwn(url)) { - return; - } - - if (!url.isEmpty()) { - bool open_externally_now = qApp->settings()->value(GROUP(Browser), - SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool(); - - if (open_externally_now) { - qApp->web()->openUrlInExternalBrowser(url.toString()); - } - else { - // User clicked some URL. Open it in external browser or download? - MessageBox box(qApp->mainFormWidget()); - box.setText(tr("You clicked some link. You can download the link contents or open it in external web browser.")); - box.setInformativeText(tr("What action do you want to take?")); - box.setDetailedText(url.toString()); - - QAbstractButton* btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ButtonRole::ActionRole); - QAbstractButton* btn_download = box.addButton(tr("Download"), QMessageBox::ButtonRole::ActionRole); - QAbstractButton* btn_cancel = box.addButton(QMessageBox::StandardButton::Cancel); - bool always; - MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always); - - box.setDefaultButton(QMessageBox::StandardButton::Cancel); - box.exec(); - - if (box.clickedButton() != box.button(QMessageBox::StandardButton::Cancel)) { - // Store selected checkbox value. - qApp->settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, always); - } - - if (box.clickedButton() == btn_open) { - qApp->web()->openUrlInExternalBrowser(url.toString()); - } - else if (box.clickedButton() == btn_download) { - qApp->downloadManager()->download(url); - } - - btn_download->deleteLater(); - btn_open->deleteLater(); - btn_cancel->deleteLater(); - } - } - else { - MessageBox::show(qApp->mainFormWidget(), QMessageBox::Warning, tr("Incorrect link"), tr("Selected hyperlink is invalid.")); - } - }); + connect(m_txtBrowser, &QTextBrowser::anchorClicked, this, &MessageBrowser::onAnchorClicked); connect(m_txtBrowser, QOverload::of(&QTextBrowser::highlighted), [=](const QUrl& url) { @@ -198,6 +148,58 @@ bool MessageBrowser::eventFilter(QObject* watched, QEvent* event) { return false; } +void MessageBrowser::onAnchorClicked(const QUrl &url) { + if (url.toString().startsWith(INTERNAL_URL_PASSATTACHMENT) && + m_root != nullptr && + m_root->getParentServiceRoot()->downloadAttachmentOnMyOwn(url)) { + return; + } + + if (!url.isEmpty()) { + bool open_externally_now = qApp->settings()->value(GROUP(Browser), + SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool(); + + if (open_externally_now) { + qApp->web()->openUrlInExternalBrowser(url.toString()); + } + else { + // User clicked some URL. Open it in external browser or download? + MessageBox box(qApp->mainFormWidget()); + box.setText(tr("You clicked some link. You can download the link contents or open it in external web browser.")); + box.setInformativeText(tr("What action do you want to take?")); + box.setDetailedText(url.toString()); + + QAbstractButton* btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ButtonRole::ActionRole); + QAbstractButton* btn_download = box.addButton(tr("Download"), QMessageBox::ButtonRole::ActionRole); + QAbstractButton* btn_cancel = box.addButton(QMessageBox::StandardButton::Cancel); + bool always; + MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always); + + box.setDefaultButton(QMessageBox::StandardButton::Cancel); + box.exec(); + + if (box.clickedButton() != box.button(QMessageBox::StandardButton::Cancel)) { + // Store selected checkbox value. + qApp->settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, always); + } + + if (box.clickedButton() == btn_open) { + qApp->web()->openUrlInExternalBrowser(url.toString()); + } + else if (box.clickedButton() == btn_download) { + qApp->downloadManager()->download(url); + } + + btn_download->deleteLater(); + btn_open->deleteLater(); + btn_cancel->deleteLater(); + } + } + else { + MessageBox::show(qApp->mainFormWidget(), QMessageBox::Warning, tr("Incorrect link"), tr("Selected hyperlink is invalid.")); + } +} + void MessageBrowser::reloadFontSettings() { const Settings* settings = qApp->settings(); QFont fon; @@ -206,6 +208,10 @@ void MessageBrowser::reloadFontSettings() { m_txtBrowser->setFont(fon); } +void MessageBrowser::loadUrl(const QString &url) { + onAnchorClicked(url); +} + void MessageBrowser::loadMessage(const Message& message, RootItem* root) { Q_UNUSED(root) diff --git a/src/librssguard/gui/messagebrowser.h b/src/librssguard/gui/messagebrowser.h index 38e8ed603..4422159ce 100644 --- a/src/librssguard/gui/messagebrowser.h +++ b/src/librssguard/gui/messagebrowser.h @@ -28,11 +28,15 @@ class MessageBrowser : public QWidget { void setVerticalScrollBarPosition(double pos); void clear(bool also_hide); void reloadFontSettings(); + void loadUrl(const QString& url); void loadMessage(const Message& message, RootItem* root); protected: bool eventFilter(QObject* watched, QEvent* event); + private slots: + void onAnchorClicked(const QUrl& url); + private: QString prepareHtmlForMessage(const Message& message); diff --git a/src/librssguard/gui/messagepreviewer.cpp b/src/librssguard/gui/messagepreviewer.cpp index 5ed95217c..714497ce7 100644 --- a/src/librssguard/gui/messagepreviewer.cpp +++ b/src/librssguard/gui/messagepreviewer.cpp @@ -107,6 +107,15 @@ void MessagePreviewer::hideToolbar() { m_toolBar->setVisible(false); } +void MessagePreviewer::loadUrl(const QString &url) { +#if defined(USE_WEBENGINE) + m_txtMessage->loadUrl(url); + +#else + m_txtMessage->loadUrl(url); +#endif +} + void MessagePreviewer::loadMessage(const Message& message, RootItem* root) { bool same_message = message.m_id == m_message.m_id && m_root == root; diff --git a/src/librssguard/gui/messagepreviewer.h b/src/librssguard/gui/messagepreviewer.h index 3aea7db1c..946e9e709 100644 --- a/src/librssguard/gui/messagepreviewer.h +++ b/src/librssguard/gui/messagepreviewer.h @@ -49,6 +49,7 @@ class MessagePreviewer : public QWidget { void setToolbarsVisible(bool visible); void clear(); void hideToolbar(); + void loadUrl(const QString& url); void loadMessage(const Message& message, RootItem* root); private slots: diff --git a/src/librssguard/gui/messagesview.cpp b/src/librssguard/gui/messagesview.cpp index c447ca827..bcb09e9ed 100644 --- a/src/librssguard/gui/messagesview.cpp +++ b/src/librssguard/gui/messagesview.cpp @@ -373,12 +373,14 @@ void MessagesView::initializeContextMenu() { << qApp->mainForm()->m_ui->m_actionSendMessageViaEmail << qApp->mainForm()->m_ui->m_actionOpenSelectedSourceArticlesExternally << qApp->mainForm()->m_ui->m_actionOpenSelectedMessagesInternally + << qApp->mainForm()->m_ui->m_actionOpenSelectedMessagesInternallyNoTab << qApp->mainForm()->m_ui->m_actionCopyUrlSelectedArticles << qApp->mainForm()->m_ui->m_actionMarkSelectedMessagesAsRead << qApp->mainForm()->m_ui->m_actionMarkSelectedMessagesAsUnread << qApp->mainForm()->m_ui->m_actionSwitchImportanceOfSelectedMessages << qApp->mainForm()->m_ui->m_actionDeleteSelectedMessages); + if (m_sourceModel->loadedItem() != nullptr) { if (m_sourceModel->loadedItem()->kind() == RootItem::Kind::Bin) { m_contextMenu->addAction(qApp->mainForm()->m_ui->m_actionRestoreSelectedMessages); @@ -542,6 +544,18 @@ void MessagesView::openSelectedMessagesInternally() { } } +void MessagesView::openSelectedMessageUrl() { + auto rws = selectionModel()->selectedRows(); + + if (!rws.isEmpty()) { + auto msg = m_sourceModel->messageAt(m_proxyModel->mapToSource(rws.at(0)).row()); + + if (!msg.m_url.isEmpty()) { + emit openLinkMiniBrowser(msg.m_url); + } + } +} + void MessagesView::sendSelectedMessageViaEmail() { if (selectionModel()->selectedRows().size() == 1) { const Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(selectionModel()->selectedRows().at(0)).row()); diff --git a/src/librssguard/gui/messagesview.h b/src/librssguard/gui/messagesview.h index bb9529e28..3a8111947 100644 --- a/src/librssguard/gui/messagesview.h +++ b/src/librssguard/gui/messagesview.h @@ -42,6 +42,7 @@ class MessagesView : public BaseTreeView { // Message manipulators. void openSelectedSourceMessagesExternally(); void openSelectedMessagesInternally(); + void openSelectedMessageUrl(); void sendSelectedMessageViaEmail(); // Works with SELECTED messages only. diff --git a/src/librssguard/gui/tabwidget.cpp b/src/librssguard/gui/tabwidget.cpp index 844685060..4bdae2fd7 100644 --- a/src/librssguard/gui/tabwidget.cpp +++ b/src/librssguard/gui/tabwidget.cpp @@ -126,6 +126,7 @@ void TabWidget::createConnections() { connect(tabBar(), &TabBar::tabCloseRequested, this, &TabWidget::closeTab); connect(tabBar(), &TabBar::emptySpaceDoubleClicked, this, &TabWidget::addEmptyBrowser); connect(tabBar(), &TabBar::tabMoved, this, &TabWidget::fixContentsAfterMove); + connect(feedMessageViewer()->messagesView(), &MessagesView::openMessagesInNewspaperView, this, &TabWidget::addNewspaperView); connect(feedMessageViewer()->feedsView(), &FeedsView::openMessagesInNewspaperView, this, &TabWidget::addNewspaperView); } diff --git a/src/librssguard/network-web/downloader.cpp b/src/librssguard/network-web/downloader.cpp index a9a184ec6..c31da6327 100644 --- a/src/librssguard/network-web/downloader.cpp +++ b/src/librssguard/network-web/downloader.cpp @@ -21,6 +21,7 @@ Downloader::Downloader(QObject* parent) m_lastOutputData(QByteArray()), m_lastOutputError(QNetworkReply::NoError) { m_timer->setInterval(DOWNLOAD_TIMEOUT); m_timer->setSingleShot(true); + connect(m_timer, &QTimer::timeout, this, &Downloader::cancel); m_downloadManager->setCookieJar(qApp->web()->cookieJar());