diff --git a/src/librssguard/gui/dialogs/formupdate.cpp b/src/librssguard/gui/dialogs/formupdate.cpp index 93c2f93a1..e8a4ea214 100644 --- a/src/librssguard/gui/dialogs/formupdate.cpp +++ b/src/librssguard/gui/dialogs/formupdate.cpp @@ -17,8 +17,7 @@ #include #endif -FormUpdate::FormUpdate(QWidget* parent) - : QDialog(parent) { +FormUpdate::FormUpdate(QWidget* parent) : QDialog(parent) { m_ui.setupUi(this); m_ui.m_lblCurrentRelease->setText(QSL(APP_VERSION)); m_ui.m_tabInfo->removeTab(1); @@ -35,7 +34,8 @@ FormUpdate::FormUpdate(QWidget* parent) m_btnUpdate->setToolTip(tr("Download new installation files.")); } else { - m_btnUpdate = m_ui.m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ButtonRole::ActionRole); + m_btnUpdate = + m_ui.m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ButtonRole::ActionRole); m_btnUpdate->setToolTip(tr("Go to application website to get update packages manually.")); } @@ -57,49 +57,49 @@ void FormUpdate::checkForUpdates() { &SystemFactory::updatesChecked, this, [this](const QPair, QNetworkReply::NetworkError>& update) { - m_ui.m_buttonBox->setEnabled(true); - disconnect(qApp->system(), &SystemFactory::updatesChecked, nullptr, nullptr); + m_ui.m_buttonBox->setEnabled(true); + disconnect(qApp->system(), &SystemFactory::updatesChecked, nullptr, nullptr); - if (update.second != QNetworkReply::NoError) { - m_updateInfo = UpdateInfo(); - m_ui.m_tabInfo->setEnabled(false); + if (update.second != QNetworkReply::NoError) { + m_updateInfo = UpdateInfo(); + m_ui.m_tabInfo->setEnabled(false); - //: Unknown release. - m_ui.m_lblAvailableRelease->setText(tr("unknown")); - m_ui.m_txtChanges->clear(); - m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Error, - tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)), - tr("List with updates was not\ndownloaded successfully.")); - } - else { - const bool self_update_supported = isSelfUpdateSupported(); - m_updateInfo = update.first.at(0); - m_ui.m_tabInfo->setEnabled(true); - m_ui.m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion); + //: Unknown release. + m_ui.m_lblAvailableRelease->setText(tr("unknown")); + m_ui.m_txtChanges->clear(); + m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Error, + tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)), + tr("List with updates was not\ndownloaded successfully.")); + } + else { + const bool self_update_supported = isSelfUpdateSupported(); + m_updateInfo = update.first.at(0); + m_ui.m_tabInfo->setEnabled(true); + m_ui.m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion); #if QT_VERSION >= 0x050E00 // Qt >= 5.14.0 - m_ui.m_txtChanges->setMarkdown(m_updateInfo.m_changes); + m_ui.m_txtChanges->setMarkdown(m_updateInfo.m_changes); #else m_ui.m_txtChanges->setText(m_updateInfo.m_changes); #endif - if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, QSL(APP_VERSION))) { - m_btnUpdate->setVisible(true); - m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Ok, - tr("New release available."), - tr("This is new version which can be\ndownloaded.")); + if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, QSL(APP_VERSION))) { + m_btnUpdate->setVisible(true); + m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Ok, + tr("New release available."), + tr("This is new version which can be\ndownloaded.")); - if (self_update_supported) { - loadAvailableFiles(); - } - } - else { - m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Warning, - tr("No new release available."), - tr("This release is not newer than\ncurrently installed one.")); - } - } - }); + if (self_update_supported) { + loadAvailableFiles(); + } + } + else { + m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Warning, + tr("No new release available."), + tr("This release is not newer than\ncurrently installed one.")); + } + } + }); qApp->system()->checkForUpdates(); } @@ -107,14 +107,11 @@ void FormUpdate::checkForUpdates() { void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) { if (bytes_received - m_lastDownloadedBytes > 500000 || m_lastDownloadedBytes == 0) { m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Information, - tr("Downloaded %1% (update size is %2 kB).").arg(QString::number(bytes_total == 0L - ? 0L - : (bytes_received * 100.0) / bytes_total, - 'f', - 2), - QString::number(bytes_total / 1000.0, - 'f', - 2)), + tr("Downloaded %1% (update size is %2 kB).") + .arg(QString::number(bytes_total == 0L ? 0L : (bytes_received * 100.0) / bytes_total, + 'f', + 2), + QString::number(bytes_total / 1000.0, 'f', 2)), tr("Downloading update...")); m_ui.m_lblStatus->repaint(); m_lastDownloadedBytes = bytes_received; @@ -140,9 +137,7 @@ void FormUpdate::saveUpdateFile(const QByteArray& file_contents) { m_readyToInstall = true; } else { - qDebugNN << LOGSEC_GUI - << "Cannot save downloaded update file because target temporary file '" - << output_file_name + qDebugNN << LOGSEC_GUI << "Cannot save downloaded update file because target temporary file '" << output_file_name << "' cannot be opened for writing."; } } @@ -175,21 +170,24 @@ void FormUpdate::loadAvailableFiles() { m_ui.m_tabInfo->setCurrentIndex(1); } -void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, const QByteArray& contents) { - qDebugNN << LOGSEC_GUI - << "Download of application update file was completed with code '" << status << "'."; +void FormUpdate::updateCompleted(const QUrl& url, QNetworkReply::NetworkError status, const QByteArray& contents) { + Q_UNUSED(url) + + qDebugNN << LOGSEC_GUI << "Download of application update file was completed with code" << QUOTE_W_SPACE_DOT(status); switch (status) { case QNetworkReply::NetworkError::NoError: saveUpdateFile(contents); - m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Ok, tr("Downloaded successfully"), + m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Ok, + tr("Downloaded successfully"), tr("Package was downloaded successfully.\nYou can install it now.")); m_btnUpdate->setText(tr("Install")); m_btnUpdate->setEnabled(true); break; default: - m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Error, tr("Error occured"), + m_ui.m_lblStatus->setStatus(WidgetWithStatus::StatusType::Error, + tr("Error occured"), tr("Error occured during downloading of the package.")); m_btnUpdate->setText(tr("Error occured")); break; @@ -210,32 +208,32 @@ void FormUpdate::startUpdate() { if (m_readyToInstall) { close(); - qDebugNN << LOGSEC_GUI - << "Preparing to launch external installer '" - << QDir::toNativeSeparators(m_updateFilePath) + qDebugNN << LOGSEC_GUI << "Preparing to launch external installer '" << QDir::toNativeSeparators(m_updateFilePath) << "'."; #if defined(Q_OS_WIN) - HINSTANCE exec_result = ShellExecute(nullptr, - nullptr, - reinterpret_cast(QDir::toNativeSeparators(m_updateFilePath).utf16()), - nullptr, - nullptr, - SW_NORMAL); + HINSTANCE exec_result = + ShellExecute(nullptr, + nullptr, + reinterpret_cast(QDir::toNativeSeparators(m_updateFilePath).utf16()), + nullptr, + nullptr, + SW_NORMAL); if (exec_result <= HINSTANCE(32)) { qDebugNN << LOGSEC_GUI << "External updater was not launched due to error."; - qApp->showGuiMessage(Notification::Event::GeneralEvent, { - tr("Cannot update application"), - tr("Cannot launch external updater. Update application manually."), - QSystemTrayIcon::MessageIcon::Warning }, - {}, {}, this); + qApp->showGuiMessage(Notification::Event::GeneralEvent, + {tr("Cannot update application"), + tr("Cannot launch external updater. Update application manually."), + QSystemTrayIcon::MessageIcon::Warning}, + {}, + {}, + this); } else { qApp->quit(); } #endif - } else if (update_for_this_system) { updateProgress(0, 100); diff --git a/src/librssguard/gui/dialogs/formupdate.h b/src/librssguard/gui/dialogs/formupdate.h index 4b27460fc..8c64311a1 100644 --- a/src/librssguard/gui/dialogs/formupdate.h +++ b/src/librssguard/gui/dialogs/formupdate.h @@ -32,7 +32,7 @@ class RSSGUARD_DLLSPEC FormUpdate : public QDialog { void startUpdate(); void updateProgress(qint64 bytes_received, qint64 bytes_total); - void updateCompleted(QNetworkReply::NetworkError status, const QByteArray& contents); + void updateCompleted(const QUrl &url, QNetworkReply::NetworkError status, const QByteArray& contents); void saveUpdateFile(const QByteArray& file_contents); private: diff --git a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp index 96b1bbe6f..25427225b 100644 --- a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp +++ b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp @@ -27,8 +27,16 @@ TextBrowserViewer::TextBrowserViewer(QWidget* parent) setOpenLinks(false); viewport()->setAutoFillBackground(true); + m_document.data()->setResourcesEnabled(qApp->settings() + ->value(GROUP(Messages), SETTING(Messages::ShowResourcesInArticles)) + .toBool()); + setDocument(m_document.data()); + connect(m_document.data(), &TextBrowserDocument::reloadDocument, this, [this]() { + setHtmlPrivate(html(), m_currentUrl); + }); + connect(this, &QTextBrowser::anchorClicked, this, &TextBrowserViewer::onAnchorClicked); connect(this, QOverload::of(&QTextBrowser::highlighted), this, &TextBrowserViewer::linkMouseHighlighted); } @@ -264,24 +272,27 @@ void TextBrowserViewer::contextMenuEvent(QContextMenuEvent* event) { return; } - if (m_actionReloadWithImages.isNull()) { - m_actionReloadWithImages.reset(new QAction(qApp->icons()->fromTheme(QSL("viewimage"), QSL("view-refresh")), - tr("Reload with images"), - this)); + if (m_actionEnableResources.isNull()) { + m_actionEnableResources.reset(new QAction(qApp->icons()->fromTheme(QSL("viewimage"), QSL("image-x-generic")), + tr("Enable external resources"), + this)); m_actionOpenExternalBrowser.reset(new QAction(qApp->icons()->fromTheme(QSL("document-open")), tr("Open in external browser"), this)); m_actionDownloadLink.reset(new QAction(qApp->icons()->fromTheme(QSL("download")), tr("Download"), this)); - connect(m_actionReloadWithImages.data(), &QAction::triggered, this, &TextBrowserViewer::reloadWithImages); + m_actionEnableResources.data()->setCheckable(true); + m_actionEnableResources.data()->setChecked(m_document.data()->resourcesEnabled()); + connect(m_actionOpenExternalBrowser.data(), &QAction::triggered, this, &TextBrowserViewer::openLinkInExternalBrowser); connect(m_actionDownloadLink.data(), &QAction::triggered, this, &TextBrowserViewer::downloadLink); + connect(m_actionEnableResources.data(), &QAction::toggled, this, &TextBrowserViewer::enableResources); } - menu->addAction(m_actionReloadWithImages.data()); + menu->addAction(m_actionEnableResources.data()); menu->addAction(m_actionOpenExternalBrowser.data()); menu->addAction(m_actionDownloadLink.data()); @@ -340,34 +351,9 @@ void TextBrowserViewer::wheelEvent(QWheelEvent* event) { updateMicroFocus(); } -void TextBrowserViewer::reloadWithImages() { - m_document.data()->m_reloadingWithResources = true; - m_document.data()->m_loadedResources.clear(); - - QEventLoop loop; - - for (const QUrl& url : m_document.data()->m_neededResourcesForHtml) { - if (m_document.data()->m_loadedResources.contains(url)) { - continue; - } - - QUrl resolved_url = m_currentUrl.resolved(url); - - connect(m_downloader.data(), &Downloader::completed, &loop, &QEventLoop::quit); - m_downloader->manipulateData(resolved_url.toString(), QNetworkAccessManager::Operation::GetOperation, {}, 5000); - - loop.exec(); - - if (m_downloader->lastOutputError() == QNetworkReply::NetworkError::NoError) { - m_document.data()->m_loadedResources.insert(url, m_downloader->lastOutputData()); - } - } - - auto scrolled = verticalScrollBarPosition(); - - setHtmlPrivate(html(), m_currentUrl); - - setVerticalScrollBarPosition(scrolled); +void TextBrowserViewer::enableResources(bool enable) { + qApp->settings()->setValue(GROUP(Messages), Messages::ShowResourcesInArticles, enable); + m_document.data()->setResourcesEnabled(enable); } void TextBrowserViewer::openLinkInExternalBrowser() { @@ -411,9 +397,9 @@ void TextBrowserViewer::onAnchorClicked(const QUrl& url) { } void TextBrowserViewer::setHtml(const QString& html, const QUrl& base_url) { - m_document.data()->m_reloadingWithResources = false; - m_document.data()->m_loadedResources.clear(); - m_document.data()->m_neededResourcesForHtml.clear(); + m_document.data()->m_resourceTimer.stop(); + m_document.data()->m_neededResources.clear(); + m_document.data()->m_resourceTimer.start(); setHtmlPrivate(html, base_url); @@ -431,12 +417,7 @@ void TextBrowserViewer::setHtml(const QString& html, const QUrl& base_url) { void TextBrowserViewer::setHtmlPrivate(const QString& html, const QUrl& base_url) { m_currentUrl = base_url; - if (!m_document.data()->m_reloadingWithResources) { - m_document.data()->m_neededResourcesForHtml.clear(); - } - QTextBrowser::setHtml(html); - setZoomFactor(m_zoomFactor); emit pageTitleChanged(documentTitle()); @@ -444,21 +425,76 @@ void TextBrowserViewer::setHtmlPrivate(const QString& html, const QUrl& base_url } TextBrowserDocument::TextBrowserDocument(QObject* parent) - : QTextDocument(parent), m_reloadingWithResources(false), - m_placeholderImage(qApp->icons()->miscPixmap("image-placeholder")) {} + : QTextDocument(parent), m_resourcesEnabled(false), m_resourceDownloader(new Downloader(this)), + m_placeholderImage(qApp->icons()->miscPixmap("image-placeholder")) { + + connect(&m_resourceTimer, &QTimer::timeout, this, &TextBrowserDocument::reloadHtmlDelayed); + connect(m_resourceDownloader.data(), &Downloader::completed, this, &TextBrowserDocument::resourceDownloaded); + + m_resourceTimer.setSingleShot(false); + m_resourceTimer.setInterval(300); +} QVariant TextBrowserDocument::loadResource(int type, const QUrl& name) { - if (!m_reloadingWithResources) { - if (type == QTextDocument::ResourceType::ImageResource && !m_neededResourcesForHtml.contains(name)) { - m_neededResourcesForHtml.append(name); + if (type != QTextDocument::ResourceType::ImageResource) { + return {}; + } + + if (!m_resourcesEnabled) { + // Resources are not enabled. + return m_placeholderImage; + } + + if (m_loadedResources.contains(name)) { + // Resources are enabled and we already have the resource. + return QImage::fromData(m_loadedResources.value(name)); + } + else { + // Resources are not enabled and we need to download the resource. + if (!m_neededResources.contains(name) && m_resourceTimer.isActive()) { + m_neededResources.append(name); + m_resourceTimer.start(); } return m_placeholderImage; } - else if (m_loadedResources.contains(name)) { - return QImage::fromData(m_loadedResources.value(name)); - } - else { - return m_placeholderImage; +} + +void TextBrowserDocument::reloadHtmlDelayed() { + // Timer has elapsed, we do not wait for other resources, + // we download what we know about. + m_resourceTimer.stop(); + + if (!m_neededResources.isEmpty()) { + downloadNextNeededResource(); } } + +void TextBrowserDocument::downloadNextNeededResource() { + if (m_neededResources.isEmpty()) { + // Everything is downloaded. + emit reloadDocument(); + } + else { + m_resourceDownloader.data()->manipulateData(m_neededResources.takeFirst().toString(), + QNetworkAccessManager::Operation::GetOperation, + {}, + 5000); + } +} + +void TextBrowserDocument::resourceDownloaded(const QUrl& url, QNetworkReply::NetworkError status, QByteArray contents) { + if (status == QNetworkReply::NetworkError::NoError && !m_loadedResources.contains(url)) { + m_loadedResources.insert(url, contents); + } + + downloadNextNeededResource(); +} + +bool TextBrowserDocument::resourcesEnabled() const { + return m_resourcesEnabled; +} + +void TextBrowserDocument::setResourcesEnabled(bool enabled) { + m_resourcesEnabled = enabled; +} diff --git a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h index 3cf175a7d..47b6eafcb 100644 --- a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h +++ b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h @@ -9,8 +9,10 @@ #include "network-web/adblock/adblockmanager.h" +#include #include #include +#include class QContextMenuEvent; class QResizeEvent; @@ -25,12 +27,26 @@ class TextBrowserDocument : public QTextDocument { public: explicit TextBrowserDocument(QObject* parent = nullptr); + bool resourcesEnabled() const; + void setResourcesEnabled(bool enabled); + protected: virtual QVariant loadResource(int type, const QUrl& name); + signals: + void loadingProgress(int progress); + void reloadDocument(); + + private slots: + void reloadHtmlDelayed(); + void downloadNextNeededResource(); + void resourceDownloaded(const QUrl& url, QNetworkReply::NetworkError status, QByteArray contents = QByteArray()); + private: - bool m_reloadingWithResources; - QList m_neededResourcesForHtml; + bool m_resourcesEnabled; + QTimer m_resourceTimer; + QList m_neededResources; + QScopedPointer m_resourceDownloader; QMap m_loadedResources; QPixmap m_placeholderImage; }; @@ -65,7 +81,7 @@ class TextBrowserViewer : public QTextBrowser, public WebViewer { virtual void wheelEvent(QWheelEvent* event); private slots: - void reloadWithImages(); + void enableResources(bool enable); void openLinkInExternalBrowser(); void downloadLink(); void onAnchorClicked(const QUrl& url); @@ -93,7 +109,7 @@ class TextBrowserViewer : public QTextBrowser, public WebViewer { QPointer m_root; QFont m_baseFont; qreal m_zoomFactor = 1.0; - QScopedPointer m_actionReloadWithImages; + QScopedPointer m_actionEnableResources; QScopedPointer m_actionOpenExternalBrowser; QScopedPointer m_actionDownloadLink; QScopedPointer m_document; diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp index 8833dfa80..bfe516dc1 100644 --- a/src/librssguard/miscellaneous/settings.cpp +++ b/src/librssguard/miscellaneous/settings.cpp @@ -49,11 +49,10 @@ DKEY AdBlock::AdBlockEnabled = "enabled"; DVALUE(bool) AdBlock::AdBlockEnabledDef = false; DKEY AdBlock::FilterLists = "filter_lists"; -DVALUE(QStringList) AdBlock::FilterListsDef = { - QSL("https://easylist.to/easylist/easylist.txt"), - QSL("https://easylist.to/easylist/easyprivacy.txt"), - QSL("https://easylist.to/easylist/fanboy-social.txt") -}; +DVALUE(QStringList) +AdBlock::FilterListsDef = {QSL("https://easylist.to/easylist/easylist.txt"), + QSL("https://easylist.to/easylist/easyprivacy.txt"), + QSL("https://easylist.to/easylist/fanboy-social.txt")}; DKEY AdBlock::CustomFilters = "custom_filters"; DVALUE(QStringList) AdBlock::CustomFiltersDef = {}; @@ -117,6 +116,9 @@ DVALUE(bool) Messages::DisplayEnclosuresInMessageDef = false; DKEY Messages::EnableMessagePreview = "enable_message_preview"; DVALUE(bool) Messages::EnableMessagePreviewDef = true; +DKEY Messages::ShowResourcesInArticles = "enable_message_resources"; +DVALUE(bool) Messages::ShowResourcesInArticlesDef = false; + DKEY Messages::Zoom = "zoom"; DVALUE(qreal) Messages::ZoomDef = double(1.0); @@ -207,11 +209,14 @@ DKEY GUI::HeightRowFeeds = "height_row_feeds"; DVALUE(int) GUI::HeightRowFeedsDef = -1; DKEY GUI::FeedsToolbarActions = "feeds_toolbar"; -DVALUE(char*) GUI::FeedsToolbarActionsDef = "m_actionUpdateAllItems,m_actionStopRunningItemsUpdate,m_actionMarkAllItemsRead,spacer,search"; +DVALUE(char*) +GUI::FeedsToolbarActionsDef = + "m_actionUpdateAllItems,m_actionStopRunningItemsUpdate,m_actionMarkAllItemsRead,spacer,search"; DKEY GUI::StatusbarActions = "status_bar"; -DVALUE(char*) GUI::StatusbarActionsDef = - "m_barProgressDownloadAction,m_barProgressFeedsAction,m_actionUpdateAllItems,m_actionUpdateSelectedItems,m_actionStopRunningItemsUpdate,m_actionFullscreen,m_actionQuit"; +DVALUE(char*) +GUI::StatusbarActionsDef = "m_barProgressDownloadAction,m_barProgressFeedsAction,m_actionUpdateAllItems,m_" + "actionUpdateSelectedItems,m_actionStopRunningItemsUpdate,m_actionFullscreen,m_actionQuit"; DKEY GUI::SettingsWindowInitialSize = "settings_window_size"; DKEY GUI::MainWindowInitialSize = "window_size"; @@ -283,8 +288,10 @@ DKEY GUI::HideTabBarIfOnlyOneTab = "hide_tabbar_one_tab"; DVALUE(bool) GUI::HideTabBarIfOnlyOneTabDef = false; DKEY GUI::MessagesToolbarDefaultButtons = "messages_toolbar"; -DVALUE(char*) GUI::MessagesToolbarDefaultButtonsDef = - "m_actionMarkSelectedMessagesAsRead,m_actionMarkSelectedMessagesAsUnread,m_actionSwitchImportanceOfSelectedMessages,separator,highlighter,filter,spacer,search"; +DVALUE(char*) +GUI::MessagesToolbarDefaultButtonsDef = + "m_actionMarkSelectedMessagesAsRead,m_actionMarkSelectedMessagesAsUnread,m_actionSwitchImportanceOfSelectedMessages," + "separator,highlighter,filter,spacer,search"; DKEY GUI::DefaultSortColumnFeeds = "default_sort_column_feeds"; DVALUE(int) GUI::DefaultSortColumnFeedsDef = FDS_MODEL_TITLE_INDEX; @@ -451,8 +458,8 @@ QSettings::Status Settings::checkSettings() { bool Settings::initiateRestoration(const QString& settings_backup_file_path) { return IOFactory::copyFile(settings_backup_file_path, - QFileInfo(fileName()).absolutePath() + QDir::separator() + - BACKUP_NAME_SETTINGS + BACKUP_SUFFIX_SETTINGS); + QFileInfo(fileName()).absolutePath() + QDir::separator() + BACKUP_NAME_SETTINGS + + BACKUP_SUFFIX_SETTINGS); } void Settings::finishRestoration(const QString& desired_settings_file_path) { @@ -460,9 +467,7 @@ void Settings::finishRestoration(const QString& desired_settings_file_path) { BACKUP_NAME_SETTINGS + BACKUP_SUFFIX_SETTINGS; if (QFile::exists(backup_settings_file)) { - qWarningNN << LOGSEC_CORE - << "Backup settings file" - << QUOTE_W_SPACE(QDir::toNativeSeparators(backup_settings_file)) + qWarningNN << LOGSEC_CORE << "Backup settings file" << QUOTE_W_SPACE(QDir::toNativeSeparators(backup_settings_file)) << "was detected. Restoring it."; if (IOFactory::copyFile(backup_settings_file, desired_settings_file_path)) { @@ -489,22 +494,16 @@ Settings* Settings::setupSettings(QObject* parent) { new_settings = new Settings(properties.m_absoluteSettingsFileName, QSettings::IniFormat, properties.m_type, parent); if (properties.m_type == SettingsProperties::SettingsType::Portable) { - qDebugNN << LOGSEC_CORE - << "Initializing settings in" - << QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)) - << "(portable way)."; + qDebugNN << LOGSEC_CORE << "Initializing settings in" + << QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)) << "(portable way)."; } else if (properties.m_type == SettingsProperties::SettingsType::Custom) { - qDebugNN << LOGSEC_CORE - << "Initializing settings in" - << QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)) - << "(custom way)."; + qDebugNN << LOGSEC_CORE << "Initializing settings in" + << QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)) << "(custom way)."; } else { - qDebugNN << LOGSEC_CORE - << "Initializing settings in" - << QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)) - << "(non-portable way)."; + qDebugNN << LOGSEC_CORE << "Initializing settings in" + << QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)) << "(non-portable way)."; } return new_settings; diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h index bbd5a499a..250a9c894 100644 --- a/src/librssguard/miscellaneous/settings.h +++ b/src/librssguard/miscellaneous/settings.h @@ -22,8 +22,8 @@ #define NON_CONST_VALUE(x) extern x #define DVALUE(x) const x #define NON_CONST_DVALUE(x) x -#define SETTING(x) x, x ## Def -#define DEFAULT_VALUE(x) x ## Def +#define SETTING(x) x, x##Def +#define DEFAULT_VALUE(x) x##Def #define GROUP(x) x::ID #if defined(USE_WEBENGINE) @@ -47,7 +47,7 @@ namespace Node { KEY PackageFolder; VALUE(QString) PackageFolderDef; -} +} // namespace Node namespace AdBlock { KEY ID; @@ -60,7 +60,7 @@ namespace AdBlock { KEY CustomFilters; VALUE(QStringList) CustomFiltersDef; -} +} // namespace AdBlock // Feeds. namespace Feeds { @@ -109,7 +109,7 @@ namespace Feeds { VALUE(bool) OnlyBasicShortcutsInListsDef; KEY ListFont; -} +} // namespace Feeds // Messages. namespace Messages { @@ -124,6 +124,9 @@ namespace Messages { KEY EnableMessagePreview; VALUE(bool) EnableMessagePreviewDef; + KEY ShowResourcesInArticles; + VALUE(bool) ShowResourcesInArticlesDef; + KEY Zoom; VALUE(qreal) ZoomDef; @@ -176,7 +179,7 @@ namespace Messages { NON_CONST_VALUE(QString) PreviewerFontStandardDef; KEY ListFont; -} +} // namespace Messages // Custom skin colors. namespace CustomSkinColors { @@ -186,7 +189,7 @@ namespace CustomSkinColors { VALUE(bool) EnabledDef; KEY CustomSkinColors; -} +} // namespace CustomSkinColors // GUI. namespace GUI { @@ -311,7 +314,7 @@ namespace GUI { KEY Style; VALUE(char*) StyleDef; -} +} // namespace GUI // General. namespace General { @@ -325,7 +328,7 @@ namespace General { KEY Language; VALUE(QString) LanguageDef; -} +} // namespace General // Downloads. namespace Downloads { @@ -353,7 +356,7 @@ namespace Downloads { KEY ItemUrl; KEY ItemLocation; KEY ItemDone; -} +} // namespace Downloads // Proxy. namespace Proxy { @@ -377,7 +380,7 @@ namespace Proxy { KEY Port; VALUE(int) PortDef; -} +} // namespace Proxy // Database. namespace Database { @@ -413,7 +416,7 @@ namespace Database { KEY ActiveDriver; VALUE(char*) ActiveDriverDef; -} +} // namespace Database // Keyboard. namespace Keyboard { @@ -463,7 +466,7 @@ namespace Browser { KEY CustomExternalEmailArguments; VALUE(char*) CustomExternalEmailArgumentsDef; -} +} // namespace Browser // Categories. namespace CategoriesExpandStates { @@ -471,10 +474,9 @@ namespace CategoriesExpandStates { } class Settings : public QSettings { - Q_OBJECT + Q_OBJECT public: - // Destructor. virtual ~Settings(); @@ -510,9 +512,11 @@ class Settings : public QSettings { static SettingsProperties determineProperties(); private: - // Constructor. - explicit Settings(const QString& file_name, Format format, SettingsProperties::SettingsType type, QObject* parent = nullptr); + explicit Settings(const QString& file_name, + Format format, + SettingsProperties::SettingsType type, + QObject* parent = nullptr); SettingsProperties::SettingsType m_initializationStatus; }; diff --git a/src/librssguard/network-web/downloader.cpp b/src/librssguard/network-web/downloader.cpp index c1a94280b..66cdfab74 100644 --- a/src/librssguard/network-web/downloader.cpp +++ b/src/librssguard/network-web/downloader.cpp @@ -16,9 +16,9 @@ Downloader::Downloader(QObject* parent) : QObject(parent), m_activeReply(nullptr), m_downloadManager(new SilentNetworkAccessManager(this)), - m_timer(new QTimer(this)), m_inputData(QByteArray()), - m_inputMultipartData(nullptr), m_targetProtected(false), m_targetUsername(QString()), m_targetPassword(QString()), - m_lastOutputData(QByteArray()), m_lastOutputError(QNetworkReply::NoError) { + m_timer(new QTimer(this)), m_inputData(QByteArray()), m_inputMultipartData(nullptr), m_targetProtected(false), + m_targetUsername(QString()), m_targetPassword(QString()), m_lastOutputData(QByteArray()), + m_lastOutputError(QNetworkReply::NoError) { m_timer->setInterval(DOWNLOAD_TIMEOUT); m_timer->setSingleShot(true); @@ -32,25 +32,52 @@ Downloader::~Downloader() { qDebugNN << LOGSEC_NETWORK << "Destroying Downloader instance."; } -void Downloader::downloadFile(const QString& url, int timeout, bool protected_contents, const QString& username, +void Downloader::downloadFile(const QString& url, + int timeout, + bool protected_contents, + const QString& username, const QString& password) { - manipulateData(url, QNetworkAccessManager::GetOperation, QByteArray(), timeout, - protected_contents, username, password); + manipulateData(url, + QNetworkAccessManager::GetOperation, + QByteArray(), + timeout, + protected_contents, + username, + password); } -void Downloader::uploadFile(const QString& url, const QByteArray& data, int timeout, - bool protected_contents, const QString& username, const QString& password) { - manipulateData(url, QNetworkAccessManager::Operation::PostOperation, data, timeout, protected_contents, username, password); +void Downloader::uploadFile(const QString& url, + const QByteArray& data, + int timeout, + bool protected_contents, + const QString& username, + const QString& password) { + manipulateData(url, + QNetworkAccessManager::Operation::PostOperation, + data, + timeout, + protected_contents, + username, + password); } -void Downloader::manipulateData(const QString& url, QNetworkAccessManager::Operation operation, - QHttpMultiPart* multipart_data, int timeout, - bool protected_contents, const QString& username, const QString& password) { +void Downloader::manipulateData(const QString& url, + QNetworkAccessManager::Operation operation, + QHttpMultiPart* multipart_data, + int timeout, + bool protected_contents, + const QString& username, + const QString& password) { manipulateData(url, operation, QByteArray(), multipart_data, timeout, protected_contents, username, password); } -void Downloader::manipulateData(const QString& url, QNetworkAccessManager::Operation operation, const QByteArray& data, - int timeout, bool protected_contents, const QString& username, const QString& password) { +void Downloader::manipulateData(const QString& url, + QNetworkAccessManager::Operation operation, + const QByteArray& data, + int timeout, + bool protected_contents, + const QString& username, + const QString& password) { manipulateData(url, operation, data, nullptr, timeout, protected_contents, username, password); } @@ -123,20 +150,13 @@ void Downloader::finished() { // Setup redirection URL and download again. QNetworkRequest request = reply->request(); - qWarningNN << LOGSEC_NETWORK - << "Network layer indicates HTTP redirection is needed."; - qWarningNN << LOGSEC_NETWORK - << "Origin URL:" - << QUOTE_W_SPACE_DOT(request.url().toString()); - qWarningNN << LOGSEC_NETWORK - << "Proposed redirection URL:" - << QUOTE_W_SPACE_DOT(redirection_url.toString()); + qWarningNN << LOGSEC_NETWORK << "Network layer indicates HTTP redirection is needed."; + qWarningNN << LOGSEC_NETWORK << "Origin URL:" << QUOTE_W_SPACE_DOT(request.url().toString()); + qWarningNN << LOGSEC_NETWORK << "Proposed redirection URL:" << QUOTE_W_SPACE_DOT(redirection_url.toString()); redirection_url = request.url().resolved(redirection_url); - qWarningNN << LOGSEC_NETWORK - << "Resolved redirection URL:" - << QUOTE_W_SPACE_DOT(redirection_url.toString()); + qWarningNN << LOGSEC_NETWORK << "Resolved redirection URL:" << QUOTE_W_SPACE_DOT(redirection_url.toString()); request.setUrl(redirection_url); @@ -191,7 +211,7 @@ void Downloader::finished() { m_inputMultipartData->deleteLater(); } - emit completed(m_lastOutputError, m_lastOutputData); + emit completed(reply->url(), m_lastOutputError, m_lastOutputData); } } @@ -237,9 +257,8 @@ QList Downloader::decodeMultipartAnswer(QNetworkReply* reply) { int start_of_headers = http_response_str.indexOf(QRegularExpression(QSL("\\r\\r?\\n")), start_of_http); int start_of_body = http_response_str.indexOf(QRegularExpression(QSL("(\\r\\r?\\n){2,}")), start_of_headers + 2); QString body = http_response_str.mid(start_of_body); - QString headers = http_response_str.mid(start_of_headers, - start_of_body - start_of_headers).replace(QRegularExpression(QSL("[\\n\\r]+")), - QSL("\n")); + QString headers = http_response_str.mid(start_of_headers, start_of_body - start_of_headers) + .replace(QRegularExpression(QSL("[\\n\\r]+")), QSL("\n")); auto header_lines = headers.split(QL1C('\n'), #if QT_VERSION >= 0x050F00 // Qt >= 5.15.0 @@ -312,11 +331,8 @@ QVariant Downloader::lastContentType() const { } void Downloader::setProxy(const QNetworkProxy& proxy) { - qWarningNN << LOGSEC_NETWORK - << "Setting specific downloader proxy, address:" - << QUOTE_W_SPACE_COMMA(proxy.hostName()) - << " type:" - << QUOTE_W_SPACE_DOT(proxy.type()); + qWarningNN << LOGSEC_NETWORK << "Setting specific downloader proxy, address:" << QUOTE_W_SPACE_COMMA(proxy.hostName()) + << " type:" << QUOTE_W_SPACE_DOT(proxy.type()); m_downloadManager->setProxy(proxy); } diff --git a/src/librssguard/network-web/downloader.h b/src/librssguard/network-web/downloader.h index a275fe14d..05890c14e 100644 --- a/src/librssguard/network-web/downloader.h +++ b/src/librssguard/network-web/downloader.h @@ -17,7 +17,7 @@ class SilentNetworkAccessManager; class QTimer; class Downloader : public QObject { - Q_OBJECT + Q_OBJECT public: explicit Downloader(QObject* parent = nullptr); @@ -38,28 +38,39 @@ class Downloader : public QObject { void appendRawHeader(const QByteArray& name, const QByteArray& value); // Performs asynchronous download of given file. Redirections are handled. - void downloadFile(const QString& url, int timeout = DOWNLOAD_TIMEOUT, bool protected_contents = false, - const QString& username = QString(), const QString& password = QString()); + void downloadFile(const QString& url, + int timeout = DOWNLOAD_TIMEOUT, + bool protected_contents = false, + const QString& username = QString(), + const QString& password = QString()); - void uploadFile(const QString& url, const QByteArray& data, int timeout = DOWNLOAD_TIMEOUT, - bool protected_contents = false, const QString& username = QString(), + void uploadFile(const QString& url, + const QByteArray& data, + int timeout = DOWNLOAD_TIMEOUT, + bool protected_contents = false, + const QString& username = QString(), const QString& password = QString()); - void manipulateData(const QString& url, QNetworkAccessManager::Operation operation, + void manipulateData(const QString& url, + QNetworkAccessManager::Operation operation, QHttpMultiPart* multipart_data, - int timeout = DOWNLOAD_TIMEOUT, bool protected_contents = false, - const QString& username = QString(), const QString& password = QString()); + int timeout = DOWNLOAD_TIMEOUT, + bool protected_contents = false, + const QString& username = QString(), + const QString& password = QString()); - void manipulateData(const QString& url, QNetworkAccessManager::Operation operation, + void manipulateData(const QString& url, + QNetworkAccessManager::Operation operation, const QByteArray& data = QByteArray(), - int timeout = DOWNLOAD_TIMEOUT, bool protected_contents = false, - const QString& username = QString(), const QString& password = QString()); + int timeout = DOWNLOAD_TIMEOUT, + bool protected_contents = false, + const QString& username = QString(), + const QString& password = QString()); signals: - // Emitted when new progress is known. void progress(qint64 bytes_received, qint64 bytes_total); - void completed(QNetworkReply::NetworkError status, QByteArray contents = QByteArray()); + void completed(const QUrl& url, QNetworkReply::NetworkError status, QByteArray contents = QByteArray()); private slots: @@ -72,10 +83,14 @@ class Downloader : public QObject { private: void setCustomPropsToReply(QNetworkReply* reply); QList decodeMultipartAnswer(QNetworkReply* reply); - void manipulateData(const QString& url, QNetworkAccessManager::Operation operation, - const QByteArray& data, QHttpMultiPart* multipart_data, - int timeout = DOWNLOAD_TIMEOUT, bool protected_contents = false, - const QString& username = QString(), const QString& password = QString()); + void manipulateData(const QString& url, + QNetworkAccessManager::Operation operation, + const QByteArray& data, + QHttpMultiPart* multipart_data, + int timeout = DOWNLOAD_TIMEOUT, + bool protected_contents = false, + const QString& username = QString(), + const QString& password = QString()); void runDeleteRequest(const QNetworkRequest& request); void runPutRequest(const QNetworkRequest& request, const QByteArray& data); void runPostRequest(const QNetworkRequest& request, QHttpMultiPart* multipart_data); diff --git a/src/librssguard/network-web/googlesuggest.cpp b/src/librssguard/network-web/googlesuggest.cpp index e07cae4c7..a8f1c9196 100644 --- a/src/librssguard/network-web/googlesuggest.cpp +++ b/src/librssguard/network-web/googlesuggest.cpp @@ -44,7 +44,8 @@ #include GoogleSuggest::GoogleSuggest(LocationLineEdit* editor, QObject* parent) - : QObject(parent), editor(editor), m_downloader(new Downloader(this)), popup(new QListWidget()), m_enteredText(QString()) { + : QObject(parent), editor(editor), m_downloader(new Downloader(this)), popup(new QListWidget()), + m_enteredText(QString()) { popup->setWindowFlags(Qt::WindowType::Popup); popup->setFocusPolicy(Qt::FocusPolicy::NoFocus); popup->setFocusProxy(editor); @@ -155,7 +156,9 @@ void GoogleSuggest::autoSuggest() { m_downloader->downloadFile(url); } -void GoogleSuggest::handleNetworkData(QNetworkReply::NetworkError status, const QByteArray& contents) { +void GoogleSuggest::handleNetworkData(const QUrl& url, QNetworkReply::NetworkError status, const QByteArray& contents) { + Q_UNUSED(url) + if (status == QNetworkReply::NetworkError::NoError) { QStringList choices; QDomDocument xml; diff --git a/src/librssguard/network-web/googlesuggest.h b/src/librssguard/network-web/googlesuggest.h index 83ca844ba..24b6fef6c 100644 --- a/src/librssguard/network-web/googlesuggest.h +++ b/src/librssguard/network-web/googlesuggest.h @@ -42,7 +42,7 @@ class LocationLineEdit; class QTimer; class GoogleSuggest : public QObject { - Q_OBJECT + Q_OBJECT public: explicit GoogleSuggest(LocationLineEdit* editor, QObject* parent = nullptr); @@ -54,7 +54,7 @@ class GoogleSuggest : public QObject { void doneCompletion(); void preventSuggest(); void autoSuggest(); - void handleNetworkData(QNetworkReply::NetworkError status, const QByteArray& contents); + void handleNetworkData(const QUrl& url, QNetworkReply::NetworkError status, const QByteArray& contents); private: LocationLineEdit* editor;