From 17c233563a256f641934be2b7d4b69aff26927bf Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 14 Jan 2022 14:13:44 +0100 Subject: [PATCH] fixed #198 --- resources/icons.qrc | 4 + src/librssguard/gui/messagebox.cpp | 4 + src/librssguard/librssguard.pro | 4 + .../standard/gui/formstandardimportexport.ui | 4 +- .../services/tt-rss/gui/formttrssnote.cpp | 79 +++++++++++++ .../services/tt-rss/gui/formttrssnote.h | 33 ++++++ .../services/tt-rss/gui/formttrssnote.ui | 108 ++++++++++++++++++ src/librssguard/services/tt-rss/ttrssfeed.cpp | 20 +++- src/librssguard/services/tt-rss/ttrssfeed.h | 4 + .../services/tt-rss/ttrssnetworkfactory.cpp | 55 +++++++++ .../services/tt-rss/ttrssnetworkfactory.h | 5 + .../services/tt-rss/ttrssnotetopublish.h | 15 +++ .../services/tt-rss/ttrssserviceroot.cpp | 5 + .../services/tt-rss/ttrssserviceroot.h | 3 + 14 files changed, 340 insertions(+), 3 deletions(-) create mode 100755 src/librssguard/services/tt-rss/gui/formttrssnote.cpp create mode 100755 src/librssguard/services/tt-rss/gui/formttrssnote.h create mode 100755 src/librssguard/services/tt-rss/gui/formttrssnote.ui create mode 100755 src/librssguard/services/tt-rss/ttrssnotetopublish.h diff --git a/resources/icons.qrc b/resources/icons.qrc index e762e973a..2c3d443cb 100644 --- a/resources/icons.qrc +++ b/resources/icons.qrc @@ -26,6 +26,7 @@ ./graphics/Breeze/actions/32/edit-reset.svg ./graphics/Breeze/actions/22/edit-select-all.svg ./graphics/Breeze/actions/22/edit-select-none.svg + ./graphics/Breeze/emblems/22/emblem-shared.svg ./graphics/Breeze/places/96/folder.svg ./graphics/Breeze/actions/22/format-indent-more.svg ./graphics/Breeze/actions/22/format-justify-fill.svg @@ -93,6 +94,7 @@ ./graphics/Breeze Dark/actions/32/edit-reset.svg ./graphics/Breeze Dark/actions/22/edit-select-all.svg ./graphics/Breeze Dark/actions/22/edit-select-none.svg + ./graphics/Breeze Dark/emblems/22/emblem-shared.svg ./graphics/Breeze Dark/places/96/folder.svg ./graphics/Breeze Dark/actions/22/format-indent-more.svg ./graphics/Breeze Dark/actions/22/format-justify-fill.svg @@ -159,6 +161,7 @@ ./graphics/Faenza/actions/64/edit-copy.png ./graphics/Faenza/actions/64/edit-select-all.png ./graphics/Faenza/emblems/64/emblem-downloads.png + ./graphics/Faenza/emblems/64/emblem-shared.png ./graphics/Faenza/emblems/64/emblem-system.png ./graphics/Faenza/places/64/folder.png ./graphics/Faenza/actions/64/format-indent-more.png @@ -230,6 +233,7 @@ ./graphics/Numix/22/actions/edit-copy.svg ./graphics/Numix/22/actions/edit-select-all.svg ./graphics/Numix/22/emblems/emblem-downloads.svg + ./graphics/Numix/22/emblems/emblem-shared.svg ./graphics/Numix/22/emblems/emblem-system.svg ./graphics/Numix/22/places/folder.svg ./graphics/Numix/22/actions/format-indent-more.svg diff --git a/src/librssguard/gui/messagebox.cpp b/src/librssguard/gui/messagebox.cpp index f7e593339..b546c1dd0 100644 --- a/src/librssguard/gui/messagebox.cpp +++ b/src/librssguard/gui/messagebox.cpp @@ -64,6 +64,10 @@ QMessageBox::StandardButton MessageBox::show(QWidget* parent, bool* dont_show_again, const QString& functor_heading, const std::function& functor) { + if (parent == nullptr) { + parent = qApp->mainFormWidget(); + } + // Create and find needed components. MessageBox msg_box(parent); diff --git a/src/librssguard/librssguard.pro b/src/librssguard/librssguard.pro index 06874b7d3..7bee40602 100644 --- a/src/librssguard/librssguard.pro +++ b/src/librssguard/librssguard.pro @@ -220,10 +220,12 @@ HEADERS += core/feeddownloader.h \ services/tt-rss/definitions.h \ services/tt-rss/gui/formeditttrssaccount.h \ services/tt-rss/gui/formttrssfeeddetails.h \ + services/tt-rss/gui/formttrssnote.h \ services/tt-rss/gui/ttrssaccountdetails.h \ services/tt-rss/gui/ttrssfeeddetails.h \ services/tt-rss/ttrssfeed.h \ services/tt-rss/ttrssnetworkfactory.h \ + services/tt-rss/ttrssnotetopublish.h \ services/tt-rss/ttrssserviceentrypoint.h \ services/tt-rss/ttrssserviceroot.h @@ -403,6 +405,7 @@ SOURCES += core/feeddownloader.cpp \ services/standard/standardserviceroot.cpp \ services/tt-rss/gui/formeditttrssaccount.cpp \ services/tt-rss/gui/formttrssfeeddetails.cpp \ + services/tt-rss/gui/formttrssnote.cpp \ services/tt-rss/gui/ttrssaccountdetails.cpp \ services/tt-rss/gui/ttrssfeeddetails.cpp \ services/tt-rss/ttrssfeed.cpp \ @@ -455,6 +458,7 @@ FORMS += gui/dialogs/formabout.ui \ services/reddit/gui/redditaccountdetails.ui \ services/standard/gui/formstandardimportexport.ui \ services/standard/gui/standardfeeddetails.ui \ + services/tt-rss/gui/formttrssnote.ui \ services/tt-rss/gui/ttrssaccountdetails.ui \ services/tt-rss/gui/ttrssfeeddetails.ui diff --git a/src/librssguard/services/standard/gui/formstandardimportexport.ui b/src/librssguard/services/standard/gui/formstandardimportexport.ui index 720ec2b94..68242b39a 100644 --- a/src/librssguard/services/standard/gui/formstandardimportexport.ui +++ b/src/librssguard/services/standard/gui/formstandardimportexport.ui @@ -239,8 +239,8 @@ reject() - 316 - 260 + 325 + 424 286 diff --git a/src/librssguard/services/tt-rss/gui/formttrssnote.cpp b/src/librssguard/services/tt-rss/gui/formttrssnote.cpp new file mode 100755 index 000000000..8a66eb81b --- /dev/null +++ b/src/librssguard/services/tt-rss/gui/formttrssnote.cpp @@ -0,0 +1,79 @@ +// For license of this file, see /LICENSE.md. + +#include "services/tt-rss/gui/formttrssnote.h" + +#include "gui/guiutilities.h" +#include "gui/messagebox.h" +#include "miscellaneous/application.h" +#include "miscellaneous/iconfactory.h" +#include "services/tt-rss/definitions.h" +#include "services/tt-rss/ttrssnetworkfactory.h" +#include "services/tt-rss/ttrssnotetopublish.h" +#include "services/tt-rss/ttrssserviceroot.h" + +FormTtRssNote::FormTtRssNote(TtRssServiceRoot* root) : QDialog(qApp->mainFormWidget()), m_root(root), m_titleOk(false), + m_urlOk(false) { + m_ui.setupUi(this); + + GuiUtilities::applyDialogProperties(*this, + qApp->icons()->fromTheme(QSL("emblem-shared")), + tr("Share note to \"Published\" feed")); + + setTabOrder(m_ui.m_txtTitle->lineEdit(), m_ui.m_txtUrl->lineEdit()); + setTabOrder(m_ui.m_txtUrl->lineEdit(), m_ui.m_txtContent); + setTabOrder(m_ui.m_txtContent, m_ui.m_btnBox); + + connect(m_ui.m_txtTitle->lineEdit(), &BaseLineEdit::textChanged, this, &FormTtRssNote::onTitleChanged); + connect(m_ui.m_txtUrl->lineEdit(), &BaseLineEdit::textChanged, this, &FormTtRssNote::onUrlChanged); + connect(m_ui.m_btnBox, &QDialogButtonBox::accepted, this, &FormTtRssNote::sendNote); + + emit m_ui.m_txtTitle->lineEdit()->textChanged({}); + emit m_ui.m_txtUrl->lineEdit()->textChanged({}); +} + +void FormTtRssNote::sendNote() { + TtRssNoteToPublish note; + + note.m_content = m_ui.m_txtContent->toPlainText(); + note.m_url = m_ui.m_txtUrl->lineEdit()->text(); + note.m_title = m_ui.m_txtTitle->lineEdit()->text(); + + auto res = m_root->network()->shareToPublished(note, m_root->networkProxy()); + + if (res.status() == TTRSS_API_STATUS_OK) { + accept(); + } + else { + MessageBox::show({}, QMessageBox::Icon::Critical, + tr("Cannot share note"), + tr("There was an error, when trying to send your custom note."), + {}, + res.error()); + } +} + +void FormTtRssNote::onTitleChanged(const QString& text) { + m_titleOk = !text.simplified().isEmpty(); + + m_ui.m_txtTitle->setStatus(m_titleOk + ? WidgetWithStatus::StatusType::Ok + : WidgetWithStatus::StatusType::Error, + tr("Enter non-empty title.")); + + updateOkButton(); +} + +void FormTtRssNote::onUrlChanged(const QString& text) { + m_urlOk = text.startsWith(URI_SCHEME_HTTPS) || text.startsWith(URI_SCHEME_HTTP); + + m_ui.m_txtUrl->setStatus(m_urlOk + ? WidgetWithStatus::StatusType::Ok + : WidgetWithStatus::StatusType::Error, + tr("Enter valid URL.")); + + updateOkButton(); +} + +void FormTtRssNote::updateOkButton() { + m_ui.m_btnBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(m_urlOk && m_titleOk); +} diff --git a/src/librssguard/services/tt-rss/gui/formttrssnote.h b/src/librssguard/services/tt-rss/gui/formttrssnote.h new file mode 100755 index 000000000..8ebe6fe70 --- /dev/null +++ b/src/librssguard/services/tt-rss/gui/formttrssnote.h @@ -0,0 +1,33 @@ +// For license of this file, see /LICENSE.md. + +#ifndef FORMTTRSSNOTE_H +#define FORMTTRSSNOTE_H + +#include + +#include "ui_formttrssnote.h" + +class TtRssServiceRoot; + +class FormTtRssNote : public QDialog { + Q_OBJECT + + public: + explicit FormTtRssNote(TtRssServiceRoot* root); + + private slots: + void sendNote(); + void onTitleChanged(const QString& text); + void onUrlChanged(const QString& text); + + private: + void updateOkButton(); + + private: + Ui::FormTtRssNote m_ui; + TtRssServiceRoot* m_root; + bool m_titleOk; + bool m_urlOk; +}; + +#endif // FORMTTRSSNOTE_H diff --git a/src/librssguard/services/tt-rss/gui/formttrssnote.ui b/src/librssguard/services/tt-rss/gui/formttrssnote.ui new file mode 100755 index 000000000..91a453834 --- /dev/null +++ b/src/librssguard/services/tt-rss/gui/formttrssnote.ui @@ -0,0 +1,108 @@ + + + FormTtRssNote + + + + 0 + 0 + 400 + 340 + + + + Dialog + + + + + + Title + + + m_txtTitle + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + URL + + + m_txtUrl + + + + + + + Content + + + m_txtContent + + + + + + + + + + + LineEditWithStatus + QWidget +
lineeditwithstatus.h
+ 1 +
+
+ + + + m_btnBox + rejected() + FormTtRssNote + reject() + + + 295 + 327 + + + 286 + 274 + + + + +
diff --git a/src/librssguard/services/tt-rss/ttrssfeed.cpp b/src/librssguard/services/tt-rss/ttrssfeed.cpp index 5e0a48279..1afed9766 100644 --- a/src/librssguard/services/tt-rss/ttrssfeed.cpp +++ b/src/librssguard/services/tt-rss/ttrssfeed.cpp @@ -13,7 +13,7 @@ #include -TtRssFeed::TtRssFeed(RootItem* parent) : Feed(parent) {} +TtRssFeed::TtRssFeed(RootItem* parent) : Feed(parent), m_actionShareToPublished(nullptr) {} TtRssServiceRoot* TtRssFeed::serviceRoot() const { return qobject_cast(getParentServiceRoot()); @@ -39,6 +39,24 @@ bool TtRssFeed::deleteViaGui() { } } +QList TtRssFeed::contextMenuFeedsList() { + auto menu = Feed::contextMenuFeedsList(); + + if (customNumericId() == TTRSS_PUBLISHED_FEED_ID) { + if (m_actionShareToPublished == nullptr) { + m_actionShareToPublished = new QAction(qApp->icons()->fromTheme(QSL("emblem-shared")), + tr("Share to published"), + this); + + connect(m_actionShareToPublished, &QAction::triggered, serviceRoot(), &TtRssServiceRoot::shareToPublished); + } + + menu.append(m_actionShareToPublished); + } + + return menu; +} + bool TtRssFeed::removeItself() { QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className()); diff --git a/src/librssguard/services/tt-rss/ttrssfeed.h b/src/librssguard/services/tt-rss/ttrssfeed.h index 8db689369..7ee08aefc 100644 --- a/src/librssguard/services/tt-rss/ttrssfeed.h +++ b/src/librssguard/services/tt-rss/ttrssfeed.h @@ -15,10 +15,14 @@ class TtRssFeed : public Feed { virtual bool canBeDeleted() const; virtual bool deleteViaGui(); + virtual QList contextMenuFeedsList(); private: TtRssServiceRoot* serviceRoot() const; bool removeItself(); + + private: + QAction* m_actionShareToPublished; }; #endif // TTRSSFEED_H diff --git a/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp b/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp index 3d87e47fe..41b1eefa4 100644 --- a/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp +++ b/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp @@ -209,6 +209,61 @@ TtRssGetLabelsResponse TtRssNetworkFactory::getLabels(const QNetworkProxy& proxy return result; } +TtRssResponse TtRssNetworkFactory::shareToPublished(const TtRssNoteToPublish& note, const QNetworkProxy& proxy) { + QJsonObject json; + + json[QSL("op")] = QSL("shareToPublished"); + json[QSL("sid")] = m_sessionId; + json[QSL("title")] = note.m_title; + json[QSL("url")] = note.m_url; + json[QSL("content")] = note.m_content; + + const int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); + QByteArray result_raw; + QList> headers; + + headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); + headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + + NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, + timeout, + QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact), + result_raw, + QNetworkAccessManager::Operation::PostOperation, + headers, + false, + {}, + {}, + proxy); + TtRssResponse result(QString::fromUtf8(result_raw)); + + if (result.isNotLoggedIn()) { + // We are not logged in. + login(proxy); + json[QSL("sid")] = m_sessionId; + network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, + timeout, + QJsonDocument(json).toJson(QJsonDocument::JsonFormat::Compact), + result_raw, + QNetworkAccessManager::Operation::PostOperation, + headers, + false, + {}, + {}, + proxy); + result = TtRssResponse(QString::fromUtf8(result_raw)); + } + + if (network_reply.first != QNetworkReply::NoError) { + qWarningNN << LOGSEC_TTRSS + << "shareToPublished failed with error:" + << QUOTE_W_SPACE_DOT(network_reply.first); + } + + m_lastError = network_reply.first; + return result; +} + TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories(const QNetworkProxy& proxy) { QJsonObject json; diff --git a/src/librssguard/services/tt-rss/ttrssnetworkfactory.h b/src/librssguard/services/tt-rss/ttrssnetworkfactory.h index cea35045d..720580b9e 100644 --- a/src/librssguard/services/tt-rss/ttrssnetworkfactory.h +++ b/src/librssguard/services/tt-rss/ttrssnetworkfactory.h @@ -5,6 +5,8 @@ #include "core/message.h" +#include "services/tt-rss/ttrssnotetopublish.h" + #include #include #include @@ -155,6 +157,9 @@ class TtRssNetworkFactory { // Gets list of labels from the server. TtRssGetLabelsResponse getLabels(const QNetworkProxy& proxy); + // Shares new item to "published" feed. + TtRssResponse shareToPublished(const TtRssNoteToPublish& note, const QNetworkProxy& proxy); + // Gets feeds from the server. TtRssGetFeedsCategoriesResponse getFeedsCategories(const QNetworkProxy& proxy); diff --git a/src/librssguard/services/tt-rss/ttrssnotetopublish.h b/src/librssguard/services/tt-rss/ttrssnotetopublish.h new file mode 100755 index 000000000..077ed239f --- /dev/null +++ b/src/librssguard/services/tt-rss/ttrssnotetopublish.h @@ -0,0 +1,15 @@ +// For license of this file, see /LICENSE.md. + +#ifndef TTRSSNOTETOPUBLISH_H +#define TTRSSNOTETOPUBLISH_H + +#include + +struct TtRssNoteToPublish { + public: + QString m_title; + QString m_url; + QString m_content; +}; + +#endif // TTRSSNOTETOPUBLISH_H diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index f713474e9..5088524ad 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -17,6 +17,7 @@ #include "services/tt-rss/definitions.h" #include "services/tt-rss/gui/formeditttrssaccount.h" #include "services/tt-rss/gui/formttrssfeeddetails.h" +#include "services/tt-rss/gui/formttrssnote.h" #include "services/tt-rss/ttrssfeed.h" #include "services/tt-rss/ttrssnetworkfactory.h" #include "services/tt-rss/ttrssserviceentrypoint.h" @@ -297,6 +298,10 @@ TtRssNetworkFactory* TtRssServiceRoot::network() const { return m_network; } +void TtRssServiceRoot::shareToPublished() { + FormTtRssNote(this).exec(); +} + void TtRssServiceRoot::updateTitle() { QString host = QUrl(m_network->url()).host(); diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.h b/src/librssguard/services/tt-rss/ttrssserviceroot.h index 866c0791a..239fbe13c 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.h +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.h @@ -40,6 +40,9 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot { // Access to network. TtRssNetworkFactory* network() const; + public slots: + void shareToPublished(); + protected: virtual RootItem* obtainNewTreeForSyncIn() const;