diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml index 8ba6c5cd9..80be04abd 100644 --- a/resources/desktop/com.github.rssguard.appdata.xml +++ b/resources/desktop/com.github.rssguard.appdata.xml @@ -30,7 +30,7 @@ https://martinrotter.github.io/donate/ - + none diff --git a/resources/scripts/7za b/resources/scripts/7za index 9c10723bf..47f412575 160000 --- a/resources/scripts/7za +++ b/resources/scripts/7za @@ -1 +1 @@ -Subproject commit 9c10723bfbaf6cb85107d6ee16e0324e9e487749 +Subproject commit 47f4125753452eff8800dbd6600c5a05540b15d9 diff --git a/src/librssguard/definitions/definitions.h b/src/librssguard/definitions/definitions.h index 9e0961710..76af20060 100755 --- a/src/librssguard/definitions/definitions.h +++ b/src/librssguard/definitions/definitions.h @@ -82,8 +82,8 @@ #define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8" #define GOOGLE_SUGGEST_URL "http://suggestqueries.google.com/complete/search?output=toolbar&hl=en&q=%1" -#define EXTERNAL_TOOL_SEPARATOR "###" -#define EXTERNAL_TOOL_PARAM_SEPARATOR "|||" +#define EXECUTION_LINE_SEPARATOR "#" +#define EXTERNAL_TOOL_SEPARATOR "|||" #define USER_DATA_PLACEHOLDER "%data%" #define CLI_LOG_SHORT "l" diff --git a/src/librssguard/gui/messagebrowser.cpp b/src/librssguard/gui/messagebrowser.cpp index 3d42be517..8af93a3c9 100644 --- a/src/librssguard/gui/messagebrowser.cpp +++ b/src/librssguard/gui/messagebrowser.cpp @@ -100,6 +100,8 @@ MessageBrowser::MessageBrowser(bool should_resize_to_fit, QWidget* parent) m_searchWidget->hide(); installEventFilter(this); + + reloadFontSettings(); } void MessageBrowser::clear() { diff --git a/src/librssguard/gui/messagepreviewer.cpp b/src/librssguard/gui/messagepreviewer.cpp index 9b1030db0..7d085dcb0 100755 --- a/src/librssguard/gui/messagepreviewer.cpp +++ b/src/librssguard/gui/messagepreviewer.cpp @@ -71,7 +71,7 @@ MessagePreviewer::MessagePreviewer(bool should_resize_to_fit, QWidget* parent) createConnections(); m_actionSwitchImportance->setCheckable(true); - reloadFontSettings(); + //reloadFontSettings(); clear(); } diff --git a/src/librssguard/gui/messagesview.cpp b/src/librssguard/gui/messagesview.cpp index 8221213be..01851c67a 100644 --- a/src/librssguard/gui/messagesview.cpp +++ b/src/librssguard/gui/messagesview.cpp @@ -224,7 +224,7 @@ void MessagesView::initializeContextMenu() { } if (menu_ext_tools->actions().isEmpty()) { - QAction* act_not_tools = new QAction("No external tools activated"); + QAction* act_not_tools = new QAction(tr("No external tools activated")); act_not_tools->setEnabled(false); menu_ext_tools->addAction(act_not_tools); @@ -598,10 +598,10 @@ void MessagesView::openSelectedMessagesWithExternalTool() { .replace(QRegularExpression("[\\t\\n]"), QString()); if (!link.isEmpty()) { - if (!QProcess::startDetached(tool.executable(), QStringList() << tool.parameters() << link)) { + if (!tool.run(link)) { qApp->showGuiMessage(tr("Cannot run external tool"), tr("External tool '%1' could not be started.").arg(tool.executable()), - QSystemTrayIcon::Critical); + QSystemTrayIcon::MessageIcon::Critical); } } } diff --git a/src/librssguard/gui/settings/settingsbrowsermail.cpp b/src/librssguard/gui/settings/settingsbrowsermail.cpp index 4beb117e0..53aeb668d 100644 --- a/src/librssguard/gui/settings/settingsbrowsermail.cpp +++ b/src/librssguard/gui/settings/settingsbrowsermail.cpp @@ -2,10 +2,12 @@ #include "gui/settings/settingsbrowsermail.h" +#include "exceptions/applicationexception.h" #include "gui/guiutilities.h" #include "gui/networkproxydetails.h" #include "miscellaneous/application.h" #include "miscellaneous/externaltool.h" +#include "miscellaneous/iconfactory.h" #include "network-web/silentnetworkaccessmanager.h" #include "network-web/webfactory.h" @@ -23,6 +25,10 @@ SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent) GuiUtilities::setLabelAsNotice(*m_ui->m_lblExternalEmailInfo, false); GuiUtilities::setLabelAsNotice(*m_ui->m_lblToolInfo, false); + m_ui->m_btnAddTool->setIcon(qApp->icons()->fromTheme(QSL("list-add"))); + m_ui->m_btnEditTool->setIcon(qApp->icons()->fromTheme(QSL("document-edit"))); + m_ui->m_btnDeleteTool->setIcon(qApp->icons()->fromTheme(QSL("list-remove"))); + #if defined(USE_WEBENGINE) m_ui->m_checkOpenLinksInExternal->setVisible(false); #else @@ -46,13 +52,17 @@ SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent) &SettingsBrowserMail::changeDefaultEmailArguments); connect(m_ui->m_btnExternalEmailExecutable, &QPushButton::clicked, this, &SettingsBrowserMail::selectEmailExecutable); connect(m_ui->m_btnAddTool, &QPushButton::clicked, this, &SettingsBrowserMail::dirtifySettings); + connect(m_ui->m_btnEditTool, &QPushButton::clicked, this, &SettingsBrowserMail::dirtifySettings); connect(m_ui->m_btnDeleteTool, &QPushButton::clicked, this, &SettingsBrowserMail::dirtifySettings); connect(m_ui->m_btnAddTool, &QPushButton::clicked, this, &SettingsBrowserMail::addExternalTool); + connect(m_ui->m_btnEditTool, &QPushButton::clicked, this, &SettingsBrowserMail::editSelectedExternalTool); connect(m_ui->m_btnDeleteTool, &QPushButton::clicked, this, &SettingsBrowserMail::deleteSelectedExternalTool); + connect(m_ui->m_listTools, &QTreeWidget::itemDoubleClicked, this, &SettingsBrowserMail::editSelectedExternalTool); connect(m_ui->m_listTools, &QTreeWidget::currentItemChanged, this, [this](QTreeWidgetItem* current, QTreeWidgetItem* previous) { Q_UNUSED(previous) m_ui->m_btnDeleteTool->setEnabled(current != nullptr); + m_ui->m_btnEditTool->setEnabled(current != nullptr); }); } @@ -87,7 +97,7 @@ QList SettingsBrowserMail::externalTools() const { QList list; for (int i = 0; i < m_ui->m_listTools->topLevelItemCount(); i++) { - list.append(m_ui->m_listTools->topLevelItem(i)->data(0, Qt::UserRole).value()); + list.append(m_ui->m_listTools->topLevelItem(i)->data(0, Qt::ItemDataRole::UserRole).value()); } return list; @@ -96,9 +106,9 @@ QList SettingsBrowserMail::externalTools() const { void SettingsBrowserMail::setExternalTools(const QList& list) { for (const ExternalTool& tool : list) { QTreeWidgetItem* item = new QTreeWidgetItem(m_ui->m_listTools, - QStringList() << tool.executable() << tool.parameters().join(QL1C(' '))); + QStringList() << tool.executable() << tool.parameters()); - item->setData(0, Qt::UserRole, QVariant::fromValue(tool)); + item->setData(0, Qt::ItemDataRole::UserRole, QVariant::fromValue(tool)); m_ui->m_listTools->addTopLevelItem(item); } @@ -202,36 +212,66 @@ void SettingsBrowserMail::saveSettings() { } void SettingsBrowserMail::addExternalTool() { - QString executable_file = QFileDialog::getOpenFileName(this, - tr("Select external tool"), - qApp->homeFolder(), + try { + auto tool = tweakExternalTool(ExternalTool(qApp->homeFolder(), {})); + QTreeWidgetItem* item = new QTreeWidgetItem(m_ui->m_listTools, + QStringList() << QDir::toNativeSeparators(tool.executable()) + << tool.parameters()); - //: File filter for external tool selection dialog. -#if defined(Q_OS_LINUX) - tr("Executables (*)")); -#else + item->setData(0, Qt::ItemDataRole::UserRole, QVariant::fromValue(tool)); + m_ui->m_listTools->addTopLevelItem(item); + } + catch (const ApplicationException& ex) { + // NOTE: Tool adding cancelled. + } +} + +ExternalTool SettingsBrowserMail::tweakExternalTool(const ExternalTool& tool) const { + QString executable_file = QFileDialog::getOpenFileName(window(), + tr("Select external tool"), + tool.executable(), +#if defined(Q_OS_WIN) tr("Executables (*.*)")); +#else + tr("Executables (*)")); #endif if (!executable_file.isEmpty()) { executable_file = QDir::toNativeSeparators(executable_file); bool ok; - QString parameters = QInputDialog::getText(this, + QString parameters = QInputDialog::getText(window(), tr("Enter parameters"), - tr( - "Enter (optional) parameters separated by single space to send to executable when opening URLs."), + tr("Enter (optional) parameters separated by \"%1\":").arg(EXECUTION_LINE_SEPARATOR), QLineEdit::EchoMode::Normal, - QString(), + tool.parameters(), &ok); if (ok) { - QTreeWidgetItem* item = new QTreeWidgetItem(m_ui->m_listTools, - QStringList() << QDir::toNativeSeparators(executable_file) << parameters); - - item->setData(0, Qt::UserRole, QVariant::fromValue(ExternalTool(executable_file, parameters.split(QSL(" "))))); - m_ui->m_listTools->addTopLevelItem(item); + return ExternalTool(executable_file, parameters); } } + + throw ApplicationException(); +} + +void SettingsBrowserMail::editSelectedExternalTool() { + auto* cur_it = m_ui->m_listTools->currentItem(); + + if (cur_it == nullptr) { + return; + } + + auto ext_tool = cur_it->data(0, Qt::ItemDataRole::UserRole).value(); + + try { + ext_tool = tweakExternalTool(ext_tool); + m_ui->m_listTools->currentItem()->setText(0, ext_tool.executable()); + m_ui->m_listTools->currentItem()->setText(1, ext_tool.parameters()); + m_ui->m_listTools->currentItem()->setData(0, Qt::ItemDataRole::UserRole, QVariant::fromValue(ext_tool)); + } + catch (const ApplicationException& ex) { + // NOTE: Tool adding cancelled. + } } void SettingsBrowserMail::deleteSelectedExternalTool() { diff --git a/src/librssguard/gui/settings/settingsbrowsermail.h b/src/librssguard/gui/settings/settingsbrowsermail.h index 6a80aeca5..807ff1556 100644 --- a/src/librssguard/gui/settings/settingsbrowsermail.h +++ b/src/librssguard/gui/settings/settingsbrowsermail.h @@ -24,12 +24,16 @@ class SettingsBrowserMail : public SettingsPanel { private slots: void addExternalTool(); + void editSelectedExternalTool(); void deleteSelectedExternalTool(); void changeDefaultBrowserArguments(int index); void selectBrowserExecutable(); void changeDefaultEmailArguments(int index); void selectEmailExecutable(); + private: + ExternalTool tweakExternalTool(const ExternalTool& tool) const; + private: QList externalTools() const; void setExternalTools(const QList& list); diff --git a/src/librssguard/gui/settings/settingsbrowsermail.ui b/src/librssguard/gui/settings/settingsbrowsermail.ui index e67fcd89c..433480a5f 100644 --- a/src/librssguard/gui/settings/settingsbrowsermail.ui +++ b/src/librssguard/gui/settings/settingsbrowsermail.ui @@ -262,27 +262,6 @@ External tools - - - - - - Add external tool - - - - - - - false - - - Delete selected external tool - - - - - @@ -330,6 +309,37 @@ + + + + + + &Add new external tool + + + + + + + false + + + &Edit selected external tool + + + + + + + false + + + &Delete selected external tool + + + + + @@ -351,6 +361,7 @@ m_cmbExternalEmailPreset m_listTools m_btnAddTool + m_btnEditTool m_btnDeleteTool diff --git a/src/librssguard/gui/webbrowser.cpp b/src/librssguard/gui/webbrowser.cpp index 529bc0cc1..2c164fa2e 100644 --- a/src/librssguard/gui/webbrowser.cpp +++ b/src/librssguard/gui/webbrowser.cpp @@ -2,13 +2,13 @@ #include "gui/webbrowser.h" +#include "database/databasequeries.h" #include "gui/discoverfeedsbutton.h" #include "gui/locationlineedit.h" #include "gui/messagebox.h" #include "gui/searchtextwidget.h" #include "gui/webviewer.h" #include "miscellaneous/application.h" -#include "database/databasequeries.h" #include "miscellaneous/iconfactory.h" #include "network-web/networkfactory.h" #include "network-web/webfactory.h" @@ -118,9 +118,9 @@ void WebBrowser::reloadFontSettings() { fon.fromString(qApp->settings()->value(GROUP(Messages), SETTING(Messages::PreviewerFontStandard)).toString()); - QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::StandardFont, fon.family()); - QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::SerifFont, fon.family()); - QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::SansSerifFont, fon.family()); + QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::FontFamily::StandardFont, fon.family()); + QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::FontFamily::SerifFont, fon.family()); + QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::FontFamily::SansSerifFont, fon.family()); QWebEngineSettings::defaultSettings()->setFontSize(QWebEngineSettings::DefaultFontSize, fon.pointSize()); } diff --git a/src/librssguard/gui/webviewer.cpp b/src/librssguard/gui/webviewer.cpp index 9d3b7093c..666b9844c 100644 --- a/src/librssguard/gui/webviewer.cpp +++ b/src/librssguard/gui/webviewer.cpp @@ -7,12 +7,14 @@ #include "gui/tabwidget.h" #include "gui/webbrowser.h" #include "miscellaneous/application.h" +#include "miscellaneous/externaltool.h" #include "miscellaneous/skinfactory.h" #include "network-web/adblock/adblockicon.h" #include "network-web/adblock/adblockmanager.h" #include "network-web/webfactory.h" #include "network-web/webpage.h" +#include #include #include #include @@ -162,7 +164,7 @@ void WebViewer::contextMenuEvent(QContextMenuEvent* event) { if (menu_data.linkUrl().isValid()) { // Add option to open link in external viewe - menu->addAction(qApp->icons()->fromTheme(QSL("")), tr("Open link in external browser"), [menu_data]() { + menu->addAction(qApp->icons()->fromTheme(QSL("document-open")), tr("Open link in external browser"), [menu_data]() { qApp->web()->openUrlInExternalBrowser(menu_data.linkUrl().toString()); if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::BringAppToFrontAfterMessageOpenedExternally)).toBool()) { @@ -173,6 +175,35 @@ void WebViewer::contextMenuEvent(QContextMenuEvent* event) { }); } + if (menu_data.mediaUrl().isValid() || menu_data.linkUrl().isValid()) { + QFileIconProvider icon_provider; + QMenu* menu_ext_tools = new QMenu(tr("Open with external tool"), menu); + + menu_ext_tools->setIcon(qApp->icons()->fromTheme(QSL("document-open"))); + + for (const ExternalTool& tool : ExternalTool::toolsFromSettings()) { + QAction* act_tool = new QAction(QFileInfo(tool.executable()).fileName(), menu_ext_tools); + + act_tool->setIcon(icon_provider.icon(tool.executable())); + act_tool->setToolTip(tool.executable()); + act_tool->setData(QVariant::fromValue(tool)); + menu_ext_tools->addAction(act_tool); + + connect(act_tool, &QAction::triggered, this, [this, act_tool, menu_data]() { + openUrlWithExternalTool(act_tool->data().value(), menu_data); + }); + } + + if (menu_ext_tools->actions().isEmpty()) { + QAction* act_not_tools = new QAction("No external tools activated"); + + act_not_tools->setEnabled(false); + menu_ext_tools->addAction(act_not_tools); + } + + menu->addMenu(menu_ext_tools); + } + menu->addAction(qApp->web()->adBlock()->adBlockIcon()); menu->addAction(qApp->web()->engineSettingsAction()); @@ -233,6 +264,10 @@ bool WebViewer::eventFilter(QObject* object, QEvent* event) { return false; } +void WebViewer::openUrlWithExternalTool(ExternalTool tool, const QWebEngineContextMenuData& target) { + tool.run(target.mediaUrl().isValid() ? target.mediaUrl().toString() : target.linkUrl().toString()); +} + RootItem* WebViewer::root() const { return m_root; } diff --git a/src/librssguard/gui/webviewer.h b/src/librssguard/gui/webviewer.h index 584a2f95d..30b51c830 100644 --- a/src/librssguard/gui/webviewer.h +++ b/src/librssguard/gui/webviewer.h @@ -6,6 +6,7 @@ #include #include "core/message.h" +#include "miscellaneous/externaltool.h" #include "network-web/webpage.h" class RootItem; @@ -39,6 +40,9 @@ class WebViewer : public QWebEngineView { virtual bool event(QEvent* event); virtual bool eventFilter(QObject* object, QEvent* event); + private slots: + void openUrlWithExternalTool(ExternalTool tool, const QWebEngineContextMenuData& target); + private: RootItem* m_root; QString m_messageContents; diff --git a/src/librssguard/miscellaneous/externaltool.cpp b/src/librssguard/miscellaneous/externaltool.cpp index fca376b7e..ad514d09a 100644 --- a/src/librssguard/miscellaneous/externaltool.cpp +++ b/src/librssguard/miscellaneous/externaltool.cpp @@ -12,27 +12,25 @@ void ExternalTool::sanitizeParameters() { m_executable = QDir::toNativeSeparators(m_executable); - m_parameters.removeDuplicates(); - m_parameters.removeAll(QString()); } ExternalTool::ExternalTool(const ExternalTool& other) : ExternalTool(other.executable(), other.parameters()) {} -ExternalTool::ExternalTool(QString executable, QStringList parameters) +ExternalTool::ExternalTool(QString executable, QString parameters) : m_executable(std::move(executable)), m_parameters(std::move(parameters)) { sanitizeParameters(); } QString ExternalTool::toString() { sanitizeParameters(); - return m_executable + EXTERNAL_TOOL_SEPARATOR + m_parameters.join(EXTERNAL_TOOL_PARAM_SEPARATOR); + return m_executable + EXTERNAL_TOOL_SEPARATOR + m_parameters; } QString ExternalTool::executable() const { return m_executable; } -QStringList ExternalTool::parameters() const { +QString ExternalTool::parameters() const { return m_parameters; } @@ -44,7 +42,7 @@ ExternalTool ExternalTool::fromString(const QString& str) { } else { const QString& executable = outer.at(0); - const QStringList parameters = outer.at(1).split(EXTERNAL_TOOL_PARAM_SEPARATOR); + const QString& parameters = outer.at(1); return ExternalTool(executable, parameters); } @@ -70,3 +68,7 @@ void ExternalTool::setToolsToSettings(QList& tools) { qApp->settings()->setValue(GROUP(Browser), Browser::ExternalTools, encode); } + +bool ExternalTool::run(const QString& target) { + return IOFactory::startProcessDetached(executable(), QStringList() << parameters() << target); +} diff --git a/src/librssguard/miscellaneous/externaltool.h b/src/librssguard/miscellaneous/externaltool.h index ff82bb88d..d570cac25 100644 --- a/src/librssguard/miscellaneous/externaltool.h +++ b/src/librssguard/miscellaneous/externaltool.h @@ -10,19 +10,22 @@ class ExternalTool { public: explicit ExternalTool() = default; ExternalTool(const ExternalTool& other); - explicit ExternalTool(QString executable, QStringList parameters); + explicit ExternalTool(QString executable, QString parameters); QString toString(); QString executable() const; - QStringList parameters() const; + QString parameters() const; + bool run(const QString& target); + + public: static ExternalTool fromString(const QString& str); static QList toolsFromSettings(); static void setToolsToSettings(QList& tools); private: QString m_executable; - QStringList m_parameters; + QString m_parameters; void sanitizeParameters(); }; diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp index 1b7e6e8e2..a061e8eee 100644 --- a/src/librssguard/services/standard/standardfeed.cpp +++ b/src/librssguard/services/standard/standardfeed.cpp @@ -508,7 +508,7 @@ void StandardFeed::setEncoding(const QString& encoding) { } QStringList StandardFeed::prepareExecutionLine(const QString& execution_line) { - auto split_exec = execution_line.split('#', + auto split_exec = execution_line.split(EXECUTION_LINE_SEPARATOR, #if QT_VERSION >= 0x050F00 // Qt >= 5.15.0 Qt::SplitBehaviorFlags::SkipEmptyParts); #else