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