From d04c28cffc2a539378e17065b06a623396204817 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 20 Apr 2023 19:00:51 +0200 Subject: [PATCH 01/18] Fixed to get reizable people page * Fixed to get resizable people page * Moved text for auto ban as tooltip, keep short text for the checkbox * Removed empty wasting spacer from Boards bar --- retroshare-gui/src/gui/Identity/IdDialog.ui | 31 +++++++++---------- .../gui/Posted/PostedListWidgetWithModel.ui | 16 ---------- .../src/gui/msgs/MessageComposer.ui | 4 +-- 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index f18ddbc87..196fbdae4 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -301,8 +301,8 @@ 0 0 - 634 - 538 + 479 + 731 @@ -338,21 +338,14 @@ - - - - Qt::Vertical - - - - 518 - 17 - - - - + + + 0 + 0 + + @@ -490,6 +483,9 @@ Invite messages stay into your Outbox until an acknowledgement of receipt has been received. + + true + @@ -895,9 +891,12 @@ border-image: url(:/images/closepressed.png) - + Auto-Ban all identities signed by the same node + + Auto-Ban + diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui index 9ed0fc3db..2bafbc8a2 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui @@ -454,22 +454,6 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 40 - 20 - - - - diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.ui b/retroshare-gui/src/gui/msgs/MessageComposer.ui index 8b2e3d601..9b5e8605c 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.ui +++ b/retroshare-gui/src/gui/msgs/MessageComposer.ui @@ -6,8 +6,8 @@ 0 0 - 1215 - 825 + 800 + 650 From 7858db9b2c9cc3d5428710d945a52963a0cd9a66 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 20 Apr 2023 19:48:13 +0200 Subject: [PATCH 02/18] Use ElidedLabel for post name Label --- .../src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui index c4005cfc6..9afe3e5d0 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui @@ -402,7 +402,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html> @@ -534,7 +534,7 @@ p, li { white-space: pre-wrap; } - + 75 From a71d6e243003553396a26b47cd39706daefdf1a6 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 20 Apr 2023 23:26:57 +0200 Subject: [PATCH 03/18] Picture attachments improved * Added a remove button to clear pictures * Improved picture attachments --- .../src/gui/TheWire/PulseAddDialog.cpp | 46 ++++++-- .../src/gui/TheWire/PulseAddDialog.h | 3 +- .../src/gui/TheWire/PulseAddDialog.ui | 102 +++++++++--------- 3 files changed, 91 insertions(+), 60 deletions(-) diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp index 572772a1e..8877d5cf6 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp @@ -42,15 +42,26 @@ PulseAddDialog::PulseAddDialog(QWidget *parent) connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) ); connect(ui.textEdit_Pulse, SIGNAL( textChanged( void ) ), this, SLOT( pulseTextChanged( void ) ) ); connect(ui.pushButton_picture, SIGNAL(clicked()), this, SLOT( toggle())); + connect(ui.pushButton_remove, SIGNAL(clicked()), this, SLOT( removePictures())); + // this connection is from browse push button to the slot function onBrowseButtonClicked() connect(ui.pushButton_Browse, SIGNAL(clicked()), this, SLOT( onBrowseButtonClicked())); ui.pushButton_picture->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/photo.png"))); + ui.pushButton_Browse->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/add-image.png"))); + ui.pushButton_remove->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/mail/delete.png"))); + ui.frame_picture->hide(); + ui.pushButton_picture->hide(); // initially hiding the browse button as the attach image button is not pressed - ui.frame_PictureBrowse->hide(); + //ui.frame_PictureBrowse->hide(); + + ui.label_image1->hide(); + ui.label_image2->hide(); + ui.label_image3->hide(); + ui.label_image4->hide(); setAcceptDrops(true); } @@ -160,11 +171,10 @@ void PulseAddDialog::cleanup() ui.label_image4->clear(); ui.label_image4->setText(tr("Drag and Drop Image")); - ui.lineEdit_FilePath->clear(); - // Hide Drag & Drop Frame and the browse frame ui.frame_picture->hide(); - ui.frame_PictureBrowse->hide(); + //ui.frame_PictureBrowse->hide(); + ui.pushButton_picture->hide(); ui.pushButton_picture->setChecked(false); } @@ -489,24 +499,29 @@ void PulseAddDialog::addImage(const QString &path) std::cerr << "PulseAddDialog::addImage() Installing in Image1"; std::cerr << std::endl; ui.label_image1->setPixmap(icon); + ui.label_image1->show(); + ui.frame_picture->show(); mImage1.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image1 Size: " << mImage1.mSize; std::cerr << std::endl; } else if (mImage2.empty()) { ui.label_image2->setPixmap(icon); + ui.label_image2->show(); mImage2.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image2 Size: " << mImage2.mSize; std::cerr << std::endl; } else if (mImage3.empty()) { ui.label_image3->setPixmap(icon); + ui.label_image3->show(); mImage3.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image3 Size: " << mImage3.mSize; std::cerr << std::endl; } else if (mImage4.empty()) { ui.label_image4->setPixmap(icon); + ui.label_image4->show(); mImage4.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image4 Size: " << mImage4.mSize; std::cerr << std::endl; @@ -523,7 +538,6 @@ void PulseAddDialog::toggle() { // Show the input methods (drag and drop field and the browse button) ui.frame_picture->show(); - ui.frame_PictureBrowse->show(); ui.pushButton_picture->setToolTip(tr("Hide Pictures")); } @@ -531,7 +545,6 @@ void PulseAddDialog::toggle() { // Hide the input methods (drag and drop field and the browse button) ui.frame_picture->hide(); - ui.frame_PictureBrowse->hide(); ui.pushButton_picture->setToolTip(tr("Add Pictures")); } @@ -543,8 +556,27 @@ void PulseAddDialog::onBrowseButtonClicked() QString filePath; misc::getOpenFileName(this, RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", filePath); if (!filePath.isEmpty()) { - ui.lineEdit_FilePath->setText(filePath); + //ui.lineEdit_FilePath->setText(filePath); addImage(filePath); } } +void PulseAddDialog::removePictures() +{ + + mImage1.clear(); + ui.label_image1->clear(); + mImage2.clear(); + ui.label_image2->clear(); + mImage3.clear(); + ui.label_image3->clear(); + mImage4.clear(); + ui.label_image4->clear(); + + ui.label_image1->hide(); + ui.label_image2->hide(); + ui.label_image3->hide(); + ui.label_image4->hide(); + + ui.frame_picture->hide(); +} diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h index 69007b025..b1e8eca47 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h @@ -53,7 +53,8 @@ private slots: void clearDialog(); void pulseTextChanged(); void toggle(); - void onBrowseButtonClicked(); + void onBrowseButtonClicked(); + void removePictures(); private: // OLD VERSIONs, private now. diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui index 5ef30ef19..25738136d 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui @@ -6,7 +6,7 @@ 0 0 - 720 + 735 513 @@ -52,6 +52,7 @@ 12 + 75 true @@ -249,6 +250,12 @@ + + + 0 + 0 + + 0 @@ -278,6 +285,22 @@ + + + + + 40 + 40 + + + + Drag and Drop Image + + + Qt::AlignCenter + + + @@ -310,63 +333,22 @@ - - - - - 40 - 40 - + + + + Remove all images - Drag and Drop Image + - - Qt::AlignCenter - - - - - - - - - - - 0 - 50 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - + - 541 - 25 + 24 + 24 - - - - - 101 - 25 - - - - Browse... - - - @@ -413,7 +395,6 @@ frame_URL frame_picture - frame_PictureBrowse textEdit_Pulse @@ -423,7 +404,7 @@ 6 - + @@ -438,6 +419,22 @@ + + + + Add Picture + + + + + + + 24 + 24 + + + + @@ -456,6 +453,7 @@ 12 + 75 true From f06506ec5418315a26d7da88ca1ae23c083c6d30 Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 23 Apr 2023 19:31:30 +0200 Subject: [PATCH 04/18] Corrected checkbox text --- retroshare-gui/src/gui/Identity/IdDialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 196fbdae4..ff3775aee 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -301,7 +301,7 @@ 0 0 - 479 + 456 731 @@ -895,7 +895,7 @@ border-image: url(:/images/closepressed.png) Auto-Ban all identities signed by the same node - Auto-Ban + Auto-Ban profile From beed6a08c828bc4a81f51ea5d52f6f1448fc74ec Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 4 May 2023 22:30:06 +0200 Subject: [PATCH 05/18] made SearchDialog to use RsEvents in order to catch turtle search results --- .../src/gui/FileTransfer/SearchDialog.cpp | 35 ++++++++++++++++++- .../src/gui/FileTransfer/SearchDialog.h | 4 +++ retroshare-gui/src/main.cpp | 2 +- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 94e4229cc..2ecf442e4 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -37,6 +37,7 @@ #include "gui/advsearch/advancedsearchdialog.h" #include "gui/common/RSTreeWidgetItem.h" #include "util/QtVersion.h" +#include "util/qtthreadsutils.h" #include #include @@ -217,6 +218,15 @@ SearchDialog::SearchDialog(QWidget *parent) checkText(ui.lineEdit->text()); + // add an event handler to get search results (previously available through notifyQt) + + mEventHandlerId = 0; + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId, RsEventType::FILE_TRANSFER ); + } SearchDialog::~SearchDialog() @@ -235,6 +245,29 @@ SearchDialog::~SearchDialog() ui.searchResultWidget->setItemDelegateForColumn(SR_SIZE_COL, nullptr); ui.searchResultWidget->setItemDelegateForColumn(SR_AGE_COL, nullptr); + + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void SearchDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::FILE_TRANSFER) + return; + + auto fe = dynamic_cast(event.get()); + + if(!fe || fe->mFileTransferEventCode!=RsFileTransferEventCode::NEW_DISTANT_SEARCH_RESULTS) + return; + + for(uint32_t i=0;imResults.size();++i) + { + FileDetail f; + f.hash = fe->mResults[i].fHash; + f.name = fe->mResults[i].fName; + f.size = fe->mResults[i].fSize; + + updateFiles(fe->mRequestId,f); + } } void SearchDialog::processSettings(bool bLoad) @@ -961,7 +994,7 @@ void SearchDialog::processResultQueue() while(!searchResultsQueue.empty() && nb_treated_elements++ < 250) { qulonglong search_id = searchResultsQueue.back().first ; - FileDetail& file = searchResultsQueue.back().second ; + const FileDetail& file = searchResultsQueue.back().second ; #ifdef DEBUG std::cout << "Updating file detail:" << std::endl ; diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index 25925c36d..5661f6246 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -22,6 +22,7 @@ #define _SEARCHDIALOG_H #include "retroshare/rstypes.h" +#include "retroshare/rsevents.h" #include "ui_SearchDialog.h" #include "retroshare-gui/mainpage.h" @@ -125,6 +126,7 @@ private: void setIconAndType(QTreeWidgetItem *item, const QString& filename); void downloadDirectory(const QTreeWidgetItem *item, const QString &base); void getSourceFriendsForHash(const RsFileHash &hash,std::list &srcIds); + void handleEvent_main_thread(std::shared_ptr event); /** the advanced search dialog instance */ AdvancedSearchDialog * advSearchDialog; @@ -176,6 +178,8 @@ private: bool _queueIsAlreadyTakenCareOf ; std::vector > searchResultsQueue ; + + RsEventsHandlerId_t mEventHandlerId ; }; #endif diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 2d3fabf89..3361597c8 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -540,7 +540,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); qRegisterMetaType("RsPeerId") ; std::cerr << "connecting signals and slots" << std::endl ; - QObject::connect(notify,SIGNAL(gotTurtleSearchResult(qulonglong,FileDetail)),w->transfersDialog->searchDialog ,SLOT(updateFiles(qulonglong,FileDetail))) ; +// QObject::connect(notify,SIGNAL(gotTurtleSearchResult(qulonglong,FileDetail)),w->transfersDialog->searchDialog ,SLOT(updateFiles(qulonglong,FileDetail))) ; QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ; From 93d7589a94e0f979f055730347ba1016f02f6f6b Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 4 May 2023 22:30:41 +0200 Subject: [PATCH 06/18] removed unused notifyQt calls to notify turtleSearch results --- retroshare-gui/src/gui/notifyqt.cpp | 3 +++ retroshare-gui/src/gui/notifyqt.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 9012e77bd..d2dee5ac4 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -482,6 +482,8 @@ void NotifyQt::notifyTurtleSearchResult(uint32_t /*search_id*/,const std::list& files) { { @@ -507,6 +509,7 @@ void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,c emit gotTurtleSearchResult(search_id,det) ; } } +#endif void NotifyQt::notifyHistoryChanged(uint32_t msgId, int type) { diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index d2b15fa09..0f9ae11e2 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -67,7 +67,9 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyChatStatus(const ChatId &chat_id,const std::string& status_string); virtual void notifyChatCleared(const ChatId &chat_id); virtual void notifyCustomState(const std::string& peer_id, const std::string& status_string); +#ifdef TO_REMOVE virtual void notifyTurtleSearchResult(const RsPeerId &pid, uint32_t search_id, const std::list& found_files); +#endif virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_groups); virtual void notifyPeerHasNewAvatar(std::string peer_id) ; virtual void notifyOwnAvatarChanged() ; From 7070a6cad6269d44dbf6a835528057bf4c3de6cc Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 12 Apr 2023 13:42:42 +0200 Subject: [PATCH 07/18] FeedReader: Fixed compile of FeedReader plugin --- plugins/FeedReader/services/rsFeedReaderItems.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index a8cce7084..d2ee7574e 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -62,6 +62,7 @@ public: virtual ~RsFeedReaderFeed() {} virtual void clear(); + virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&) {} uint32_t feedId; uint32_t parentId; @@ -105,6 +106,7 @@ public: virtual ~RsFeedReaderMsg() {} virtual void clear(); + virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&) {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); std::string msgId; From ecffb3cb7ff0f0f3aa547a63c2251699673ed412 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 13 Apr 2023 13:30:24 +0200 Subject: [PATCH 08/18] FeedReader: Fixed download of favicon --- plugins/FeedReader/services/p3FeedReaderThread.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 45c869581..130d2fac1 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -204,8 +204,14 @@ static std::string calculateLink(const std::string &baseLink, const std::string /* calculate link of base link */ std::string resultLink = baseLink; + int hostStart = 0; /* link should begin with "http://" or "https://" */ - if (resultLink.substr(0, 7) != "http://" || resultLink.substr(0, 8) != "https://") { + if (resultLink.substr(0, 7) == "http://") { + hostStart = 7; + } else if (resultLink.substr(0, 8) == "https://") { + hostStart = 8; + } else { + hostStart = 7; resultLink.insert(0, "http://"); } @@ -216,7 +222,7 @@ static std::string calculateLink(const std::string &baseLink, const std::string if (*link.begin() == '/') { /* link begins with "/" */ - size_t found = resultLink.find('/', 7); + size_t found = resultLink.find('/', hostStart); if (found != std::string::npos) { resultLink.erase(found); } @@ -245,7 +251,7 @@ static bool getFavicon(CURLWrapper &CURL, const std::string &url, std::string &i if (code == CURLE_OK) { if (CURL.responseCode() == 200) { std::string contentType = CURL.contentType(); - if (isContentType(contentType, "image/x-icon") || + if (isContentType(contentType, "image/") || isContentType(contentType, "application/octet-stream") || isContentType(contentType, "text/plain")) { if (!vicon.empty()) { From 571f709b50222be19490b60e41ba437036046a7f Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 11 Apr 2023 00:36:41 +0200 Subject: [PATCH 09/18] FeedReader: The feed can be used as source for board --- plugins/FeedReader/FeedReaderPlugin.cpp | 2 +- plugins/FeedReader/gui/AddFeedDialog.cpp | 214 ++++++++++++-- plugins/FeedReader/gui/AddFeedDialog.h | 12 +- plugins/FeedReader/gui/AddFeedDialog.ui | 116 ++++++-- .../gui/FeedReaderMessageWidget.cpp | 14 +- .../FeedReader/gui/FeedReaderStringDefs.cpp | 18 +- plugins/FeedReader/interface/rsFeedReader.h | 13 +- plugins/FeedReader/lang/FeedReader_en.ts | 90 ++++-- plugins/FeedReader/services/p3FeedReader.cc | 263 +++++++++++++++++- plugins/FeedReader/services/p3FeedReader.h | 10 +- .../FeedReader/services/p3FeedReaderThread.cc | 26 +- .../FeedReader/services/rsFeedReaderItems.cc | 8 +- .../FeedReader/services/rsFeedReaderItems.h | 31 ++- 13 files changed, 704 insertions(+), 113 deletions(-) diff --git a/plugins/FeedReader/FeedReaderPlugin.cpp b/plugins/FeedReader/FeedReaderPlugin.cpp index 24b602f9c..bc44a3036 100644 --- a/plugins/FeedReader/FeedReaderPlugin.cpp +++ b/plugins/FeedReader/FeedReaderPlugin.cpp @@ -92,7 +92,7 @@ void FeedReaderPlugin::setInterfaces(RsPlugInInterfaces &interfaces) { mInterfaces = interfaces; - mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums); + mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums, mInterfaces.mPosted); rsFeedReader = mFeedReader; mNotify = new FeedReaderNotify(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index 19d02d968..c99b29b7a 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -30,9 +30,11 @@ #include "gui/common/UIStateHelper.h" #include +#include #include -#define TOKEN_TYPE_FORUM_GROUPS 1 +#define TOKEN_TYPE_FORUM_GROUPS 1 +#define TOKEN_TYPE_POSTED_GROUPS 2 AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent) : QDialog(parent, Qt::Window), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) @@ -47,9 +49,12 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->forumComboBox, UISTATE_LOADING_DISABLED); mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), UISTATE_LOADING_DISABLED); + mStateHelper->addWidget(TOKEN_TYPE_POSTED_GROUPS, ui->postedComboBox, UISTATE_LOADING_DISABLED); + mStateHelper->addWidget(TOKEN_TYPE_POSTED_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), UISTATE_LOADING_DISABLED); /* Setup TokenQueue */ - mTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mForumTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mPostedTokenQueue = new TokenQueue(rsPosted->getTokenService(), this); /* Connect signals */ connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(createFeed())); @@ -59,18 +64,23 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, connect(ui->useStandardStorageTimeCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardStorageTimeToggled())); connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled())); connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); - connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->typeForumCheckBox, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->typePostedCheckBox, SIGNAL(toggled(bool)), this, SLOT(typePostedToggled())); + connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(typeLocalToggled())); + connect(ui->postedFirstImageCheckBox, SIGNAL(toggled(bool)), this, SLOT(postedFirstImageToggled())); connect(ui->previewButton, SIGNAL(clicked()), this, SLOT(preview())); /* currently only for local feeds */ - connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumToggled())); + connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumAndPostedToggled())); connect(ui->urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->useInfoFromFeedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); - connect(ui->typeLocalRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); - connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeForumCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); connect(ui->forumComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(validate())); + connect(ui->typePostedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->postedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(validate())); connect(ui->clearCachePushButton, SIGNAL(clicked()), this, SLOT(clearMessageCache())); @@ -79,13 +89,22 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, ui->activatedCheckBox->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, false); + mStateHelper->setWidgetEnabled(ui->postedComboBox, false); ui->useInfoFromFeedCheckBox->setChecked(true); ui->updateForumInfoCheckBox->setEnabled(false); ui->updateForumInfoCheckBox->setChecked(true); + ui->updatePostedInfoCheckBox->setEnabled(false); + ui->updatePostedInfoCheckBox->setChecked(true); + ui->postedFirstImageCheckBox->setEnabled(false); + ui->postedFirstImageCheckBox->setChecked(false); + ui->postedOnlyImageCheckBox->setEnabled(false); + ui->postedOnlyImageCheckBox->setChecked(false); ui->useAuthenticationCheckBox->setChecked(false); ui->useStandardStorageTimeCheckBox->setChecked(true); ui->useStandardUpdateInterval->setChecked(true); ui->useStandardProxyCheckBox->setChecked(true); + ui->embedImagesCheckBox->setChecked(true); + ui->saveCompletePageCheckBox->setEnabled(false); /* not yet supported */ ui->authenticationGroupBox->setEnabled(false); @@ -98,6 +117,9 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, /* fill own forums */ requestForumGroups(); + /* fill own posted */ + requestPostedGroups(); + validate(); ui->urlLineEdit->setFocus(); @@ -112,7 +134,8 @@ AddFeedDialog::~AddFeedDialog() processSettings(false); delete(ui); - delete(mTokenQueue); + delete(mForumTokenQueue); + delete(mPostedTokenQueue); } void AddFeedDialog::processSettings(bool load) @@ -161,18 +184,65 @@ void AddFeedDialog::useStandardProxyToggled() void AddFeedDialog::typeForumToggled() { - bool checked = ui->typeForumRadio->isChecked(); + bool checked = ui->typeForumCheckBox->isChecked(); mStateHelper->setWidgetEnabled(ui->forumComboBox, checked); ui->updateForumInfoCheckBox->setEnabled(checked); + + if (checked) { + ui->typeLocalCheckBox->setChecked(false); + } } -void AddFeedDialog::denyForumToggled() +void AddFeedDialog::postedFirstImageToggled() +{ + bool checked = ui->postedFirstImageCheckBox->isChecked(); + ui->postedOnlyImageCheckBox->setEnabled(checked); + + if (!checked) { + ui->postedOnlyImageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::typePostedToggled() +{ + bool checked = ui->typePostedCheckBox->isChecked(); + mStateHelper->setWidgetEnabled(ui->postedComboBox, checked); + ui->updatePostedInfoCheckBox->setEnabled(checked); + ui->postedFirstImageCheckBox->setEnabled(checked); + + if (checked) { + ui->typeLocalCheckBox->setChecked(false); + }else { + ui->postedFirstImageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::typeLocalToggled() +{ + bool checked = ui->typeLocalCheckBox->isChecked(); + if (checked) { + mStateHelper->setWidgetEnabled(ui->forumComboBox, false); + mStateHelper->setWidgetEnabled(ui->postedComboBox, false); + ui->typeForumCheckBox->setChecked(false); + ui->typePostedCheckBox->setChecked(false); + ui->saveCompletePageCheckBox->setEnabled(true); + } else { + ui->saveCompletePageCheckBox->setEnabled(false); + ui->saveCompletePageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::denyForumAndPostedToggled() { if (ui->saveCompletePageCheckBox->isChecked()) { - ui->typeForumRadio->setEnabled(false); - ui->typeLocalRadio->setChecked(true); + ui->typeForumCheckBox->setEnabled(false); + ui->typeForumCheckBox->setChecked(false); + ui->typePostedCheckBox->setEnabled(false); + ui->typePostedCheckBox->setChecked(false); + ui->typeLocalCheckBox->setChecked(true); } else { - ui->typeForumRadio->setEnabled(true); + ui->typeForumCheckBox->setEnabled(true); + ui->typePostedCheckBox->setEnabled(true); } } @@ -189,11 +259,15 @@ void AddFeedDialog::validate() ui->previewButton->setEnabled(ok); - if (!ui->typeLocalRadio->isChecked() && !ui->typeForumRadio->isChecked()) { + if (!ui->typeLocalCheckBox->isChecked() && !ui->typeForumCheckBox->isChecked() && !ui->typePostedCheckBox->isChecked()) { ok = false; } - if (ui->typeForumRadio->isChecked() && ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().isEmpty()) { + if (ui->typeForumCheckBox->isChecked() && ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().isEmpty()) { + ok = false; + } + + if (ui->typePostedCheckBox->isChecked() && ui->postedComboBox->itemData(ui->postedComboBox->currentIndex()).toString().isEmpty()) { ok = false; } @@ -224,20 +298,31 @@ bool AddFeedDialog::fillFeed(uint32_t feedId) ui->urlLineEdit->setText(QString::fromUtf8(feedInfo.url.c_str())); ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed); ui->updateForumInfoCheckBox->setChecked(feedInfo.flag.updateForumInfo); + ui->updatePostedInfoCheckBox->setChecked(feedInfo.flag.updatePostedInfo); + ui->postedFirstImageCheckBox->setChecked(feedInfo.flag.postedFirstImage); + ui->postedOnlyImageCheckBox->setChecked(feedInfo.flag.postedOnlyImage); ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages); ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage); ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str())); - if (feedInfo.flag.forum) { - mStateHelper->setWidgetEnabled(ui->forumComboBox, true); - ui->typeForumRadio->setChecked(true); - ui->saveCompletePageCheckBox->setEnabled(false); + if (feedInfo.flag.forum || feedInfo.flag.posted) { + if (feedInfo.flag.forum) { + mStateHelper->setWidgetEnabled(ui->forumComboBox, true); + ui->typeForumCheckBox->setChecked(true); - setActiveForumId(feedInfo.forumId); + setActiveForumId(feedInfo.forumId); + } + if (feedInfo.flag.posted) { + mStateHelper->setWidgetEnabled(ui->postedComboBox, true); + ui->typePostedCheckBox->setChecked(true); + + setActivePostedId(feedInfo.postedId); + } + ui->saveCompletePageCheckBox->setEnabled(false); } else { - ui->typeLocalRadio->setChecked(true); + ui->typeLocalCheckBox->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, false); } @@ -286,6 +371,21 @@ void AddFeedDialog::setActiveForumId(const std::string &forumId) } } +void AddFeedDialog::setActivePostedId(const std::string &postedId) +{ + if (mStateHelper->isLoading(TOKEN_TYPE_POSTED_GROUPS)) { + mFillPostedId = postedId; + return; + } + + int index = ui->postedComboBox->findData(QString::fromStdString(postedId)); + if (index >= 0) { + ui->postedComboBox->setCurrentIndex(index); + } else { + ui->postedComboBox->setCurrentIndex(0); + } +} + void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) { feedInfo.parentId = mParentId; @@ -294,18 +394,27 @@ void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) feedInfo.url = ui->urlLineEdit->text().toUtf8().constData(); feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked(); feedInfo.flag.updateForumInfo = ui->updateForumInfoCheckBox->isChecked() && ui->updateForumInfoCheckBox->isEnabled(); + feedInfo.flag.updatePostedInfo = ui->updatePostedInfoCheckBox->isChecked() && ui->updatePostedInfoCheckBox->isEnabled(); + feedInfo.flag.postedFirstImage = ui->postedFirstImageCheckBox->isChecked() && ui->postedFirstImageCheckBox->isEnabled(); + feedInfo.flag.postedOnlyImage = ui->postedOnlyImageCheckBox->isChecked() && ui->postedOnlyImageCheckBox->isEnabled(); feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked(); feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked(); feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData(); - feedInfo.flag.forum = ui->typeForumRadio->isChecked(); + feedInfo.flag.forum = ui->typeForumCheckBox->isChecked(); if (feedInfo.flag.forum) { feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); } + feedInfo.flag.posted = ui->typePostedCheckBox->isChecked(); + + if (feedInfo.flag.posted) { + feedInfo.postedId = ui->postedComboBox->itemData(ui->postedComboBox->currentIndex()).toString().toStdString(); + } + feedInfo.flag.authentication = ui->useAuthenticationCheckBox->isChecked(); feedInfo.user = ui->userLineEdit->text().toUtf8().constData(); feedInfo.password = ui->passwordLineEdit->text().toUtf8().constData(); @@ -382,10 +491,10 @@ void AddFeedDialog::requestForumGroups() RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); + mForumTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); uint32_t token; - mTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_FORUM_GROUPS); + mForumTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_FORUM_GROUPS); } void AddFeedDialog::loadForumGroups(const uint32_t &token) @@ -416,9 +525,50 @@ void AddFeedDialog::loadForumGroups(const uint32_t &token) } } +void AddFeedDialog::requestPostedGroups() +{ + mStateHelper->setLoading(TOKEN_TYPE_POSTED_GROUPS, true); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + mPostedTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_POSTED_GROUPS); + + uint32_t token; + mPostedTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_POSTED_GROUPS); +} + +void AddFeedDialog::loadPostedGroups(const uint32_t &token) +{ + std::vector groups; + rsPosted->getGroupData(token, groups); + + ui->postedComboBox->clear(); + + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsPostedGroup &group = *it; + + /* show only own posted */ + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags) && !group.mMeta.mAuthorId.isNull()) { + ui->postedComboBox->addItem(QString::fromUtf8(group.mMeta.mGroupName.c_str()), QString::fromStdString(group.mMeta.mGroupId.toStdString())); + } + } + + /* insert empty item */ + ui->postedComboBox->insertItem(0, "", ""); + ui->postedComboBox->setCurrentIndex(0); + + mStateHelper->setLoading(TOKEN_TYPE_POSTED_GROUPS, false); + + if (!mFillPostedId.empty()) { + setActivePostedId(mFillPostedId); + mFillPostedId.clear(); + } +} + void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { - if (queue == mTokenQueue) + if (queue == mForumTokenQueue) { /* now switch on req */ switch(req.mUserType) @@ -433,4 +583,20 @@ void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req } } + + if (queue == mPostedTokenQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case TOKEN_TYPE_POSTED_GROUPS: + loadPostedGroups(req.mToken); + break; + + default: + std::cerr << "AddFeedDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + + } + } } diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h index 111238d33..e557580e1 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.h +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -53,7 +53,10 @@ private slots: void useStandardUpdateIntervalToggled(); void useStandardProxyToggled(); void typeForumToggled(); - void denyForumToggled(); + void postedFirstImageToggled(); + void typePostedToggled(); + void typeLocalToggled(); + void denyForumAndPostedToggled(); void validate(); void createFeed(); void preview(); @@ -63,9 +66,12 @@ private: void processSettings(bool load); void getFeedInfo(FeedInfo &feedInfo); void setActiveForumId(const std::string &forumId); + void setActivePostedId(const std::string &postedId); void requestForumGroups(); void loadForumGroups(const uint32_t &token); + void requestPostedGroups(); + void loadPostedGroups(const uint32_t &token); private: RsFeedReader *mFeedReader; @@ -73,13 +79,15 @@ private: uint32_t mFeedId; uint32_t mParentId; std::string mFillForumId; + std::string mFillPostedId; RsFeedTransformationType mTransformationType; std::list mXPathsToUse; std::list mXPathsToRemove; std::string mXslt; - TokenQueue *mTokenQueue; + TokenQueue *mForumTokenQueue; + TokenQueue *mPostedTokenQueue; UIStateHelper *mStateHelper; Ui::AddFeedDialog *ui; diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index a10cec8a4..f3bcaf85f 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -50,7 +50,7 @@ Type - + 6 @@ -63,27 +63,75 @@ 6 - - - - - - Forum - - - - - - - + + + + + 0 + 0 + + + + Forum + + - - + + + + + Local Feed + + + + + + Update forum information + + + + + + + + + + + + Board + + + + + + + + + Update board information + + + + + + + Only image + + + + + + + Use first image as board image + + + + + @@ -309,7 +357,6 @@ 11 - 75 true true @@ -377,13 +424,6 @@ - - - - Update forum information - - - @@ -398,6 +438,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -423,22 +476,31 @@ urlLineEdit nameLineEdit descriptionPlainTextEdit - typeForumRadio + typeForumCheckBox forumComboBox + updateForumInfoCheckBox + typePostedCheckBox + postedComboBox + updatePostedInfoCheckBox + postedFirstImageCheckBox + checkBox + typeLocalCheckBox activatedCheckBox useInfoFromFeedCheckBox - updateForumInfoCheckBox + embedImagesCheckBox + saveCompletePageCheckBox + previewButton useAuthenticationCheckBox userLineEdit passwordLineEdit useStandardStorageTimeCheckBox + clearCachePushButton storageTimeSpinBox useStandardUpdateInterval updateIntervalSpinBox useStandardProxyCheckBox proxyAddressLineEdit proxyPortSpinBox - buttonBox diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp index 1550bc636..96198f400 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp @@ -245,9 +245,19 @@ void FeedReaderMessageWidget::setFeedId(uint32_t feedId) ui->msgReadAllButton->setEnabled(false); ui->msgTreeWidget->setPlaceholderText(""); } else { - if (mFeedInfo.flag.forum) { + if (mFeedInfo.flag.forum || mFeedInfo.flag.posted) { ui->msgReadAllButton->setEnabled(false); - ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum")); + + if (mFeedInfo.flag.forum && mFeedInfo.flag.posted) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum and the board")); + } else { + if (mFeedInfo.flag.forum) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum")); + } + if (mFeedInfo.flag.posted) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the board")); + } + } } else { ui->msgReadAllButton->setEnabled(true); ui->msgTreeWidget->setPlaceholderText(""); diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp index 99c537498..fefb3ed32 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -109,9 +109,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT: errorText = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); break; - case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: - errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); - break; +// case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: +// errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); +// break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND: errorText = QApplication::translate("FeedReaderStringDefs", "Forum not found"); break; @@ -121,6 +121,18 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR: errorText = QApplication::translate("FeedReaderStringDefs", "Forum has no author"); break; +// case RS_FEED_ERRORSTATE_PROCESS_POSTED_CREATE: +// errorText = QApplication::translate("FeedReaderStringDefs", "Can't create board"); +// break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND: + errorText = QApplication::translate("FeedReaderStringDefs", "Board not found"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN: + errorText = QApplication::translate("FeedReaderStringDefs", "You are not admin of the board"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR: + errorText = QApplication::translate("FeedReaderStringDefs", "Board has no author"); + break; case RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR: errorText = QApplication::translate("FeedReaderStringDefs", "Can't read html"); diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index bf524ad0c..7158d29ee 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -42,10 +42,14 @@ enum RsFeedReaderErrorState { /* process */ RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, - RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, +// RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND = 101, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR = 103, +// RS_FEED_ERRORSTATE_PROCESS_POSTED_CREATE = 104, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND = 105, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN = 106, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR = 107, RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR = 150, RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR = 151, @@ -102,6 +106,8 @@ public: flag.deactivated = false; flag.forum = false; flag.updateForumInfo = false; + flag.posted = false; + flag.updatePostedInfo = false; flag.embedImages = false; flag.saveCompletePage = false; flag.preview = false; @@ -122,6 +128,7 @@ public: time_t lastUpdate; uint32_t storageTime; std::string forumId; + std::string postedId; WorkState workstate; RsFeedReaderErrorState errorState; std::string errorString; @@ -141,6 +148,10 @@ public: bool deactivated : 1; bool forum : 1; bool updateForumInfo : 1; + bool posted : 1; + bool updatePostedInfo : 1; + bool postedFirstImage : 1; + bool postedOnlyImage : 1; bool embedImages : 1; bool saveCompletePage : 1; bool preview : 1; diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index 89cde2fe0..f366ccc9c 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -9,7 +9,27 @@ - + + Board + + + + + Update board information + + + + + Only image + + + + + Use first image as board image + + + + Authentication (not yet supported) @@ -99,22 +119,22 @@ - + Type - + Forum - + Local Feed - + Transformation @@ -144,12 +164,12 @@ - + Update forum information - + Save complete web page (experimental for local feeds) @@ -164,18 +184,18 @@ - + Name: - + Feed Details - - + + Edit feed @@ -277,7 +297,7 @@ FeedReaderDialog - + Feeds @@ -402,7 +422,7 @@ FeedReaderFeedItem - + Expand @@ -542,12 +562,22 @@ - + The messages will be added to the forum - + + The messages will be added to the forum and the board + + + + + The messages will be added to the board + + + + No name @@ -659,12 +689,12 @@ - + Unknown - + Internal download error @@ -699,12 +729,7 @@ - - Can't create forum - - - - + Forum not found @@ -718,6 +743,21 @@ Forum has no author + + + Board not found + + + + + You are not admin of the board + + + + + Board has no author + + Can't read html @@ -790,7 +830,7 @@ - + Name: @@ -825,7 +865,7 @@ - + Title: diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index d70591c36..4c2eacaaf 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -24,6 +24,7 @@ #include "rsitems/rsconfigitems.h" #include "retroshare/rsiface.h" #include "retroshare/rsgxsforums.h" +#include "retroshare/rsposted.h" #include "util/rsstring.h" #include "util/rstime.h" #include "gxs/rsgenexchange.h" @@ -34,6 +35,7 @@ RsFeedReader *rsFeedReader = NULL; #define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour #define FEEDREADER_FORUM_PREFIX "RSS: " +#define FEEDREADER_POSTED_PREFIX "RSS: " #define MAX_REQUEST_AGE 30 // 30 seconds @@ -41,7 +43,7 @@ RsFeedReader *rsFeedReader = NULL; * #define FEEDREADER_DEBUG *********/ -p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums) +p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums, RsPosted *posted) : RsPQIService(RS_SERVICE_TYPE_PLUGIN_FEEDREADER, 5, pgHandler), mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mPreviewMutex("p3FeedReaderPreview") { @@ -55,6 +57,7 @@ p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums) mStandardProxyPort = 0; mLastClean = 0; mForums = forums; + mPosted = posted; mNotify = NULL; mSaveInBackground = false; mStopped = false; @@ -92,6 +95,7 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.updateInterval = feed->updateInterval; info.lastUpdate = feed->lastUpdate; info.forumId = feed->forumId; + info.postedId = feed->postedId; info.storageTime = feed->storageTime; info.errorState = feed->errorState; info.errorString = feed->errorString; @@ -110,6 +114,10 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED); info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM); info.flag.updateForumInfo = (feed->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO); + info.flag.posted = (feed->flag & RS_FEED_FLAG_POSTED); + info.flag.updatePostedInfo = (feed->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO); + info.flag.postedFirstImage = (feed->flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE); + info.flag.postedOnlyImage = (feed->flag & RS_FEED_FLAG_POSTED_ONLY_IMAGE); info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); @@ -151,6 +159,7 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) feed->storageTime = info.storageTime; feed->forumId = info.forumId; + feed->postedId = info.postedId; feed->transformationType = info.transformationType; feed->xpathsToUse.ids = info.xpathsToUse; @@ -193,6 +202,21 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) if (info.flag.updateForumInfo) { feed->flag |= RS_FEED_FLAG_UPDATE_FORUM_INFO; } + if (info.flag.posted) { + feed->flag |= RS_FEED_FLAG_POSTED; + } + if (info.flag.updatePostedInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_POSTED_INFO; + } + if (info.flag.updatePostedInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_POSTED_INFO; + } + if (info.flag.postedFirstImage) { + feed->flag |= RS_FEED_FLAG_POSTED_FIRST_IMAGE; + } + if (info.flag.postedOnlyImage) { + feed->flag |= RS_FEED_FLAG_POSTED_ONLY_IMAGE; + } } static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) @@ -478,6 +502,9 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) std::string forumId; std::string forumName; std::string forumDescription; + std::string postedId; + std::string postedName; + std::string postedDescription; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -521,6 +548,7 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) RsFeedReaderFeed *fi = feedIt->second; std::string oldForumId = fi->forumId; + std::string oldPostedId = fi->postedId; std::string oldName = fi->name; std::string oldDescription = fi->description; @@ -534,6 +562,15 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) forumDescription = fi->description; forumName.insert(0, FEEDREADER_FORUM_PREFIX); } + + if ((fi->flag & RS_FEED_FLAG_POSTED) && (fi->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO) && !fi->postedId.empty() && + (fi->postedId != oldPostedId || fi->name != oldName || fi->description != oldDescription)) { + /* name or description changed, update posted */ + postedId = fi->postedId; + postedName = fi->name; + postedDescription = fi->description; + postedName.insert(0, FEEDREADER_POSTED_PREFIX); + } } IndicateConfigChanged(); @@ -550,6 +587,14 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) //TODO: error } + if (!postedId.empty()) { + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) { + updatePostedGroup(postedGroup, postedName, postedDescription); + } + //TODO: error + } + return RS_FEED_ADD_RESULT_SUCCESS; } @@ -682,6 +727,7 @@ bool p3FeedReader::addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) fi->updateInterval = 0; fi->lastUpdate = 0; fi->forumId.clear(); + fi->postedId.clear(); fi->storageTime = 0; mFeeds[fi->feedId] = fi; @@ -1885,8 +1931,12 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list addedMsgs; std::string forumId; - RsGxsId authorId; + RsGxsId forumAuthorId; std::list forumMsgs; + std::string postedId; + RsGxsId postedAuthorId; + std::list postedMsgs; + uint32_t feedFlag = 0; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1903,7 +1953,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listsecond; bool forum = (fi->flag & RS_FEED_FLAG_FORUM) && !fi->preview; + bool posted = (fi->flag & RS_FEED_FLAG_POSTED) && !fi->preview; RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK; + feedFlag = fi->flag; if (forum && !msgs.empty()) { if (mForums) { @@ -1913,9 +1965,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listforumId), forumGroup)) { if (IS_GROUP_PUBLISHER(forumGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(forumGroup.mMeta.mSubscribeFlags)) { forumId = fi->forumId; - authorId = forumGroup.mMeta.mAuthorId; + forumAuthorId = forumGroup.mMeta.mAuthorId; - if (authorId.isNull()) { + if (forumAuthorId.isNull()) { errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR; } } else { @@ -1933,6 +1985,34 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listpostedId.empty()) { + /* check posted */ + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(fi->postedId), postedGroup)) { + if (IS_GROUP_PUBLISHER(postedGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(postedGroup.mMeta.mSubscribeFlags)) { + postedId = fi->postedId; + postedAuthorId = postedGroup.mMeta.mAuthorId; + + if (postedAuthorId.isNull()) { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR; + } + } else { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN; + } + } else { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - posted id is empty (" << fi->name << ")" << std::endl; + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not set" << std::endl; + } + } + /* process msgs */ if (errorState == RS_FEED_ERRORSTATE_OK) { /* process msgs */ @@ -1949,9 +2029,14 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listmsgId, "%lu", mNextMsgId++); } - if (forum) { + if (forum || posted) { miNew->flag = RS_FEEDMSG_FLAG_DELETED; - forumMsgs.push_back(*miNew); + if (forum) { + forumMsgs.push_back(*miNew); + } + if (posted) { + postedMsgs.push_back(*miNew); + } miNew->description.clear(); miNew->descriptionTransformed.clear(); } else { @@ -1996,7 +2081,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listcreateMsg(token, forumMsg) && waitForToken(token)) { + if (mForums->createMsg(token, forumMsg) && waitForToken(mForums, token)) { RsGxsGrpMsgIdPair msgPair; if (mForums->acknowledgeMsg(token, msgPair)) { /* set to new */ @@ -2026,6 +2111,67 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list(mPosted); + if (genExchange) { + /* add messages as posted messages */ + std::list::iterator msgIt; + for (msgIt = postedMsgs.begin(); msgIt != postedMsgs.end(); ++msgIt) { + RsFeedReaderMsg &mi = *msgIt; + + /* convert to posted messages */ + RsPostedPost postedPost; + postedPost.mMeta.mGroupId = RsGxsGroupId(postedId); + postedPost.mMeta.mMsgName = mi.title; + postedPost.mMeta.mAuthorId = postedAuthorId; + postedPost.mLink = mi.link; + + std::string description; + if (feedFlag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) { + if (!mi.postedFirstImage.empty()) { + /* use first image as image for posted and description without image as notes */ + postedPost.mImage.copy(mi.postedFirstImage.data(), mi.postedFirstImage.size()); + if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { + /* ignore description */ + } else { + description = mi.postedDescriptionWithoutFirstImage; + } + } else { + if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { + /* ignore messages without image */ + continue; + } + description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + } + } else { + description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + } + + postedPost.mNotes = description; + + uint32_t token; + if (mPosted->createPost(token, postedPost) && waitForToken(mPosted, token)) { + RsGxsGrpMsgIdPair msgPair; + if (mPosted->acknowledgeMsg(token, msgPair)) { + /* set to new */ + genExchange->setMsgStatusFlags(token, msgPair, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD); + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't add posted message " << mi.title << " for feed " << postedId << std::endl; +#endif + } + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not derived from RsGenExchange" << std::endl; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not set" << std::endl; + } + } + if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -2080,6 +2226,9 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s std::string forumId; std::string forumName; std::string forumDescription; + std::string postedId; + std::string postedName; + std::string postedDescription; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -2118,6 +2267,14 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s forumDescription = fi->description; forumName.insert(0, FEEDREADER_FORUM_PREFIX); } + + if ((fi->flag & RS_FEED_FLAG_POSTED) && (fi->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO) && !fi->postedId.empty() && !preview) { + /* change posted too */ + postedId = fi->postedId; + postedName = fi->name; + postedDescription = fi->description; + postedName.insert(0, FEEDREADER_POSTED_PREFIX); + } } if (changed) { @@ -2137,6 +2294,14 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s } //TODO: error } + + if (!postedId.empty()) { + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) { + updatePostedGroup(postedGroup, postedName, postedDescription); + } + //TODO: error + } } bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup) @@ -2159,7 +2324,7 @@ bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &f uint32_t token; mForums->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); - if (!waitForToken(token)) { + if (!waitForToken(mForums, token)) { std::cerr << "p3FeedReader::getForumGroup - waitForToken for request failed" << std::endl; return false; } @@ -2202,7 +2367,7 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std return false; } - if (!waitForToken(token)) { + if (!waitForToken(mForums, token)) { std::cerr << "p3FeedReader::updateForumGroup - waitForToken for update failed" << std::endl; return false; } @@ -2211,13 +2376,85 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std return true; } -bool p3FeedReader::waitForToken(uint32_t token) +bool p3FeedReader::getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup) { - if (!mForums) { + if (!mPosted) { + std::cerr << "p3FeedReader::getPostedGroup - can't get posted group " << groupId.toStdString() << ", member mPosted is not set" << std::endl; return false; } - RsTokenService *service = mForums->getTokenService(); + if (groupId.isNull()) { + std::cerr << "p3FeedReader::getPostedGroup - group id is not valid" << std::endl; + return false; + } + + std::list grpIds; + grpIds.push_back(groupId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mPosted->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::getPostedGroup - waitForToken for request failed" << std::endl; + return false; + } + + std::vector groups; + if (!mPosted->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getPostedGroup - Error getting data" << std::endl; + return false; + } + + if (groups.size() != 1) { + std::cerr << "p3FeedReader::getPostedGroup - Wrong number of items" << std::endl; + return false; + } + + postedGroup = groups[0]; + + return true; +} + +bool p3FeedReader::updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription) +{ + if (!mPosted) { + std::cerr << "p3FeedReader::updatePostedGroup - can't change posted " << postedGroup.mMeta.mGroupId.toStdString() << ", member mPosted is not set" << std::endl; + return false; + } + + if (postedGroup.mMeta.mGroupName == groupName && postedGroup.mDescription == groupDescription) { + /* No change */ + return true; + } + + RsPostedGroup newPostedGroup = postedGroup; + newPostedGroup.mMeta.mGroupName = groupName; + newPostedGroup.mDescription = groupDescription; + + uint32_t token; + if (!mPosted->updateGroup(token, newPostedGroup)) { + std::cerr << "p3FeedReader::updatePostedGroup - can't change posted " << newPostedGroup.mMeta.mGroupId.toStdString() << std::endl; + return false; + } + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::updatePostedGroup - waitForToken for update failed" << std::endl; + return false; + } + + /* Posted updated */ + return true; +} + +bool p3FeedReader::waitForToken(RsGxsIfaceHelper *interface, uint32_t token) +{ + if (!interface) { + return false; + } + + RsTokenService *service = interface->getTokenService(); int count = MAX_REQUEST_AGE * 2; while (!mStopped) { diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index 08fa3619b..d60b63ca2 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -33,11 +33,14 @@ class p3FeedReaderThread; class RsGxsForums; struct RsGxsForumGroup; +class RsPosted; +struct RsPostedGroup; +class RsGxsIfaceHelper; class p3FeedReader : public RsPQIService, public RsFeedReader { public: - p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums); + p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums, RsPosted *posted); /****************** FeedReader Interface *************/ virtual void stop(); @@ -92,7 +95,9 @@ public: bool getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup); bool updateForumGroup(const RsGxsForumGroup &forumGroup, const std::string &groupName, const std::string &groupDescription); - bool waitForToken(uint32_t token); + bool getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup); + bool updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription); + bool waitForToken(RsGxsIfaceHelper *interface, uint32_t token); protected: /****************** p3Config STUFF *******************/ @@ -109,6 +114,7 @@ private: private: time_t mLastClean; RsGxsForums *mForums; + RsPosted *mPosted; RsFeedReaderNotify *mNotify; volatile bool mStopped; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 130d2fac1..00da7a007 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -1076,12 +1076,15 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (isRunning()) { /* process description */ + bool processPostedFirstImage = (feed.flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) ? TRUE : FALSE; + //long todo; // encoding HTMLWrapper html; if (html.readHTML(msg->description.c_str(), url.c_str())) { xmlNodePtr root = html.getRootElement(); if (root) { std::list nodesToDelete; + xmlNodePtr postedFirstImageNode = NULL; /* process all children */ std::list nodes; @@ -1212,6 +1215,12 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); if (html.setAttr(node, "src", imageBase64.c_str())) { removeImage = false; + + if (processPostedFirstImage && postedFirstImageNode == NULL) { + /* set first image */ + msg->postedFirstImage = data; + postedFirstImageNode = node; + } } } } @@ -1247,7 +1256,22 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (result == RS_FEED_ERRORSTATE_OK) { if (isRunning()) { - if (!html.saveHTML(msg->description)) { + if (html.saveHTML(msg->description)) { + if (postedFirstImageNode) { + /* Remove first image and create description without the image */ + xmlUnlinkNode(postedFirstImageNode); + xmlFreeNode(postedFirstImageNode); + + if (!html.saveHTML(msg->postedDescriptionWithoutFirstImage)) { + errorString = html.lastError(); +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; + std::cerr << " Error: " << errorString << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + } + } + } else { errorString = html.lastError(); #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.cc b/plugins/FeedReader/services/rsFeedReaderItems.cc index 04a6c8f1e..5a2ad4fe1 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.cc +++ b/plugins/FeedReader/services/rsFeedReaderItems.cc @@ -46,6 +46,7 @@ void RsFeedReaderFeed::clear() storageTime = 0; flag = 0; forumId.clear(); + postedId.clear(); description.clear(); icon.clear(); errorState = RS_FEED_ERRORSTATE_OK; @@ -85,6 +86,7 @@ uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item) s += item->xpathsToUse.TlvSize(); s += item->xpathsToRemove.TlvSize(); s += GetTlvStringSize(item->xslt); + s += GetTlvStringSize(item->postedId); return s; } @@ -108,7 +110,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u offset += 8; /* add values */ - ok &= setRawUInt16(data, tlvsize, &offset, 2); /* version */ + ok &= setRawUInt16(data, tlvsize, &offset, 3); /* version */ ok &= setRawUInt32(data, tlvsize, &offset, item->feedId); ok &= setRawUInt32(data, tlvsize, &offset, item->parentId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->url); @@ -124,6 +126,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u ok &= setRawUInt32(data, tlvsize, &offset, item->storageTime); ok &= setRawUInt32(data, tlvsize, &offset, item->flag); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->postedId); ok &= setRawUInt32(data, tlvsize, &offset, item->errorState); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString); ok &= setRawUInt32(data, tlvsize, &offset, item->transformationType); @@ -208,6 +211,9 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * ok &= getRawUInt32(data, rssize, &offset, &(item->storageTime)); ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + if (version >= 3) { + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->postedId); + } uint32_t errorState = 0; ok &= getRawUInt32(data, rssize, &offset, &errorState); item->errorState = (RsFeedReaderErrorState) errorState; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index d2ee7574e..39d604f46 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -34,17 +34,21 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; /**************************************************************************/ -#define RS_FEED_FLAG_FOLDER 0x001 -#define RS_FEED_FLAG_INFO_FROM_FEED 0x002 -#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x004 -#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x008 -#define RS_FEED_FLAG_STANDARD_PROXY 0x010 -#define RS_FEED_FLAG_AUTHENTICATION 0x020 -#define RS_FEED_FLAG_DEACTIVATED 0x040 -#define RS_FEED_FLAG_FORUM 0x080 -#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x100 -#define RS_FEED_FLAG_EMBED_IMAGES 0x200 -#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x400 +#define RS_FEED_FLAG_FOLDER 0x0001 +#define RS_FEED_FLAG_INFO_FROM_FEED 0x0002 +#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x0004 +#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x0008 +#define RS_FEED_FLAG_STANDARD_PROXY 0x0010 +#define RS_FEED_FLAG_AUTHENTICATION 0x0020 +#define RS_FEED_FLAG_DEACTIVATED 0x0040 +#define RS_FEED_FLAG_FORUM 0x0080 +#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x0100 +#define RS_FEED_FLAG_EMBED_IMAGES 0x0200 +#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x0400 +#define RS_FEED_FLAG_POSTED 0x0800 +#define RS_FEED_FLAG_UPDATE_POSTED_INFO 0x1000 +#define RS_FEED_FLAG_POSTED_FIRST_IMAGE 0x2000 +#define RS_FEED_FLAG_POSTED_ONLY_IMAGE 0x4000 class RsFeedReaderFeed : public RsItem { @@ -76,6 +80,7 @@ public: time_t lastUpdate; uint32_t flag; // RS_FEED_FLAG_... std::string forumId; + std::string postedId; uint32_t storageTime; std::string description; std::string icon; @@ -118,6 +123,10 @@ public: std::string descriptionTransformed; time_t pubDate; uint32_t flag; // RS_FEEDMSG_FLAG_... + + // Only in memory when receiving messages + std::vector postedFirstImage; + std::string postedDescriptionWithoutFirstImage; }; class RsFeedReaderSerialiser: public RsSerialType From 186976e2095f3cc13f1a4fe09fcae69facb43974 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 13 Apr 2023 15:53:14 +0200 Subject: [PATCH 10/18] FeedReader: The feed can be moved with drag and drop to a folder --- plugins/FeedReader/FeedReader.pro | 2 + plugins/FeedReader/gui/FeedReaderDialog.cpp | 37 ++++++ plugins/FeedReader/gui/FeedReaderDialog.h | 1 + plugins/FeedReader/gui/FeedReaderDialog.ui | 6 +- plugins/FeedReader/gui/FeedTreeWidget.cpp | 119 ++++++++++++++++++++ plugins/FeedReader/gui/FeedTreeWidget.h | 50 ++++++++ plugins/FeedReader/interface/rsFeedReader.h | 1 + plugins/FeedReader/lang/FeedReader_en.ts | 20 +++- plugins/FeedReader/services/p3FeedReader.cc | 56 +++++++++ plugins/FeedReader/services/p3FeedReader.h | 1 + 10 files changed, 285 insertions(+), 8 deletions(-) create mode 100644 plugins/FeedReader/gui/FeedTreeWidget.cpp create mode 100644 plugins/FeedReader/gui/FeedTreeWidget.h diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index b5dbbf43a..5c696b5c3 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -44,6 +44,7 @@ SOURCES = FeedReaderPlugin.cpp \ gui/FeedReaderFeedNotify.cpp \ gui/FeedReaderUserNotify.cpp \ gui/FeedReaderFeedItem.cpp \ + gui/FeedTreeWidget.cpp \ util/CURLWrapper.cpp \ util/XMLWrapper.cpp \ util/HTMLWrapper.cpp \ @@ -64,6 +65,7 @@ HEADERS = FeedReaderPlugin.h \ gui/FeedReaderFeedNotify.h \ gui/FeedReaderUserNotify.h \ gui/FeedReaderFeedItem.h \ + gui/FeedTreeWidget.h \ util/CURLWrapper.h \ util/XMLWrapper.h \ util/HTMLWrapper.h \ diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index abc2f1aa5..4c409a38c 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -84,9 +84,16 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n connect(ui->feedAddButton, SIGNAL(clicked()), this, SLOT(newFeed())); connect(ui->feedProcessButton, SIGNAL(clicked()), this, SLOT(processFeed())); + connect(ui->feedTreeWidget, SIGNAL(feedReparent(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(feedTreeReparent(QTreeWidgetItem*,QTreeWidgetItem*))); + mFeedCompareRole = new RSTreeWidgetItemCompareRole; mFeedCompareRole->setRole(COLUMN_FEED_NAME, ROLE_FEED_SORT); + /* enable drag and drop */ + ui->feedTreeWidget->setAcceptDrops(true); + ui->feedTreeWidget->setDragEnabled(true); + ui->feedTreeWidget->setDragDropMode(QAbstractItemView::InternalMove); + /* initialize root item */ mRootItem = new QTreeWidgetItem(ui->feedTreeWidget); QString name = tr("Message Folders"); @@ -395,6 +402,9 @@ void FeedReaderDialog::updateFeeds(uint32_t parentId, QTreeWidgetItem *parentIte mOpenFeedIds->removeAt(index); } } + } else { + /* disable drop */ + item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); } } @@ -832,3 +842,30 @@ void FeedReaderDialog::processFeed() mFeedReader->processFeed(feedId); } + +void FeedReaderDialog::feedTreeReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent) +{ + if (!item || ! newParent) { + return; + } + + uint32_t feedId = item->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toUInt(); + uint32_t parentId = newParent->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toUInt(); + + if (feedId == 0) { + return; + } + + RsFeedAddResult result = mFeedReader->setParent(feedId, parentId); + if (FeedReaderStringDefs::showError(this, result, tr("Move feed"), tr("Cannot move feed."))) { + return; + } + + bool expanded = item->isExpanded(); + item->parent()->removeChild(item); + newParent->addChild(item); + item->setExpanded(expanded); + newParent->setExpanded(true); + + calculateFeedItems(); +} diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h index a221cfe64..d684f1f4b 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.h +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -61,6 +61,7 @@ private slots: void editFeed(); void activateFeed(); void processFeed(); + void feedTreeReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent); void messageTabCloseRequested(int index); void messageTabChanged(int index); diff --git a/plugins/FeedReader/gui/FeedReaderDialog.ui b/plugins/FeedReader/gui/FeedReaderDialog.ui index 5eed95bc7..b6b004d69 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.ui +++ b/plugins/FeedReader/gui/FeedReaderDialog.ui @@ -150,7 +150,7 @@ - + Qt::CustomContextMenu @@ -186,9 +186,9 @@ - RSTreeWidget + FeedTreeWidget QTreeWidget -
gui/common/RSTreeWidget.h
+
gui/FeedTreeWidget.h
RSTabWidget diff --git a/plugins/FeedReader/gui/FeedTreeWidget.cpp b/plugins/FeedReader/gui/FeedTreeWidget.cpp new file mode 100644 index 000000000..37baaf235 --- /dev/null +++ b/plugins/FeedReader/gui/FeedTreeWidget.cpp @@ -0,0 +1,119 @@ +/******************************************************************************* + * plugins/FeedReader/gui/FeedTreeWidget.cpp * + * * + * Copyright (C) 2012 RetroShare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include +#include "FeedTreeWidget.h" + +FeedTreeWidget::FeedTreeWidget(QWidget *parent) : RSTreeWidget(parent) +{ + mDraggedItem = NULL; +} + +void FeedTreeWidget::dragEnterEvent(QDragEnterEvent *event) +{ + mDraggedItem = currentItem(); + RSTreeWidget::dragEnterEvent(event); +} + +void FeedTreeWidget::dragLeaveEvent(QDragLeaveEvent *event) +{ + RSTreeWidget::dragLeaveEvent(event); + mDraggedItem = NULL; +} + +bool FeedTreeWidget::canDrop(QDropEvent *event, QTreeWidgetItem **dropItem) +{ + if (dropItem) { + *dropItem = NULL; + } + + if (!mDraggedItem) { + /* no drag item */ + return false; + } + + QModelIndex droppedIndex = indexAt(event->pos()); + if (!droppedIndex.isValid()) { + /* no drop target */ + return false; + } + + QTreeWidgetItem *dropItemIntern = itemFromIndex(droppedIndex); + if (!dropItemIntern) { + /* no drop item */ + return false; + } + + if ((dropItemIntern->flags() & Qt::ItemIsDropEnabled) == 0) { + /* drop is disabled */ + return false; + } + + if (dropItemIntern == mDraggedItem->parent()) { + /* drag item parent */ + return false; + } + + if (dropItem) { + *dropItem = dropItemIntern; + } + + return true; +} + +void FeedTreeWidget::dragMoveEvent(QDragMoveEvent *event) +{ + if (!canDrop(event)) { + event->ignore(); + return; + } + + RSTreeWidget::dragMoveEvent(event); +} + +void FeedTreeWidget::dropEvent(QDropEvent *event) +{ + QTreeWidgetItem *dropItem; + if (!canDrop(event, &dropItem)) { + event->ignore(); + return; + } + + if (!mDraggedItem) { + /* no drag item */ + event->ignore(); + return; + } + + QTreeWidgetItem *draggedParent = mDraggedItem->parent(); + if (!draggedParent) { + /* no drag item parent */ + event->ignore(); + return; + } + + if (!dropItem) { + /* no drop item */ + event->ignore(); + return; + } + + emit feedReparent(mDraggedItem, dropItem); +} diff --git a/plugins/FeedReader/gui/FeedTreeWidget.h b/plugins/FeedReader/gui/FeedTreeWidget.h new file mode 100644 index 000000000..e9eb197a9 --- /dev/null +++ b/plugins/FeedReader/gui/FeedTreeWidget.h @@ -0,0 +1,50 @@ +/******************************************************************************* + * plugins/FeedReader/gui/FeedTreeWidget.h * + * * + * Copyright (C) 2012 by Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef _FEEDTREEWIDGET_H +#define _FEEDTREEWIDGET_H + +#include "gui/common/RSTreeWidget.h" + +/* Subclassing RSTreeWidget */ +class FeedTreeWidget : public RSTreeWidget +{ + Q_OBJECT + +public: + FeedTreeWidget(QWidget *parent = 0); + +Q_SIGNALS: + void feedReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragLeaveEvent(QDragLeaveEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + +private: + bool canDrop(QDropEvent *event, QTreeWidgetItem **dropItem = NULL); + +private: + QTreeWidgetItem *mDraggedItem; +}; + +#endif diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index 7158d29ee..6ff39cdc9 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -216,6 +216,7 @@ public: virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name) = 0; virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0; + virtual RsFeedAddResult setParent(uint32_t feedId, uint32_t parentId) = 0; virtual bool removeFeed(uint32_t feedId) = 0; virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; virtual void getFeedList(uint32_t parentId, std::list &feedInfos) = 0; diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index f366ccc9c..500c46810 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -194,7 +194,7 @@ - + Edit feed @@ -312,7 +312,7 @@ - + Message Folders @@ -362,7 +362,7 @@ - + No name @@ -418,6 +418,16 @@ Please enter a new name for the folder + + + Move feed + + + + + Cannot move feed. + + FeedReaderFeedItem @@ -520,7 +530,7 @@ - + Title @@ -612,7 +622,7 @@ - + Hide diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 4c2eacaaf..5d861710b 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -598,6 +598,62 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) return RS_FEED_ADD_RESULT_SUCCESS; } +RsFeedAddResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) +{ + bool changed = false; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - set parent " << parentId << std::endl; +#endif + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - feed id " << feedId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + } + + if (parentId) { + /* check parent id */ + std::map::iterator parentIt = mFeeds.find(parentId); + if (parentIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - parent id " << parentId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + } + + if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - parent " << parentIt->second->name << " is no folder" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + } + } + + RsFeedReaderFeed *fi = feedIt->second; + + if (fi->parentId != parentId) { + fi->parentId = parentId; + changed = true; + } + } + + if (changed) { + IndicateConfigChanged(); + + if (mNotify) { + mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); + } + } + + return RS_FEED_ADD_RESULT_SUCCESS; +} + void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) { if (!fi) { diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index d60b63ca2..d98259a3b 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -59,6 +59,7 @@ public: virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name); virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId); virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo); + virtual RsFeedAddResult setParent(uint32_t feedId, uint32_t parentId); virtual bool removeFeed(uint32_t feedId); virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId); virtual void getFeedList(uint32_t parentId, std::list &feedInfos); From 63390fddee88f535b2710a351fd10520d19b86c6 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 13 Apr 2023 20:16:10 +0200 Subject: [PATCH 11/18] FeedReader: Renamed enum RsFeedAddResult to RsFeedResult --- plugins/FeedReader/gui/AddFeedDialog.cpp | 4 +- plugins/FeedReader/gui/FeedReaderDialog.cpp | 6 +-- .../FeedReader/gui/FeedReaderStringDefs.cpp | 14 ++--- plugins/FeedReader/gui/FeedReaderStringDefs.h | 2 +- plugins/FeedReader/interface/rsFeedReader.h | 52 +++++++++---------- plugins/FeedReader/services/p3FeedReader.cc | 48 ++++++++--------- plugins/FeedReader/services/p3FeedReader.h | 38 +++++++------- 7 files changed, 82 insertions(+), 82 deletions(-) diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index c99b29b7a..588428a8d 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -449,12 +449,12 @@ void AddFeedDialog::createFeed() if (mFeedId == 0) { /* add new feed */ - RsFeedAddResult result = mFeedReader->addFeed(feedInfo, mFeedId); + RsFeedResult result = mFeedReader->addFeed(feedInfo, mFeedId); if (FeedReaderStringDefs::showError(this, result, tr("Create feed"), tr("Cannot create feed."))) { return; } } else { - RsFeedAddResult result = mFeedReader->setFeed(mFeedId, feedInfo); + RsFeedResult result = mFeedReader->setFeed(mFeedId, feedInfo); if (FeedReaderStringDefs::showError(this, result, tr("Edit feed"), tr("Cannot change feed."))) { return; } diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index 4c409a38c..1c3d6ca8c 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -748,7 +748,7 @@ void FeedReaderDialog::newFolder() if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { uint32_t feedId; - RsFeedAddResult result = mFeedReader->addFolder(currentFeedId(), dialog.textValue().toUtf8().constData(), feedId); + RsFeedResult result = mFeedReader->addFolder(currentFeedId(), dialog.textValue().toUtf8().constData(), feedId); FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); } } @@ -801,7 +801,7 @@ void FeedReaderDialog::editFeed() dialog.setTextValue(item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString()); if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { - RsFeedAddResult result = mFeedReader->setFolder(feedId, dialog.textValue().toUtf8().constData()); + RsFeedResult result = mFeedReader->setFolder(feedId, dialog.textValue().toUtf8().constData()); FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); } } else { @@ -856,7 +856,7 @@ void FeedReaderDialog::feedTreeReparent(QTreeWidgetItem *item, QTreeWidgetItem * return; } - RsFeedAddResult result = mFeedReader->setParent(feedId, parentId); + RsFeedResult result = mFeedReader->setParent(feedId, parentId); if (FeedReaderStringDefs::showError(this, result, tr("Move feed"), tr("Cannot move feed."))) { return; } diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp index fefb3ed32..647c4cf7b 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -23,27 +23,27 @@ #include "FeedReaderStringDefs.h" -bool FeedReaderStringDefs::showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text) +bool FeedReaderStringDefs::showError(QWidget *parent, RsFeedResult result, const QString &title, const QString &text) { QString error; switch (result) { - case RS_FEED_ADD_RESULT_SUCCESS: + case RS_FEED_RESULT_SUCCESS: /* no error */ return false; - case RS_FEED_ADD_RESULT_FEED_NOT_FOUND: + case RS_FEED_RESULT_FEED_NOT_FOUND: error = QApplication::translate("FeedReaderStringDefs", "Feed not found."); break; - case RS_FEED_ADD_RESULT_PARENT_NOT_FOUND: + case RS_FEED_RESULT_PARENT_NOT_FOUND: error = QApplication::translate("FeedReaderStringDefs", "Parent not found."); break; - case RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER: + case RS_FEED_RESULT_PARENT_IS_NO_FOLDER: error = QApplication::translate("FeedReaderStringDefs", "Parent is no folder."); break; - case RS_FEED_ADD_RESULT_FEED_IS_FOLDER: + case RS_FEED_RESULT_FEED_IS_FOLDER: error = QApplication::translate("FeedReaderStringDefs", "Feed is a folder."); break; - case RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER: + case RS_FEED_RESULT_FEED_IS_NO_FOLDER: error = QApplication::translate("FeedReaderStringDefs", "Feed is no folder."); break; default: diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.h b/plugins/FeedReader/gui/FeedReaderStringDefs.h index f4b384c8f..587621e7d 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.h +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.h @@ -30,7 +30,7 @@ class QWidget; class FeedReaderStringDefs { public: - static bool showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text); + static bool showError(QWidget *parent, RsFeedResult result, const QString &title, const QString &text); static QString workState(FeedInfo::WorkState state); static QString errorString(const FeedInfo &feedInfo); static QString errorString(RsFeedReaderErrorState errorState, const std::string &errorString); diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index 6ff39cdc9..3de449ba0 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -60,14 +60,14 @@ enum RsFeedReaderErrorState { RS_FEED_ERRORSTATE_PROCESS_XSLT_NO_RESULT = 156 }; -enum RsFeedAddResult +enum RsFeedResult { - RS_FEED_ADD_RESULT_SUCCESS, - RS_FEED_ADD_RESULT_FEED_NOT_FOUND, - RS_FEED_ADD_RESULT_PARENT_NOT_FOUND, - RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER, - RS_FEED_ADD_RESULT_FEED_IS_FOLDER, - RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER + RS_FEED_RESULT_SUCCESS, + RS_FEED_RESULT_FEED_NOT_FOUND, + RS_FEED_RESULT_PARENT_NOT_FOUND, + RS_FEED_RESULT_PARENT_IS_NO_FOLDER, + RS_FEED_RESULT_FEED_IS_FOLDER, + RS_FEED_RESULT_FEED_IS_NO_FOLDER }; enum RsFeedTransformationType @@ -212,25 +212,25 @@ public: virtual bool getSaveInBackground() = 0; virtual void setSaveInBackground(bool saveInBackground) = 0; - virtual RsFeedAddResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) = 0; - virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name) = 0; - virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; - virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0; - virtual RsFeedAddResult setParent(uint32_t feedId, uint32_t parentId) = 0; - virtual bool removeFeed(uint32_t feedId) = 0; - virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; - virtual void getFeedList(uint32_t parentId, std::list &feedInfos) = 0; - virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo) = 0; - virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; - virtual bool removeMsg(uint32_t feedId, const std::string &msgId) = 0; - virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds) = 0; - virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; - virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos) = 0; - virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds) = 0; - virtual bool processFeed(uint32_t feedId) = 0; - virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read) = 0; - virtual bool retransformMsg(uint32_t feedId, const std::string &msgId) = 0; - virtual bool clearMessageCache(uint32_t feedId) = 0; + virtual RsFeedResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) = 0; + virtual RsFeedResult setFolder(uint32_t feedId, const std::string &name) = 0; + virtual RsFeedResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; + virtual RsFeedResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0; + virtual RsFeedResult setParent(uint32_t feedId, uint32_t parentId) = 0; + virtual bool removeFeed(uint32_t feedId) = 0; + virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; + virtual void getFeedList(uint32_t parentId, std::list &feedInfos) = 0; + virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo) = 0; + virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; + virtual bool removeMsg(uint32_t feedId, const std::string &msgId) = 0; + virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds) = 0; + virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; + virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos) = 0; + virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds) = 0; + virtual bool processFeed(uint32_t feedId) = 0; + virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read) = 0; + virtual bool retransformMsg(uint32_t feedId, const std::string &msgId) = 0; + virtual bool clearMessageCache(uint32_t feedId) = 0; virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) = 0; virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString) = 0; diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 5d861710b..104e137c6 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -366,7 +366,7 @@ void p3FeedReader::stopPreviewThreads_locked() } } -RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) +RsFeedResult p3FeedReader::addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) { feedId = 0; @@ -380,14 +380,14 @@ RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &na #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFolder - parent id " << parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFolder - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } @@ -407,10 +407,10 @@ RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &na mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name) +RsFeedResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name) { { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -424,19 +424,19 @@ RsFeedAddResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFolder - feed id " << feedId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + return RS_FEED_RESULT_FEED_NOT_FOUND; } if ((feedIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFolder - feed " << feedIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER; + return RS_FEED_RESULT_FEED_IS_NO_FOLDER; } RsFeedReaderFeed *fi = feedIt->second; if (fi->name == name) { - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } fi->name = name; } @@ -447,10 +447,10 @@ RsFeedAddResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId) +RsFeedResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId) { feedId = 0; @@ -468,14 +468,14 @@ RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFeed - parent id " << feedInfo.parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFeed - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } @@ -494,10 +494,10 @@ RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) +RsFeedResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) { std::string forumId; std::string forumName; @@ -518,14 +518,14 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - feed id " << feedId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + return RS_FEED_RESULT_FEED_NOT_FOUND; } if (feedIt->second->flag & RS_FEED_FLAG_FOLDER) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - feed " << feedIt->second->name << " is a folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_IS_FOLDER; + return RS_FEED_RESULT_FEED_IS_FOLDER; } if (feedInfo.parentId) { @@ -535,14 +535,14 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - parent id " << feedInfo.parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } @@ -595,10 +595,10 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) //TODO: error } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) +RsFeedResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) { bool changed = false; @@ -614,7 +614,7 @@ RsFeedAddResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setParent - feed id " << feedId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + return RS_FEED_RESULT_FEED_NOT_FOUND; } if (parentId) { @@ -624,14 +624,14 @@ RsFeedAddResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setParent - parent id " << parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setParent - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } @@ -651,7 +651,7 @@ RsFeedAddResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) } } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index d98259a3b..ac251b23a 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -55,25 +55,25 @@ public: virtual bool getSaveInBackground(); virtual void setSaveInBackground(bool saveInBackground); - virtual RsFeedAddResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId); - virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name); - virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId); - virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo); - virtual RsFeedAddResult setParent(uint32_t feedId, uint32_t parentId); - virtual bool removeFeed(uint32_t feedId); - virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId); - virtual void getFeedList(uint32_t parentId, std::list &feedInfos); - virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo); - virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo); - virtual bool removeMsg(uint32_t feedId, const std::string &msgId); - virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds); - virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); - virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos); - virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds); - virtual bool processFeed(uint32_t feedId); - virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read); - virtual bool retransformMsg(uint32_t feedId, const std::string &msgId); - virtual bool clearMessageCache(uint32_t feedId); + virtual RsFeedResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId); + virtual RsFeedResult setFolder(uint32_t feedId, const std::string &name); + virtual RsFeedResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId); + virtual RsFeedResult setFeed(uint32_t feedId, const FeedInfo &feedInfo); + virtual RsFeedResult setParent(uint32_t feedId, uint32_t parentId); + virtual bool removeFeed(uint32_t feedId); + virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId); + virtual void getFeedList(uint32_t parentId, std::list &feedInfos); + virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo); + virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo); + virtual bool removeMsg(uint32_t feedId, const std::string &msgId); + virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds); + virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); + virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos); + virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds); + virtual bool processFeed(uint32_t feedId); + virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read); + virtual bool retransformMsg(uint32_t feedId, const std::string &msgId); + virtual bool clearMessageCache(uint32_t feedId); virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString); virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString); From bcb4e527689b22f3279e01f456e23f30e8fc442b Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sun, 16 Apr 2023 22:43:40 +0200 Subject: [PATCH 12/18] Added methods to set title, notes and link on PostedCreatePostDialog from outside --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 15 +++++++++++++++ .../src/gui/Posted/PostedCreatePostDialog.h | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index ec41434c1..f0bc99551 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -330,3 +330,18 @@ void PostedCreatePostDialog::reject() QDialog::reject(); } + +void PostedCreatePostDialog::setTitle(const QString& title) +{ + ui->titleEdit->setText(title); +} + +void PostedCreatePostDialog::setNotes(const QString& notes) +{ + ui->RichTextEditWidget->setText(notes); +} + +void PostedCreatePostDialog::setLink(const QString& link) +{ + ui->linkEdit->setText(link); +} diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index d7b8a261c..e952f6be8 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -41,6 +41,10 @@ public: explicit PostedCreatePostDialog(RsPosted* posted, const RsGxsGroupId& grpId, const RsGxsId& default_author=RsGxsId(),QWidget *parent = 0); ~PostedCreatePostDialog(); + void setTitle(const QString& title); + void setNotes(const QString& notes); + void setLink(const QString& link); + private: QString imagefilename; QByteArray imagebytes; From b14fecfc2af4c0dd18be65bbef0b8a922400cc60 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sun, 16 Apr 2023 17:44:50 +0200 Subject: [PATCH 13/18] FeedReader: Message of a local feed can be added as forum and board message --- .../gui/FeedReaderMessageWidget.cpp | 119 ++++++++++++++++++ .../FeedReader/gui/FeedReaderMessageWidget.h | 4 + plugins/FeedReader/interface/rsFeedReader.h | 10 ++ plugins/FeedReader/lang/FeedReader_en.ts | 18 ++- plugins/FeedReader/services/p3FeedReader.cc | 82 ++++++++++++ plugins/FeedReader/services/p3FeedReader.h | 5 + .../src/gui/gxsforums/CreateGxsForumMsg.cpp | 6 +- 7 files changed, 237 insertions(+), 7 deletions(-) diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp index 96198f400..5be5d3ebc 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp @@ -36,8 +36,12 @@ #include "gui/settings/rsharesettings.h" #include "util/HandleRichText.h" #include "util/QtVersion.h" +#include "gui/Posted/PostedCreatePostDialog.h" +#include "gui/gxsforums/CreateGxsForumMsg.h" #include "retroshare/rsiface.h" +#include "retroshare/rsgxsforums.h" +#include "retroshare/rsposted.h" #define COLUMN_MSG_COUNT 4 #define COLUMN_MSG_TITLE 0 @@ -350,6 +354,20 @@ void FeedReaderMessageWidget::msgTreeCustomPopupMenu(QPoint /*point*/) action = contextMnu.addAction(QIcon(""), tr("Remove"), this, SLOT(removeMsg())); action->setEnabled(!selectedItems.empty()); + if (selectedItems.size() == 1 && (mFeedReader->forums() || mFeedReader->posted())) { + contextMnu.addSeparator(); + + if (mFeedReader->forums()) { + QMenu *menu = contextMnu.addMenu(tr("Add to forum")); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(fillForumMenu())); + } + + if (mFeedReader->posted()) { + QMenu *menu = contextMnu.addMenu(tr("Add to board")); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(fillPostedMenu())); + } + } + contextMnu.addSeparator(); action = contextMnu.addAction(QIcon(""), tr("Retransform"), this, SLOT(retransformMsg())); @@ -850,3 +868,104 @@ void FeedReaderMessageWidget::openLinkMsg() QDesktopServices::openUrl(QUrl(link)); } + +void FeedReaderMessageWidget::fillForumMenu() +{ + QMenu *menu = dynamic_cast(sender()) ; + if (!menu) { + return; + } + + disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(fillForumMenu())); + + std::vector groups; + if (mFeedReader->getForumGroups(groups, true)) { + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsGxsForumGroup &group = *it; + QAction *action = menu->addAction(QString::fromUtf8(group.mMeta.mGroupName.c_str()), this, SLOT(addToForum())); + action->setData(QString::fromUtf8(group.mMeta.mGroupId.toStdString().c_str())); + } + } +} + +void FeedReaderMessageWidget::fillPostedMenu() +{ + QMenu *menu = dynamic_cast(sender()) ; + if (!menu) { + return; + } + + disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(fillPostedMenu())); + + std::vector groups; + if (mFeedReader->getPostedGroups(groups, true)) { + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsPostedGroup &group = *it; + QAction *action = menu->addAction(QString::fromUtf8(group.mMeta.mGroupName.c_str()), this, SLOT(addToPosted())); + action->setData(QString::fromUtf8(group.mMeta.mGroupId.toStdString().c_str())); + } + } +} + +void FeedReaderMessageWidget::addToForum() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QString id = action->data().toString(); + if (id.isEmpty()) { + return; + } + + QList selectedItems = ui->msgTreeWidget->selectedItems(); + if (selectedItems.size() != 1) { + return; + } + + std::string msgId = selectedItems[0]->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); + FeedMsgInfo msgInfo; + if (!mFeedReader->getMsgInfo(mFeedId, msgId, msgInfo)) { + return; + } + + RsGxsGroupId forumId(id.toStdString()); + + CreateGxsForumMsg *msgDialog = new CreateGxsForumMsg(forumId, RsGxsMessageId(), RsGxsMessageId(), RsGxsId()) ; + msgDialog->setSubject(QString::fromUtf8(msgInfo.title.c_str())); + msgDialog->insertPastedText(QString::fromUtf8(msgInfo.description.c_str())); + msgDialog->show(); +} + +void FeedReaderMessageWidget::addToPosted() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QString id = action->data().toString(); + if (id.isEmpty()) { + return; + } + + QList selectedItems = ui->msgTreeWidget->selectedItems(); + if (selectedItems.size() != 1) { + return; + } + + std::string msgId = selectedItems[0]->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); + FeedMsgInfo msgInfo; + if (!mFeedReader->getMsgInfo(mFeedId, msgId, msgInfo)) { + return; + } + + RsGxsGroupId postedId(id.toStdString()); + + PostedCreatePostDialog *msgDialog = new PostedCreatePostDialog(mFeedReader->posted(), postedId); + msgDialog->setTitle(QString::fromUtf8(msgInfo.title.c_str())); + msgDialog->setNotes(QString::fromUtf8(msgInfo.description.c_str())); + msgDialog->setLink(QString::fromUtf8(msgInfo.link.c_str())); + msgDialog->show(); +} diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.h b/plugins/FeedReader/gui/FeedReaderMessageWidget.h index 452c407ad..317d61e71 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.h +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.h @@ -73,6 +73,10 @@ private slots: void openLinkMsg(); void copyLinkMsg(); void retransformMsg(); + void fillForumMenu(); + void fillPostedMenu(); + void addToForum(); + void addToPosted(); /* FeedReaderNotify */ void feedChanged(uint32_t feedId, int type); diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index 3de449ba0..bfb239400 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -25,8 +25,13 @@ #include #include #include +#include class RsFeedReader; +class RsGxsForums; +class RsPosted; +class RsGxsForumGroup; +class RsPostedGroup; extern RsFeedReader *rsFeedReader; enum RsFeedReaderErrorState { @@ -232,6 +237,11 @@ public: virtual bool retransformMsg(uint32_t feedId, const std::string &msgId) = 0; virtual bool clearMessageCache(uint32_t feedId) = 0; + virtual RsGxsForums* forums() = 0; + virtual RsPosted* posted() = 0; + virtual bool getForumGroups(std::vector &groups, bool onlyOwn) = 0; + virtual bool getPostedGroups(std::vector &groups, bool onlyOwn) = 0; + virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) = 0; virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString) = 0; }; diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index 500c46810..af6f9422f 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -194,8 +194,8 @@ - - + + Edit feed @@ -530,7 +530,7 @@ - + Title @@ -616,13 +616,23 @@ Remove + + + Add to forum + + + Add to board + + + + Retransform - + Hide diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 104e137c6..0e3310aa5 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -2532,3 +2532,85 @@ bool p3FeedReader::waitForToken(RsGxsIfaceHelper *interface, uint32_t token) return false; } + +bool p3FeedReader::getForumGroups(std::vector &groups, bool onlyOwn) +{ + if (!mForums) { + std::cerr << "p3FeedReader::getForumGroups - can't get groups, member mForums is not set" << std::endl; + return false; + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + uint32_t token; + if (!mForums->requestGroupInfo(token, opts)) { + std::cerr << "p3FeedReader::getForumGroups - can't get group list" << std::endl; + return false; + } + + if (!waitForToken(mForums, token)) { + std::cerr << "p3FeedReader::getForumGroups - waitForToken for list failed" << std::endl; + return false; + } + + if (!mForums->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getForumGroups - getGroupData failed" << std::endl; + return false; + } + + if (onlyOwn) { + // filter groups + for (std::vector::iterator it = groups.begin(); it != groups.end(); ) { + const RsGxsForumGroup &group = *it; + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags)) { + ++it; + } else { + it = groups.erase(it); + } + } + } + + return true; +} + +bool p3FeedReader::getPostedGroups(std::vector &groups, bool onlyOwn) +{ + if (!mPosted) { + std::cerr << "p3FeedReader::getPostedGroups - can't get groups, member mPosted is not set" << std::endl; + return false; + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + uint32_t token; + if (!mPosted->requestGroupInfo(token, opts)) { + std::cerr << "p3FeedReader::getPostedGroups - can't get group list" << std::endl; + return false; + } + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::getPostedGroups - waitForToken for list failed" << std::endl; + return false; + } + + if (!mPosted->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getForumGroups - getGroupData failed" << std::endl; + return false; + } + + if (onlyOwn) { + // filter groups + for (std::vector::iterator it = groups.begin(); it != groups.end(); ) { + const RsPostedGroup &group = *it; + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags)) { + ++it; + } else { + it = groups.erase(it); + } + } + } + + return true; +} diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index ac251b23a..c69832506 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -75,6 +75,11 @@ public: virtual bool retransformMsg(uint32_t feedId, const std::string &msgId); virtual bool clearMessageCache(uint32_t feedId); + virtual RsGxsForums* forums() { return mForums; } + virtual RsPosted* posted() { return mPosted; } + virtual bool getForumGroups(std::vector &groups, bool onlyOwn); + virtual bool getPostedGroups(std::vector &groups, bool onlyOwn); + virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString); virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString); diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index 493f254d4..4236b6f04 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -68,19 +68,19 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->postButton); mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->innerFrame); mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumSubject); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumSubject, false); mStateHelper->addClear(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName); mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->postButton); mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->innerFrame); mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumSubject); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumSubject, false); mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName); mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->postButton); mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->innerFrame); mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumSubject); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumSubject, false); mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName); From e25c148c27469665d14a856c931cef82a7fe6cde Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 24 Apr 2023 22:53:26 +0200 Subject: [PATCH 14/18] FeedReader: Changed save type for IndicateConfigChanged in service to SAVE_NOW --- plugins/FeedReader/services/p3FeedReader.cc | 44 ++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 0e3310aa5..7d6f44a1c 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -269,7 +269,7 @@ void p3FeedReader::setStandardStorageTime(uint32_t storageTime) if (mStandardStorageTime != storageTime) { mStandardStorageTime = storageTime; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -286,7 +286,7 @@ void p3FeedReader::setStandardUpdateInterval(uint32_t updateInterval) if (mStandardUpdateInterval != updateInterval) { mStandardUpdateInterval = updateInterval; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -308,7 +308,7 @@ void p3FeedReader::setStandardProxy(bool useProxy, const std::string &proxyAddre mStandardProxyAddress = proxyAddress; mStandardProxyPort = proxyPort; mStandardUseProxy = useProxy; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -325,7 +325,7 @@ void p3FeedReader::setSaveInBackground(bool saveInBackground) if (saveInBackground != mSaveInBackground) { mSaveInBackground = saveInBackground; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -401,7 +401,7 @@ RsFeedResult p3FeedReader::addFolder(uint32_t parentId, const std::string &name, feedId = fi->feedId; } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); @@ -441,7 +441,7 @@ RsFeedResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name) fi->name = name; } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -488,7 +488,7 @@ RsFeedResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId) feedId = fi->feedId; } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); @@ -573,7 +573,7 @@ RsFeedResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) } } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -644,7 +644,7 @@ RsFeedResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -729,7 +729,7 @@ bool p3FeedReader::removeFeed(uint32_t feedId) } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (preview) { @@ -910,7 +910,7 @@ bool p3FeedReader::removeMsg(uint32_t feedId, const std::string &msgId) } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (mNotify) { @@ -962,7 +962,7 @@ bool p3FeedReader::removeMsgs(uint32_t feedId, const std::list &msg } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (mNotify && !removedMsgs.empty()) { @@ -1260,7 +1260,7 @@ bool p3FeedReader::setMessageRead(uint32_t feedId, const std::string &msgId, boo } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->notifyMsgChanged(feedId, msgId, NOTIFY_TYPE_MOD); @@ -1314,7 +1314,7 @@ bool p3FeedReader::retransformMsg(uint32_t feedId, const std::string &msgId) } if (feedChanged || msgChanged) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { if (feedChanged) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -1368,7 +1368,7 @@ bool p3FeedReader::clearMessageCache(uint32_t feedId) } } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); return true; } @@ -1499,7 +1499,7 @@ void p3FeedReader::cleanFeeds() mLastClean = currentTime; if (removedMsgIds.size()) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { std::list >::iterator it; @@ -1811,7 +1811,7 @@ void p3FeedReader::onDownloadSuccess(uint32_t feedId, const std::string &content fi->icon = icon; if (!preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -1862,7 +1862,7 @@ void p3FeedReader::onDownloadError(uint32_t feedId, RsFeedReaderErrorState resul #endif if (!fi->preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -1974,7 +1974,7 @@ void p3FeedReader::onProcessSuccess_filterMsg(uint32_t feedId, std::listerrorString.clear(); if (!fi->preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } } @@ -2119,7 +2119,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listpreview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -2266,7 +2266,7 @@ void p3FeedReader::onProcessError(uint32_t feedId, RsFeedReaderErrorState result #endif if (!fi->preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -2335,7 +2335,7 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s if (changed) { if (!preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (mNotify) { From af562cb4cad52b55985c9f13e3fc8927a87e6b12 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 26 Apr 2023 21:53:59 +0200 Subject: [PATCH 15/18] FeedReader: Added shrink of images for board post --- plugins/FeedReader/gui/AddFeedDialog.cpp | 7 ++ plugins/FeedReader/gui/AddFeedDialog.ui | 10 +- plugins/FeedReader/gui/FeedReaderDialog.cpp | 33 ++++++ plugins/FeedReader/gui/FeedReaderDialog.h | 1 + plugins/FeedReader/gui/FeedReaderNotify.cpp | 5 + plugins/FeedReader/gui/FeedReaderNotify.h | 2 + plugins/FeedReader/interface/rsFeedReader.h | 27 +++++ plugins/FeedReader/lang/FeedReader_en.ts | 21 ++-- plugins/FeedReader/services/p3FeedReader.cc | 110 +++++++++++++++++- plugins/FeedReader/services/p3FeedReader.h | 8 ++ .../FeedReader/services/rsFeedReaderItems.h | 1 + .../src/gui/Posted/PostedCreatePostDialog.cpp | 12 +- .../src/gui/Posted/PostedCreatePostDialog.h | 3 +- 13 files changed, 226 insertions(+), 14 deletions(-) diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index 588428a8d..4e0645607 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -99,6 +99,8 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, ui->postedFirstImageCheckBox->setChecked(false); ui->postedOnlyImageCheckBox->setEnabled(false); ui->postedOnlyImageCheckBox->setChecked(false); + ui->postedShinkImageCheckBox->setEnabled(false); + ui->postedShinkImageCheckBox->setChecked(false); ui->useAuthenticationCheckBox->setChecked(false); ui->useStandardStorageTimeCheckBox->setChecked(true); ui->useStandardUpdateInterval->setChecked(true); @@ -197,9 +199,11 @@ void AddFeedDialog::postedFirstImageToggled() { bool checked = ui->postedFirstImageCheckBox->isChecked(); ui->postedOnlyImageCheckBox->setEnabled(checked); + ui->postedShinkImageCheckBox->setEnabled(checked); if (!checked) { ui->postedOnlyImageCheckBox->setChecked(false); + ui->postedShinkImageCheckBox->setChecked(false); } } @@ -209,6 +213,7 @@ void AddFeedDialog::typePostedToggled() mStateHelper->setWidgetEnabled(ui->postedComboBox, checked); ui->updatePostedInfoCheckBox->setEnabled(checked); ui->postedFirstImageCheckBox->setEnabled(checked); + ui->postedShinkImageCheckBox->setEnabled(checked); if (checked) { ui->typeLocalCheckBox->setChecked(false); @@ -301,6 +306,7 @@ bool AddFeedDialog::fillFeed(uint32_t feedId) ui->updatePostedInfoCheckBox->setChecked(feedInfo.flag.updatePostedInfo); ui->postedFirstImageCheckBox->setChecked(feedInfo.flag.postedFirstImage); ui->postedOnlyImageCheckBox->setChecked(feedInfo.flag.postedOnlyImage); + ui->postedShinkImageCheckBox->setChecked(feedInfo.flag.postedShrinkImage); ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages); ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage); @@ -397,6 +403,7 @@ void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) feedInfo.flag.updatePostedInfo = ui->updatePostedInfoCheckBox->isChecked() && ui->updatePostedInfoCheckBox->isEnabled(); feedInfo.flag.postedFirstImage = ui->postedFirstImageCheckBox->isChecked() && ui->postedFirstImageCheckBox->isEnabled(); feedInfo.flag.postedOnlyImage = ui->postedOnlyImageCheckBox->isChecked() && ui->postedOnlyImageCheckBox->isEnabled(); + feedInfo.flag.postedShrinkImage = ui->postedShinkImageCheckBox->isChecked() && ui->postedShinkImageCheckBox->isEnabled(); feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked(); feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index f3bcaf85f..40b9bd46d 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -130,6 +130,13 @@
+ + + + Shrink image + + + @@ -482,8 +489,9 @@ typePostedCheckBox postedComboBox updatePostedInfoCheckBox + postedShinkImageCheckBox postedFirstImageCheckBox - checkBox + postedOnlyImageCheckBox typeLocalCheckBox activatedCheckBox useInfoFromFeedCheckBox diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index 1c3d6ca8c..7ea17983b 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -35,6 +35,7 @@ #include "gui/settings/rsharesettings.h" #include "gui/notifyqt.h" #include "FeedReaderUserNotify.h" +#include "gui/Posted/PostedCreatePostDialog.h" #include "interface/rsFeedReader.h" #include "retroshare/rsiface.h" @@ -66,6 +67,7 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n mMessageWidget = NULL; connect(mNotify, &FeedReaderNotify::feedChanged, this, &FeedReaderDialog::feedChanged, Qt::QueuedConnection); + connect(mNotify, &FeedReaderNotify::shrinkImage, this, &FeedReaderDialog::shrinkImage, Qt::QueuedConnection); connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); @@ -604,6 +606,37 @@ void FeedReaderDialog::feedChanged(uint32_t feedId, int type) calculateFeedItems(); } +void FeedReaderDialog::shrinkImage() +{ + while (true) { + FeedReaderShrinkImageTask *shrinkImageTask = mFeedReader->getShrinkImageTask(); + + if (!shrinkImageTask) { + return; + } + + switch (shrinkImageTask->mType) { + case FeedReaderShrinkImageTask::POSTED: + { + QImage image; + if (image.loadFromData(shrinkImageTask->mImage.data(), shrinkImageTask->mImage.size())) { + QByteArray imageBytes; + QImage imageOpt; + if (PostedCreatePostDialog::optimizeImage(image, imageBytes, imageOpt)) { + shrinkImageTask->mImageResult.assign(imageBytes.begin(), imageBytes.end()); + shrinkImageTask->mResult = true; + } + } + break; + } + default: + shrinkImageTask->mResult = false; + } + + mFeedReader->setShrinkImageTaskResult(shrinkImageTask); + } +} + FeedReaderMessageWidget *FeedReaderDialog::feedMessageWidget(uint32_t id) { int tabCount = ui->messageTabWidget->count(); diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h index d684f1f4b..b4854d2f3 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.h +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -69,6 +69,7 @@ private slots: /* FeedReaderNotify */ void feedChanged(uint32_t feedId, int type); + void shrinkImage(); private: uint32_t currentFeedId(); diff --git a/plugins/FeedReader/gui/FeedReaderNotify.cpp b/plugins/FeedReader/gui/FeedReaderNotify.cpp index f2aa7ad1d..33b0c294a 100644 --- a/plugins/FeedReader/gui/FeedReaderNotify.cpp +++ b/plugins/FeedReader/gui/FeedReaderNotify.cpp @@ -33,3 +33,8 @@ void FeedReaderNotify::notifyMsgChanged(uint32_t feedId, const std::string &msgI { emit msgChanged(feedId, QString::fromStdString(msgId), type); } + +void FeedReaderNotify::notifyShrinkImage() +{ + emit shrinkImage(); +} diff --git a/plugins/FeedReader/gui/FeedReaderNotify.h b/plugins/FeedReader/gui/FeedReaderNotify.h index 5a8ad712a..18090e70c 100644 --- a/plugins/FeedReader/gui/FeedReaderNotify.h +++ b/plugins/FeedReader/gui/FeedReaderNotify.h @@ -34,10 +34,12 @@ public: /* RsFeedReaderNotify */ virtual void notifyFeedChanged(uint32_t feedId, int type); virtual void notifyMsgChanged(uint32_t feedId, const std::string &msgId, int type); + virtual void notifyShrinkImage(); signals: void feedChanged(uint32_t feedId, int type); void msgChanged(uint32_t feedId, const QString &msgId, int type); + void shrinkImage(); }; #endif diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index bfb239400..ad1ecec9a 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -157,6 +157,7 @@ public: bool updatePostedInfo : 1; bool postedFirstImage : 1; bool postedOnlyImage : 1; + bool postedShrinkImage : 1; bool embedImages : 1; bool saveCompletePage : 1; bool preview : 1; @@ -190,6 +191,28 @@ public: } flag; }; +class FeedReaderShrinkImageTask +{ +public: + enum Type { + POSTED + }; + +public: + Type mType; + std::vector mImage; + std::vector mImageResult; + bool mResult; + +public: + FeedReaderShrinkImageTask(Type type, const std::vector &image) + { + mType = type; + mImage = image; + mResult = false; + } +}; + class RsFeedReaderNotify { public: @@ -197,6 +220,7 @@ public: virtual void notifyFeedChanged(uint32_t /*feedId*/, int /*type*/) {} virtual void notifyMsgChanged(uint32_t /*feedId*/, const std::string &/*msgId*/, int /*type*/) {} + virtual void notifyShrinkImage() {} }; class RsFeedReader @@ -242,6 +266,9 @@ public: virtual bool getForumGroups(std::vector &groups, bool onlyOwn) = 0; virtual bool getPostedGroups(std::vector &groups, bool onlyOwn) = 0; + virtual FeedReaderShrinkImageTask *getShrinkImageTask() = 0; + virtual void setShrinkImageTaskResult(FeedReaderShrinkImageTask *shrinkImageTask) = 0; + virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) = 0; virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString) = 0; }; diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index af6f9422f..93db4a686 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -28,6 +28,11 @@ Use first image as board image + + + Shrink image + + Authentication (not yet supported) @@ -119,7 +124,7 @@ - + Type @@ -134,7 +139,7 @@ - + Transformation @@ -164,12 +169,12 @@ - + Update forum information - + Save complete web page (experimental for local feeds) @@ -194,8 +199,8 @@ - - + + Edit feed @@ -312,7 +317,7 @@ - + Message Folders @@ -367,7 +372,7 @@ - + Add new folder diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 7d6f44a1c..fbda4d9e1 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -45,7 +45,7 @@ RsFeedReader *rsFeedReader = NULL; p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums, RsPosted *posted) : RsPQIService(RS_SERVICE_TYPE_PLUGIN_FEEDREADER, 5, pgHandler), - mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mPreviewMutex("p3FeedReaderPreview") + mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mImageMutex("p3FeedReaderImage"), mPreviewMutex("p3FeedReaderPreview") { mNextFeedId = 1; mNextMsgId = 1; @@ -118,6 +118,7 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.flag.updatePostedInfo = (feed->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO); info.flag.postedFirstImage = (feed->flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE); info.flag.postedOnlyImage = (feed->flag & RS_FEED_FLAG_POSTED_ONLY_IMAGE); + info.flag.postedShrinkImage = (feed->flag & RS_FEED_FLAG_POSTED_SHRINK_IMAGE); info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); @@ -217,6 +218,9 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) if (info.flag.postedOnlyImage) { feed->flag |= RS_FEED_FLAG_POSTED_ONLY_IMAGE; } + if (info.flag.postedShrinkImage) { + feed->flag |= RS_FEED_FLAG_POSTED_SHRINK_IMAGE; + } } static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) @@ -1445,10 +1449,21 @@ int p3FeedReader::tick() } } + // check images + bool imageToShrink = false; + { + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + imageToShrink = !mImages.empty(); + } + if (mNotify) { for (it = notifyIds.begin(); it != notifyIds.end(); ++it) { mNotify->notifyFeedChanged(*it, NOTIFY_TYPE_MOD); } + if (imageToShrink) { + mNotify->notifyShrinkImage(); + } } return 0; @@ -2188,7 +2203,15 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list shrinkedImage; + if (shrinkImage(FeedReaderShrinkImageTask::POSTED, mi.postedFirstImage, shrinkedImage)) { + postedPost.mImage.copy(shrinkedImage.data(), shrinkedImage.size()); + } + } else { + postedPost.mImage.copy(mi.postedFirstImage.data(), mi.postedFirstImage.size()); + } if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { /* ignore description */ } else { @@ -2614,3 +2637,86 @@ bool p3FeedReader::getPostedGroups(std::vector &groups, bool only return true; } + +bool p3FeedReader::shrinkImage(FeedReaderShrinkImageTask::Type type, const std::vector &image, std::vector &resultImage) +{ + if (!mNotify) { + return false; + } + + FeedReaderShrinkImageTask *shrinkImageTask = new FeedReaderShrinkImageTask(type, image); + { + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + mImages.push_back(shrinkImageTask); + } + + /* Wait until task is complete */ + int nSeconds = 0; + while (true) { + if (mStopped) { + return false; + } + + rstime::rs_usleep(1000 * 1000); // 1 second + + if (++nSeconds >= 30) { + // timeout + std::list::iterator it = std::find(mImages.begin(), mImages.end(), shrinkImageTask); + if (it != mImages.end()) { + mImages.erase(it); + + delete(shrinkImageTask); + + return false; + } + + // not found in mImages? + } + + { + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + std::list::iterator it = std::find(mResultImages.begin(), mResultImages.end(), shrinkImageTask); + if (it != mResultImages.end()) { + mResultImages.erase(it); + + bool result = shrinkImageTask->mResult; + if (result) { + resultImage = shrinkImageTask->mImageResult; + } + + delete(shrinkImageTask); + + return result; + } + } + } + + return false; +} + +FeedReaderShrinkImageTask *p3FeedReader::getShrinkImageTask() +{ + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + if (mImages.empty()) { + return NULL; + } + + FeedReaderShrinkImageTask *imageResize = mImages.front(); + mImages.pop_front(); + + return imageResize; +} + +void p3FeedReader::setShrinkImageTaskResult(FeedReaderShrinkImageTask *shrinkImageTask) +{ + if (!shrinkImageTask) { + return; + } + + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + mResultImages.push_back(shrinkImageTask); +} diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index c69832506..edca9ee1e 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -80,6 +80,9 @@ public: virtual bool getForumGroups(std::vector &groups, bool onlyOwn); virtual bool getPostedGroups(std::vector &groups, bool onlyOwn); + virtual FeedReaderShrinkImageTask *getShrinkImageTask(); + virtual void setShrinkImageTaskResult(FeedReaderShrinkImageTask *shrinkedImageTask); + virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString); virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString); @@ -104,6 +107,7 @@ public: bool getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup); bool updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription); bool waitForToken(RsGxsIfaceHelper *interface, uint32_t token); + bool shrinkImage(FeedReaderShrinkImageTask::Type type, const std::vector &image, std::vector &resultImage); protected: /****************** p3Config STUFF *******************/ @@ -145,6 +149,10 @@ private: RsMutex mProcessMutex; std::list mProcessFeeds; + RsMutex mImageMutex; + std::list mImages; + std::list mResultImages; + RsMutex mPreviewMutex; p3FeedReaderThread *mPreviewDownloadThread; p3FeedReaderThread *mPreviewProcessThread; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index 39d604f46..3adafd55a 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -49,6 +49,7 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; #define RS_FEED_FLAG_UPDATE_POSTED_INFO 0x1000 #define RS_FEED_FLAG_POSTED_FIRST_IMAGE 0x2000 #define RS_FEED_FLAG_POSTED_ONLY_IMAGE 0x4000 +#define RS_FEED_FLAG_POSTED_SHRINK_IMAGE 0x8000 class RsFeedReaderFeed : public RsItem { diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index f0bc99551..bfccd3fc7 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -50,6 +50,8 @@ #define IMG_ATTACH 0 #define IMG_PICTURE 1 +const int MAXMESSAGESIZE = 199000; + PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGroupId& grpId, const RsGxsId& default_author, QWidget *parent): QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), mPosted(posted), mGrpId(grpId), @@ -226,7 +228,7 @@ void PostedCreatePostDialog::addPicture() } QImage opt; - if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt,"JPG", 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff + if (optimizeImage(image, imagebytes, opt)) { ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); ui->removeButton->show(); @@ -274,7 +276,7 @@ void PostedCreatePostDialog::pastePicture() image = (qvariant_cast(mimeData->imageData())); QImage opt; - if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt,"JPG", 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff + if (optimizeImage(image, imagebytes, opt)) { ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); ui->removeButton->show(); @@ -287,6 +289,12 @@ void PostedCreatePostDialog::pastePicture() } } +bool PostedCreatePostDialog::optimizeImage(const QImage &image, QByteArray &imagebytes, QImage &imageOpt) +{ + // Leave space for other stuff + return ImageUtil::optimizeSizeBytes(imagebytes, image, imageOpt, "JPG", 640*480, MAXMESSAGESIZE - 2000); +} + int PostedCreatePostDialog::viewMode() { if (ui->viewPostButton->isChecked()) { diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index e952f6be8..5ac2c2e7d 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -45,10 +45,11 @@ public: void setNotes(const QString& notes); void setLink(const QString& link); + static bool optimizeImage(const QImage &image, QByteArray &imagebytes, QImage &imageOpt); + private: QString imagefilename; QByteArray imagebytes; - const int MAXMESSAGESIZE = 199000; private slots: void createPost(); From ff183ee98b11c801afbc96e5dc8bc1e4ca7a33ca Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 26 Apr 2023 22:39:03 +0200 Subject: [PATCH 16/18] FeedReader: Reduced the height of the dialog for creating a feed --- plugins/FeedReader/gui/AddFeedDialog.ui | 271 +++++++++++------------- 1 file changed, 129 insertions(+), 142 deletions(-) diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index 40b9bd46d..ebb478162 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -6,8 +6,8 @@ 0 0 - 1068 - 880 + 739 + 653 @@ -45,103 +45,6 @@ QFrame::Raised - - - - Type - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - Forum - - - - - - - - - - Local Feed - - - - - - - - - Update forum information - - - - - - - - - - - - Board - - - - - - - - - Update board information - - - - - - - Only image - - - - - - - Use first image as board image - - - - - - - Shrink image - - - - - - - - @@ -378,40 +281,7 @@ - - - - Transformation - - - - - - - - Transformation type - - - - - - - - 0 - 0 - - - - Preview && Transformation - - - - - - - - - + Misc @@ -445,18 +315,135 @@ + + + + + + + Transformation + + - - - Qt::Vertical + + + + + Transformation type + + + + + + + + 0 + 0 + + + + Preview && Transformation + + + + + + + + + + + + Type + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 0 + 0 + - - - 20 - 40 - + + Forum - + + + + + + + + + Local Feed + + + + + + + + + Update forum information + + + + + + + + + + + + Board + + + + + + + + + Update board information + + + + + + + Only image + + + + + + + Use first image as board image + + + + + + + Shrink image + + + + From 180b7d3703d8f3a275629ecb5b0ec26db2ea1d9a Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sat, 6 May 2023 01:23:23 +0200 Subject: [PATCH 17/18] FeedReader: Added process of response code 403 and added user agent --- .../FeedReader/gui/FeedReaderStringDefs.cpp | 3 ++ plugins/FeedReader/interface/rsFeedReader.h | 1 + plugins/FeedReader/lang/FeedReader_en.ts | 29 +++++++++++-------- .../FeedReader/services/p3FeedReaderThread.cc | 3 ++ plugins/FeedReader/util/CURLWrapper.cpp | 4 +++ 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp index 647c4cf7b..07f0d44ab 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -101,6 +101,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE: errorText = QApplication::translate("FeedReaderStringDefs", "Unknown response code"); break; + case RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED: + errorText = QApplication::translate("FeedReaderStringDefs", "Download blocked"); + break; /* process */ case RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR: diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index ad1ecec9a..044dcdd80 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -43,6 +43,7 @@ enum RsFeedReaderErrorState { RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3, RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4, RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5, + RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED = 6, /* process */ RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index 93db4a686..db5748893 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -9,7 +9,7 @@ - + Board @@ -34,7 +34,7 @@ - + Authentication (not yet supported) @@ -84,12 +84,12 @@ - + Embed images - + Storage time @@ -124,7 +124,7 @@ - + Type @@ -139,7 +139,7 @@ - + Transformation @@ -154,7 +154,7 @@ - + Misc @@ -169,17 +169,17 @@ - + Update forum information - + Save complete web page (experimental for local feeds) - + Description: @@ -714,12 +714,12 @@ - + Unknown - + Internal download error @@ -743,6 +743,11 @@ Unknown response code + + + Download blocked + + Internal process error diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 00da7a007..1c8714a05 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -302,6 +302,9 @@ RsFeedReaderErrorState p3FeedReaderThread::download(const RsFeedReaderFeed &feed } } break; + case 403: + result = RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED; + break; case 404: result = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; break; diff --git a/plugins/FeedReader/util/CURLWrapper.cpp b/plugins/FeedReader/util/CURLWrapper.cpp index 87fd986ff..94ae7beaa 100644 --- a/plugins/FeedReader/util/CURLWrapper.cpp +++ b/plugins/FeedReader/util/CURLWrapper.cpp @@ -21,6 +21,8 @@ #include "CURLWrapper.h" #include +#define USERAGENT "Mozilla/5.0 (rv:109.0) Gecko/20100101 Firefox/112.0" + CURLWrapper::CURLWrapper(const std::string &proxy) { mCurl = curl_easy_init(); @@ -65,6 +67,7 @@ CURLcode CURLWrapper::downloadText(const std::string &link, std::string &data) curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, writeFunctionString); curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data); curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, false); + curl_easy_setopt(mCurl, CURLOPT_USERAGENT, USERAGENT); return curl_easy_perform(mCurl); } @@ -95,6 +98,7 @@ CURLcode CURLWrapper::downloadBinary(const std::string &link, std::vector Date: Wed, 12 Apr 2023 14:39:43 +0200 Subject: [PATCH 18/18] Windows Build Environment: Added missing target "error" to git-log.bat --- build_scripts/Windows/build/git-log.bat | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_scripts/Windows/build/git-log.bat b/build_scripts/Windows/build/git-log.bat index 286d813e2..b2328d853 100644 --- a/build_scripts/Windows/build/git-log.bat +++ b/build_scripts/Windows/build/git-log.bat @@ -88,6 +88,10 @@ echo %RsRef%>"%RsLastRefFile%" exit /B %ERRORLEVEL% +:error +%cecho% error "\n%~n0 failed\n" +exit /B 1 + :error_env echo Failed to initialize environment. endlocal