ability to open URL of article directly with keystroke

This commit is contained in:
Martin Rotter 2022-02-01 08:16:46 +01:00
parent efebb0199d
commit 4b984b4fc0
13 changed files with 106 additions and 54 deletions

View File

@ -26,7 +26,7 @@
<url type="donation">https://github.com/sponsors/martinrotter</url>
<content_rating type="oars-1.1" />
<releases>
<release version="4.1.2" date="2022-01-31"/>
<release version="4.1.2" date="2022-02-01"/>
</releases>
<content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">none</content_attribute>

View File

@ -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

View File

@ -183,6 +183,7 @@ QList<QAction*> 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,

View File

@ -45,7 +45,7 @@
<x>0</x>
<y>0</y>
<width>1296</width>
<height>23</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="m_menuFile">
@ -140,6 +140,7 @@
</property>
<addaction name="m_actionOpenSelectedSourceArticlesExternally"/>
<addaction name="m_actionOpenSelectedMessagesInternally"/>
<addaction name="m_actionOpenSelectedMessagesInternallyNoTab"/>
<addaction name="m_actionSendMessageViaEmail"/>
<addaction name="m_actionMessagePreviewEnabled"/>
<addaction name="m_actionShowOnlyUnreadMessages"/>
@ -847,6 +848,11 @@
<string>&amp;Copy URLs of selected articles</string>
</property>
</action>
<action name="m_actionOpenSelectedMessagesInternallyNoTab">
<property name="text">
<string>Open in internal browser (no new tab)</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -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);

View File

@ -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<const QUrl&>::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)

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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());

View File

@ -42,6 +42,7 @@ class MessagesView : public BaseTreeView {
// Message manipulators.
void openSelectedSourceMessagesExternally();
void openSelectedMessagesInternally();
void openSelectedMessageUrl();
void sendSelectedMessageViaEmail();
// Works with SELECTED messages only.

View File

@ -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);
}

View File

@ -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());