diff --git a/resources/rssguard.qrc b/resources/rssguard.qrc index 21924a220..62c82dc5d 100644 --- a/resources/rssguard.qrc +++ b/resources/rssguard.qrc @@ -14,6 +14,7 @@ scripts/gemini/style.css sounds/boing.wav + sounds/error.wav sounds/rooster.wav sounds/sheep.wav sounds/doorbell.wav diff --git a/resources/sounds/error.wav b/resources/sounds/error.wav new file mode 100644 index 000000000..88c26da4f Binary files /dev/null and b/resources/sounds/error.wav differ diff --git a/resources/text/licenses.json b/resources/text/licenses.json index 9bffad9ca..796ab4c3c 100644 --- a/resources/text/licenses.json +++ b/resources/text/licenses.json @@ -23,5 +23,10 @@ "title": "GNU GPL v3.0 + Qt Company GPL Exception 1.0", "file": "COPYING_QT", "components": "Qt" + }, + { + "title": "Attribution 3.0", + "text": "Error Bleep 4 by original_sound -- https://freesound.org/s/372197/ -- License: Attribution 3.0", + "components": "Error Bleep 4" } ] \ No newline at end of file diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index b722a8301..96b604b3b 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -447,6 +447,7 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc, qCriticalNN << LOGSEC_NETWORK << "Error when fetching feed:" << QUOTE_W_SPACE(feed_ex.feedStatus()) << "message:" << QUOTE_W_SPACE_DOT(feed_ex.message()); + m_results.appendErroredFeed(feed, feed_ex.message()); feed->setStatus(feed_ex.feedStatus(), feed_ex.message()); if (feed_ex.feedStatus() == Feed::Status::NetworkError && !feed_ex.data().isNull()) { @@ -468,6 +469,7 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc, qCriticalNN << LOGSEC_NETWORK << "Unknown error when fetching feed:" << "message:" << QUOTE_W_SPACE_DOT(app_ex.message()); + m_results.appendErroredFeed(feed, app_ex.message()); feed->setStatus(Feed::Status::OtherError, app_ex.message()); } @@ -484,6 +486,13 @@ void FeedDownloader::finalizeUpdate() { m_feeds.clear(); + if (!m_results.erroredFeeds().isEmpty()) { + qApp->showGuiMessage(Notification::Event::ArticlesFetchingError, + {QObject::tr("Some feed have error"), + QObject::tr("Some feeds threw an error when fetching articles."), + QSystemTrayIcon::MessageIcon::Critical}); + } + // Update of feeds has finished. // NOTE: This means that now "update lock" can be unlocked // and feeds can be added/edited/deleted and application @@ -632,8 +641,17 @@ void FeedDownloadResults::appendUpdatedFeed(Feed* feed, const QList& up } } +void FeedDownloadResults::appendErroredFeed(Feed* feed, const QString& error) { + m_erroredFeeds.insert(feed, error); +} + void FeedDownloadResults::clear() { m_updatedFeeds.clear(); + m_erroredFeeds.clear(); +} + +QHash FeedDownloadResults::erroredFeeds() const { + return m_erroredFeeds; } QHash> FeedDownloadResults::updatedFeeds() const { diff --git a/src/librssguard/core/feeddownloader.h b/src/librssguard/core/feeddownloader.h index eafad1acc..c7bf71df6 100644 --- a/src/librssguard/core/feeddownloader.h +++ b/src/librssguard/core/feeddownloader.h @@ -18,14 +18,18 @@ class MessageFilter; // Represents results of batch feed updates. class FeedDownloadResults { public: + QHash erroredFeeds() const; QHash> updatedFeeds() const; QString overview(int how_many_feeds) const; + void appendUpdatedFeed(Feed* feed, const QList& updated_unread_msgs); + void appendErroredFeed(Feed* feed, const QString& error); void clear(); private: // QString represents title if the feed, int represents count of newly downloaded messages. QHash> m_updatedFeeds; + QHash m_erroredFeeds; }; struct FeedUpdateRequest { diff --git a/src/librssguard/gui/dialogs/formabout.cpp b/src/librssguard/gui/dialogs/formabout.cpp index 69303422d..687bae3cd 100644 --- a/src/librssguard/gui/dialogs/formabout.cpp +++ b/src/librssguard/gui/dialogs/formabout.cpp @@ -107,10 +107,15 @@ void FormAbout::loadLicenseAndInformation() { QJsonDocument licenses_index = QJsonDocument::fromJson(IOFactory::readFile(APP_INFO_PATH + QSL("/licenses.json"))); for (const QJsonValue& license : licenses_index.array()) { - const QJsonObject license_obj = license.toObject(); - const QString license_text = - QString::fromUtf8(IOFactory::readFile(APP_INFO_PATH + QSL("/") + license_obj[QSL("file")].toString())); - const QString license_title = + QJsonObject license_obj = license.toObject(); + QString license_text = license_obj.value(QSL("text")).toString(); + + if (license_text.isEmpty()) { + license_text = + QString::fromUtf8(IOFactory::readFile(APP_INFO_PATH + QSL("/") + license_obj[QSL("file")].toString())); + } + + QString license_title = license_obj[QSL("title")].toString() + QSL(": ") + license_obj[QSL("components")].toString(); m_ui.m_cbLicenses->addItem(license_title, license_text); diff --git a/src/librssguard/gui/dialogs/formabout.ui b/src/librssguard/gui/dialogs/formabout.ui index 2eb084433..b7a025524 100644 --- a/src/librssguard/gui/dialogs/formabout.ui +++ b/src/librssguard/gui/dialogs/formabout.ui @@ -43,13 +43,13 @@ - Qt::RichText + Qt::TextFormat::RichText true - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -68,16 +68,16 @@ - Qt::RichText + Qt::TextFormat::RichText - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter 5 - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByKeyboard|Qt::TextInteractionFlag::TextSelectableByMouse @@ -105,7 +105,7 @@ - 0 + 1 @@ -118,7 +118,7 @@ - Qt::DefaultContextMenu + Qt::ContextMenuPolicy::DefaultContextMenu @@ -143,7 +143,7 @@ li.checked::marker { content: "\2612"; } false - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse @@ -164,7 +164,11 @@ li.checked::marker { content: "\2612"; } - + + + true + + @@ -202,7 +206,7 @@ li.checked::marker { content: "\2612"; } false - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse true @@ -224,7 +228,7 @@ li.checked::marker { content: "\2612"; } - QFormLayout::ExpandingFieldsGrow + QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow @@ -240,7 +244,7 @@ li.checked::marker { content: "\2612"; } - QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Ok diff --git a/src/librssguard/miscellaneous/notification.cpp b/src/librssguard/miscellaneous/notification.cpp index 3984db08e..bb70f9fe1 100644 --- a/src/librssguard/miscellaneous/notification.cpp +++ b/src/librssguard/miscellaneous/notification.cpp @@ -119,6 +119,7 @@ QList Notification::allEvents() { return {Event::GeneralEvent, Event::NewUnreadArticlesFetched, Event::ArticlesFetchingStarted, + Event::ArticlesFetchingError, Event::LoginDataRefreshed, Event::LoginFailure, Event::NewAppVersionAvailable, @@ -152,6 +153,9 @@ QString Notification::nameForEvent(Notification::Event event) { case Notification::Event::NodePackageFailedToUpdate: return QObject::tr("Node.js - package(s) failed to update"); + case Notification::Event::ArticlesFetchingError: + return QObject::tr("Error when fetching articles"); + default: return QObject::tr("Unknown event"); } diff --git a/src/librssguard/miscellaneous/notification.h b/src/librssguard/miscellaneous/notification.h index 099d6e883..75d165e53 100644 --- a/src/librssguard/miscellaneous/notification.h +++ b/src/librssguard/miscellaneous/notification.h @@ -40,7 +40,10 @@ class Notification { NodePackageUpdated = 7, // Node.js - package failde to update. - NodePackageFailedToUpdate = 8 + NodePackageFailedToUpdate = 8, + + // There was at least one error during fetching articles. + ArticlesFetchingError = 9 }; explicit Notification(Event event = Event::NoEvent,