Merge remote-tracking branch 'upstream/master' into v0.6-BugFixing_29

This commit is contained in:
csoler 2023-05-07 17:07:59 +02:00
commit 2f2495455f
40 changed files with 1775 additions and 375 deletions

View file

@ -88,6 +88,10 @@ echo %RsRef%>"%RsLastRefFile%"
exit /B %ERRORLEVEL% exit /B %ERRORLEVEL%
:error
%cecho% error "\n%~n0 failed\n"
exit /B 1
:error_env :error_env
echo Failed to initialize environment. echo Failed to initialize environment.
endlocal endlocal

View file

@ -44,6 +44,7 @@ SOURCES = FeedReaderPlugin.cpp \
gui/FeedReaderFeedNotify.cpp \ gui/FeedReaderFeedNotify.cpp \
gui/FeedReaderUserNotify.cpp \ gui/FeedReaderUserNotify.cpp \
gui/FeedReaderFeedItem.cpp \ gui/FeedReaderFeedItem.cpp \
gui/FeedTreeWidget.cpp \
util/CURLWrapper.cpp \ util/CURLWrapper.cpp \
util/XMLWrapper.cpp \ util/XMLWrapper.cpp \
util/HTMLWrapper.cpp \ util/HTMLWrapper.cpp \
@ -64,6 +65,7 @@ HEADERS = FeedReaderPlugin.h \
gui/FeedReaderFeedNotify.h \ gui/FeedReaderFeedNotify.h \
gui/FeedReaderUserNotify.h \ gui/FeedReaderUserNotify.h \
gui/FeedReaderFeedItem.h \ gui/FeedReaderFeedItem.h \
gui/FeedTreeWidget.h \
util/CURLWrapper.h \ util/CURLWrapper.h \
util/XMLWrapper.h \ util/XMLWrapper.h \
util/HTMLWrapper.h \ util/HTMLWrapper.h \

View file

@ -92,7 +92,7 @@ void FeedReaderPlugin::setInterfaces(RsPlugInInterfaces &interfaces)
{ {
mInterfaces = interfaces; mInterfaces = interfaces;
mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums); mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums, mInterfaces.mPosted);
rsFeedReader = mFeedReader; rsFeedReader = mFeedReader;
mNotify = new FeedReaderNotify(); mNotify = new FeedReaderNotify();

View file

@ -30,9 +30,11 @@
#include "gui/common/UIStateHelper.h" #include "gui/common/UIStateHelper.h"
#include <retroshare/rsgxsforums.h> #include <retroshare/rsgxsforums.h>
#include <retroshare/rsposted.h>
#include <iostream> #include <iostream>
#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) AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent)
: QDialog(parent, Qt::Window), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) : 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->forumComboBox, UISTATE_LOADING_DISABLED);
mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), 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 */ /* Setup TokenQueue */
mTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); mForumTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this);
mPostedTokenQueue = new TokenQueue(rsPosted->getTokenService(), this);
/* Connect signals */ /* Connect signals */
connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(createFeed())); 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->useStandardStorageTimeCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardStorageTimeToggled()));
connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled())); connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled()));
connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); 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())); connect(ui->previewButton, SIGNAL(clicked()), this, SLOT(preview()));
/* currently only for local feeds */ /* 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->urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate()));
connect(ui->nameLineEdit, 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->useInfoFromFeedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate()));
connect(ui->typeLocalRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate()));
connect(ui->typeForumRadio, 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->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())); connect(ui->clearCachePushButton, SIGNAL(clicked()), this, SLOT(clearMessageCache()));
@ -79,13 +89,24 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify,
ui->activatedCheckBox->setChecked(true); ui->activatedCheckBox->setChecked(true);
mStateHelper->setWidgetEnabled(ui->forumComboBox, false); mStateHelper->setWidgetEnabled(ui->forumComboBox, false);
mStateHelper->setWidgetEnabled(ui->postedComboBox, false);
ui->useInfoFromFeedCheckBox->setChecked(true); ui->useInfoFromFeedCheckBox->setChecked(true);
ui->updateForumInfoCheckBox->setEnabled(false); ui->updateForumInfoCheckBox->setEnabled(false);
ui->updateForumInfoCheckBox->setChecked(true); 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->postedShinkImageCheckBox->setEnabled(false);
ui->postedShinkImageCheckBox->setChecked(false);
ui->useAuthenticationCheckBox->setChecked(false); ui->useAuthenticationCheckBox->setChecked(false);
ui->useStandardStorageTimeCheckBox->setChecked(true); ui->useStandardStorageTimeCheckBox->setChecked(true);
ui->useStandardUpdateInterval->setChecked(true); ui->useStandardUpdateInterval->setChecked(true);
ui->useStandardProxyCheckBox->setChecked(true); ui->useStandardProxyCheckBox->setChecked(true);
ui->embedImagesCheckBox->setChecked(true);
ui->saveCompletePageCheckBox->setEnabled(false);
/* not yet supported */ /* not yet supported */
ui->authenticationGroupBox->setEnabled(false); ui->authenticationGroupBox->setEnabled(false);
@ -98,6 +119,9 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify,
/* fill own forums */ /* fill own forums */
requestForumGroups(); requestForumGroups();
/* fill own posted */
requestPostedGroups();
validate(); validate();
ui->urlLineEdit->setFocus(); ui->urlLineEdit->setFocus();
@ -112,7 +136,8 @@ AddFeedDialog::~AddFeedDialog()
processSettings(false); processSettings(false);
delete(ui); delete(ui);
delete(mTokenQueue); delete(mForumTokenQueue);
delete(mPostedTokenQueue);
} }
void AddFeedDialog::processSettings(bool load) void AddFeedDialog::processSettings(bool load)
@ -161,18 +186,68 @@ void AddFeedDialog::useStandardProxyToggled()
void AddFeedDialog::typeForumToggled() void AddFeedDialog::typeForumToggled()
{ {
bool checked = ui->typeForumRadio->isChecked(); bool checked = ui->typeForumCheckBox->isChecked();
mStateHelper->setWidgetEnabled(ui->forumComboBox, checked); mStateHelper->setWidgetEnabled(ui->forumComboBox, checked);
ui->updateForumInfoCheckBox->setEnabled(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);
ui->postedShinkImageCheckBox->setEnabled(checked);
if (!checked) {
ui->postedOnlyImageCheckBox->setChecked(false);
ui->postedShinkImageCheckBox->setChecked(false);
}
}
void AddFeedDialog::typePostedToggled()
{
bool checked = ui->typePostedCheckBox->isChecked();
mStateHelper->setWidgetEnabled(ui->postedComboBox, checked);
ui->updatePostedInfoCheckBox->setEnabled(checked);
ui->postedFirstImageCheckBox->setEnabled(checked);
ui->postedShinkImageCheckBox->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()) { if (ui->saveCompletePageCheckBox->isChecked()) {
ui->typeForumRadio->setEnabled(false); ui->typeForumCheckBox->setEnabled(false);
ui->typeLocalRadio->setChecked(true); ui->typeForumCheckBox->setChecked(false);
ui->typePostedCheckBox->setEnabled(false);
ui->typePostedCheckBox->setChecked(false);
ui->typeLocalCheckBox->setChecked(true);
} else { } else {
ui->typeForumRadio->setEnabled(true); ui->typeForumCheckBox->setEnabled(true);
ui->typePostedCheckBox->setEnabled(true);
} }
} }
@ -189,11 +264,15 @@ void AddFeedDialog::validate()
ui->previewButton->setEnabled(ok); ui->previewButton->setEnabled(ok);
if (!ui->typeLocalRadio->isChecked() && !ui->typeForumRadio->isChecked()) { if (!ui->typeLocalCheckBox->isChecked() && !ui->typeForumCheckBox->isChecked() && !ui->typePostedCheckBox->isChecked()) {
ok = false; 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; ok = false;
} }
@ -224,20 +303,32 @@ bool AddFeedDialog::fillFeed(uint32_t feedId)
ui->urlLineEdit->setText(QString::fromUtf8(feedInfo.url.c_str())); ui->urlLineEdit->setText(QString::fromUtf8(feedInfo.url.c_str()));
ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed); ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed);
ui->updateForumInfoCheckBox->setChecked(feedInfo.flag.updateForumInfo); 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->postedShinkImageCheckBox->setChecked(feedInfo.flag.postedShrinkImage);
ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated);
ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages); ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages);
ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage); ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage);
ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str())); ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str()));
if (feedInfo.flag.forum) { if (feedInfo.flag.forum || feedInfo.flag.posted) {
mStateHelper->setWidgetEnabled(ui->forumComboBox, true); if (feedInfo.flag.forum) {
ui->typeForumRadio->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, true);
ui->saveCompletePageCheckBox->setEnabled(false); 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 { } else {
ui->typeLocalRadio->setChecked(true); ui->typeLocalCheckBox->setChecked(true);
mStateHelper->setWidgetEnabled(ui->forumComboBox, false); mStateHelper->setWidgetEnabled(ui->forumComboBox, false);
} }
@ -286,6 +377,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) void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo)
{ {
feedInfo.parentId = mParentId; feedInfo.parentId = mParentId;
@ -294,18 +400,28 @@ void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo)
feedInfo.url = ui->urlLineEdit->text().toUtf8().constData(); feedInfo.url = ui->urlLineEdit->text().toUtf8().constData();
feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked(); feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked();
feedInfo.flag.updateForumInfo = ui->updateForumInfoCheckBox->isChecked() && ui->updateForumInfoCheckBox->isEnabled(); 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.postedShrinkImage = ui->postedShinkImageCheckBox->isChecked() && ui->postedShinkImageCheckBox->isEnabled();
feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked();
feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked(); feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked();
feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked(); feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked();
feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData(); feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData();
feedInfo.flag.forum = ui->typeForumRadio->isChecked(); feedInfo.flag.forum = ui->typeForumCheckBox->isChecked();
if (feedInfo.flag.forum) { if (feedInfo.flag.forum) {
feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); 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.flag.authentication = ui->useAuthenticationCheckBox->isChecked();
feedInfo.user = ui->userLineEdit->text().toUtf8().constData(); feedInfo.user = ui->userLineEdit->text().toUtf8().constData();
feedInfo.password = ui->passwordLineEdit->text().toUtf8().constData(); feedInfo.password = ui->passwordLineEdit->text().toUtf8().constData();
@ -340,12 +456,12 @@ void AddFeedDialog::createFeed()
if (mFeedId == 0) { if (mFeedId == 0) {
/* add new feed */ /* 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."))) { if (FeedReaderStringDefs::showError(this, result, tr("Create feed"), tr("Cannot create feed."))) {
return; return;
} }
} else { } 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."))) { if (FeedReaderStringDefs::showError(this, result, tr("Edit feed"), tr("Cannot change feed."))) {
return; return;
} }
@ -382,10 +498,10 @@ void AddFeedDialog::requestForumGroups()
RsTokReqOptions opts; RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
mTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); mForumTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS);
uint32_t token; 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) void AddFeedDialog::loadForumGroups(const uint32_t &token)
@ -416,9 +532,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<RsPostedGroup> groups;
rsPosted->getGroupData(token, groups);
ui->postedComboBox->clear();
for (std::vector<RsPostedGroup>::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) void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{ {
if (queue == mTokenQueue) if (queue == mForumTokenQueue)
{ {
/* now switch on req */ /* now switch on req */
switch(req.mUserType) switch(req.mUserType)
@ -433,4 +590,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;
}
}
} }

View file

@ -53,7 +53,10 @@ private slots:
void useStandardUpdateIntervalToggled(); void useStandardUpdateIntervalToggled();
void useStandardProxyToggled(); void useStandardProxyToggled();
void typeForumToggled(); void typeForumToggled();
void denyForumToggled(); void postedFirstImageToggled();
void typePostedToggled();
void typeLocalToggled();
void denyForumAndPostedToggled();
void validate(); void validate();
void createFeed(); void createFeed();
void preview(); void preview();
@ -63,9 +66,12 @@ private:
void processSettings(bool load); void processSettings(bool load);
void getFeedInfo(FeedInfo &feedInfo); void getFeedInfo(FeedInfo &feedInfo);
void setActiveForumId(const std::string &forumId); void setActiveForumId(const std::string &forumId);
void setActivePostedId(const std::string &postedId);
void requestForumGroups(); void requestForumGroups();
void loadForumGroups(const uint32_t &token); void loadForumGroups(const uint32_t &token);
void requestPostedGroups();
void loadPostedGroups(const uint32_t &token);
private: private:
RsFeedReader *mFeedReader; RsFeedReader *mFeedReader;
@ -73,13 +79,15 @@ private:
uint32_t mFeedId; uint32_t mFeedId;
uint32_t mParentId; uint32_t mParentId;
std::string mFillForumId; std::string mFillForumId;
std::string mFillPostedId;
RsFeedTransformationType mTransformationType; RsFeedTransformationType mTransformationType;
std::list<std::string> mXPathsToUse; std::list<std::string> mXPathsToUse;
std::list<std::string> mXPathsToRemove; std::list<std::string> mXPathsToRemove;
std::string mXslt; std::string mXslt;
TokenQueue *mTokenQueue; TokenQueue *mForumTokenQueue;
TokenQueue *mPostedTokenQueue;
UIStateHelper *mStateHelper; UIStateHelper *mStateHelper;
Ui::AddFeedDialog *ui; Ui::AddFeedDialog *ui;

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1068</width> <width>739</width>
<height>880</height> <height>653</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -45,48 +45,6 @@
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QGridLayout" name="gradFrame_GL"> <layout class="QGridLayout" name="gradFrame_GL">
<item row="3" column="0">
<widget class="QGroupBox" name="typeGroupBox">
<property name="title">
<string>Type</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="typeForumRadio">
<property name="text">
<string>Forum</string>
</property>
</widget>
</item>
<item>
<widget class="RSComboBox" name="forumComboBox"/>
</item>
</layout>
</item>
<item>
<widget class="QRadioButton" name="typeLocalRadio">
<property name="text">
<string>Local Feed</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="7" column="0"> <item row="7" column="0">
<widget class="QGroupBox" name="authenticationGroupBox"> <widget class="QGroupBox" name="authenticationGroupBox">
<property name="title"> <property name="title">
@ -309,7 +267,6 @@
<property name="font"> <property name="font">
<font> <font>
<pointsize>11</pointsize> <pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic> <italic>true</italic>
<bold>true</bold> <bold>true</bold>
</font> </font>
@ -324,7 +281,44 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="4" column="0"> <item row="3" column="1">
<widget class="QGroupBox" name="flagGroupBox">
<property name="title">
<string>Misc</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="activatedCheckBox">
<property name="text">
<string>Activated</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useInfoFromFeedCheckBox">
<property name="text">
<string>Use name and description from feed</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="embedImagesCheckBox">
<property name="text">
<string>Embed images</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="saveCompletePageCheckBox">
<property name="text">
<string>Save complete web page (experimental for local feeds)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="1">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>Transformation</string> <string>Transformation</string>
@ -357,46 +351,99 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="1" rowspan="2"> <item row="3" column="0" rowspan="3">
<widget class="QGroupBox" name="flagGroupBox"> <widget class="QGroupBox" name="typeGroupBox">
<property name="title"> <property name="title">
<string>Misc</string> <string>Type</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item> <property name="leftMargin">
<widget class="QCheckBox" name="activatedCheckBox"> <number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="typeForumCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>Activated</string> <string>Forum</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="1">
<widget class="QCheckBox" name="useInfoFromFeedCheckBox"> <widget class="RSComboBox" name="forumComboBox"/>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="typeLocalCheckBox">
<property name="text"> <property name="text">
<string>Use name and description from feed</string> <string>Local Feed</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="1" column="1">
<widget class="QCheckBox" name="updateForumInfoCheckBox"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="updateForumInfoCheckBox">
<property name="text">
<string>Update forum information</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="RSComboBox" name="postedComboBox"/>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="typePostedCheckBox">
<property name="text"> <property name="text">
<string>Update forum information</string> <string>Board</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="6" column="1">
<widget class="QCheckBox" name="embedImagesCheckBox"> <layout class="QGridLayout" name="gridLayout">
<property name="text"> <item row="0" column="0">
<string>Embed images</string> <widget class="QCheckBox" name="updatePostedInfoCheckBox">
</property> <property name="text">
</widget> <string>Update board information</string>
</item> </property>
<item> </widget>
<widget class="QCheckBox" name="saveCompletePageCheckBox"> </item>
<property name="text"> <item row="1" column="1">
<string>Save complete web page (experimental for local feeds)</string> <widget class="QCheckBox" name="postedOnlyImageCheckBox">
</property> <property name="text">
</widget> <string>Only image</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="postedFirstImageCheckBox">
<property name="text">
<string>Use first image as board image</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="postedShinkImageCheckBox">
<property name="text">
<string>Shrink image</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -423,22 +470,32 @@
<tabstop>urlLineEdit</tabstop> <tabstop>urlLineEdit</tabstop>
<tabstop>nameLineEdit</tabstop> <tabstop>nameLineEdit</tabstop>
<tabstop>descriptionPlainTextEdit</tabstop> <tabstop>descriptionPlainTextEdit</tabstop>
<tabstop>typeForumRadio</tabstop> <tabstop>typeForumCheckBox</tabstop>
<tabstop>forumComboBox</tabstop> <tabstop>forumComboBox</tabstop>
<tabstop>updateForumInfoCheckBox</tabstop>
<tabstop>typePostedCheckBox</tabstop>
<tabstop>postedComboBox</tabstop>
<tabstop>updatePostedInfoCheckBox</tabstop>
<tabstop>postedShinkImageCheckBox</tabstop>
<tabstop>postedFirstImageCheckBox</tabstop>
<tabstop>postedOnlyImageCheckBox</tabstop>
<tabstop>typeLocalCheckBox</tabstop>
<tabstop>activatedCheckBox</tabstop> <tabstop>activatedCheckBox</tabstop>
<tabstop>useInfoFromFeedCheckBox</tabstop> <tabstop>useInfoFromFeedCheckBox</tabstop>
<tabstop>updateForumInfoCheckBox</tabstop> <tabstop>embedImagesCheckBox</tabstop>
<tabstop>saveCompletePageCheckBox</tabstop>
<tabstop>previewButton</tabstop>
<tabstop>useAuthenticationCheckBox</tabstop> <tabstop>useAuthenticationCheckBox</tabstop>
<tabstop>userLineEdit</tabstop> <tabstop>userLineEdit</tabstop>
<tabstop>passwordLineEdit</tabstop> <tabstop>passwordLineEdit</tabstop>
<tabstop>useStandardStorageTimeCheckBox</tabstop> <tabstop>useStandardStorageTimeCheckBox</tabstop>
<tabstop>clearCachePushButton</tabstop>
<tabstop>storageTimeSpinBox</tabstop> <tabstop>storageTimeSpinBox</tabstop>
<tabstop>useStandardUpdateInterval</tabstop> <tabstop>useStandardUpdateInterval</tabstop>
<tabstop>updateIntervalSpinBox</tabstop> <tabstop>updateIntervalSpinBox</tabstop>
<tabstop>useStandardProxyCheckBox</tabstop> <tabstop>useStandardProxyCheckBox</tabstop>
<tabstop>proxyAddressLineEdit</tabstop> <tabstop>proxyAddressLineEdit</tabstop>
<tabstop>proxyPortSpinBox</tabstop> <tabstop>proxyPortSpinBox</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections/> <connections/>

View file

@ -35,6 +35,7 @@
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "gui/notifyqt.h" #include "gui/notifyqt.h"
#include "FeedReaderUserNotify.h" #include "FeedReaderUserNotify.h"
#include "gui/Posted/PostedCreatePostDialog.h"
#include "interface/rsFeedReader.h" #include "interface/rsFeedReader.h"
#include "retroshare/rsiface.h" #include "retroshare/rsiface.h"
@ -66,6 +67,7 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n
mMessageWidget = NULL; mMessageWidget = NULL;
connect(mNotify, &FeedReaderNotify::feedChanged, this, &FeedReaderDialog::feedChanged, Qt::QueuedConnection); 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())); connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
@ -84,9 +86,16 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n
connect(ui->feedAddButton, SIGNAL(clicked()), this, SLOT(newFeed())); connect(ui->feedAddButton, SIGNAL(clicked()), this, SLOT(newFeed()));
connect(ui->feedProcessButton, SIGNAL(clicked()), this, SLOT(processFeed())); connect(ui->feedProcessButton, SIGNAL(clicked()), this, SLOT(processFeed()));
connect(ui->feedTreeWidget, SIGNAL(feedReparent(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(feedTreeReparent(QTreeWidgetItem*,QTreeWidgetItem*)));
mFeedCompareRole = new RSTreeWidgetItemCompareRole; mFeedCompareRole = new RSTreeWidgetItemCompareRole;
mFeedCompareRole->setRole(COLUMN_FEED_NAME, ROLE_FEED_SORT); 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 */ /* initialize root item */
mRootItem = new QTreeWidgetItem(ui->feedTreeWidget); mRootItem = new QTreeWidgetItem(ui->feedTreeWidget);
QString name = tr("Message Folders"); QString name = tr("Message Folders");
@ -395,6 +404,9 @@ void FeedReaderDialog::updateFeeds(uint32_t parentId, QTreeWidgetItem *parentIte
mOpenFeedIds->removeAt(index); mOpenFeedIds->removeAt(index);
} }
} }
} else {
/* disable drop */
item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
} }
} }
@ -594,6 +606,37 @@ void FeedReaderDialog::feedChanged(uint32_t feedId, int type)
calculateFeedItems(); 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) FeedReaderMessageWidget *FeedReaderDialog::feedMessageWidget(uint32_t id)
{ {
int tabCount = ui->messageTabWidget->count(); int tabCount = ui->messageTabWidget->count();
@ -738,7 +781,7 @@ void FeedReaderDialog::newFolder()
if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) {
uint32_t feedId; 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.")); FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder."));
} }
} }
@ -791,7 +834,7 @@ void FeedReaderDialog::editFeed()
dialog.setTextValue(item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString()); dialog.setTextValue(item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString());
if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { 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.")); FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder."));
} }
} else { } else {
@ -832,3 +875,30 @@ void FeedReaderDialog::processFeed()
mFeedReader->processFeed(feedId); 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;
}
RsFeedResult 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();
}

View file

@ -61,6 +61,7 @@ private slots:
void editFeed(); void editFeed();
void activateFeed(); void activateFeed();
void processFeed(); void processFeed();
void feedTreeReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent);
void messageTabCloseRequested(int index); void messageTabCloseRequested(int index);
void messageTabChanged(int index); void messageTabChanged(int index);
@ -68,6 +69,7 @@ private slots:
/* FeedReaderNotify */ /* FeedReaderNotify */
void feedChanged(uint32_t feedId, int type); void feedChanged(uint32_t feedId, int type);
void shrinkImage();
private: private:
uint32_t currentFeedId(); uint32_t currentFeedId();

View file

@ -150,7 +150,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="RSTreeWidget" name="feedTreeWidget"> <widget class="FeedTreeWidget" name="feedTreeWidget">
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum> <enum>Qt::CustomContextMenu</enum>
</property> </property>
@ -186,9 +186,9 @@
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>
<class>RSTreeWidget</class> <class>FeedTreeWidget</class>
<extends>QTreeWidget</extends> <extends>QTreeWidget</extends>
<header>gui/common/RSTreeWidget.h</header> <header>gui/FeedTreeWidget.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>RSTabWidget</class> <class>RSTabWidget</class>

View file

@ -36,8 +36,12 @@
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "util/HandleRichText.h" #include "util/HandleRichText.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include "gui/Posted/PostedCreatePostDialog.h"
#include "gui/gxsforums/CreateGxsForumMsg.h"
#include "retroshare/rsiface.h" #include "retroshare/rsiface.h"
#include "retroshare/rsgxsforums.h"
#include "retroshare/rsposted.h"
#define COLUMN_MSG_COUNT 4 #define COLUMN_MSG_COUNT 4
#define COLUMN_MSG_TITLE 0 #define COLUMN_MSG_TITLE 0
@ -245,9 +249,19 @@ void FeedReaderMessageWidget::setFeedId(uint32_t feedId)
ui->msgReadAllButton->setEnabled(false); ui->msgReadAllButton->setEnabled(false);
ui->msgTreeWidget->setPlaceholderText(""); ui->msgTreeWidget->setPlaceholderText("");
} else { } else {
if (mFeedInfo.flag.forum) { if (mFeedInfo.flag.forum || mFeedInfo.flag.posted) {
ui->msgReadAllButton->setEnabled(false); 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 { } else {
ui->msgReadAllButton->setEnabled(true); ui->msgReadAllButton->setEnabled(true);
ui->msgTreeWidget->setPlaceholderText(""); ui->msgTreeWidget->setPlaceholderText("");
@ -340,6 +354,20 @@ void FeedReaderMessageWidget::msgTreeCustomPopupMenu(QPoint /*point*/)
action = contextMnu.addAction(QIcon(""), tr("Remove"), this, SLOT(removeMsg())); action = contextMnu.addAction(QIcon(""), tr("Remove"), this, SLOT(removeMsg()));
action->setEnabled(!selectedItems.empty()); 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(); contextMnu.addSeparator();
action = contextMnu.addAction(QIcon(""), tr("Retransform"), this, SLOT(retransformMsg())); action = contextMnu.addAction(QIcon(""), tr("Retransform"), this, SLOT(retransformMsg()));
@ -840,3 +868,104 @@ void FeedReaderMessageWidget::openLinkMsg()
QDesktopServices::openUrl(QUrl(link)); QDesktopServices::openUrl(QUrl(link));
} }
void FeedReaderMessageWidget::fillForumMenu()
{
QMenu *menu = dynamic_cast<QMenu*>(sender()) ;
if (!menu) {
return;
}
disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(fillForumMenu()));
std::vector<RsGxsForumGroup> groups;
if (mFeedReader->getForumGroups(groups, true)) {
for (std::vector<RsGxsForumGroup>::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<QMenu*>(sender()) ;
if (!menu) {
return;
}
disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(fillPostedMenu()));
std::vector<RsPostedGroup> groups;
if (mFeedReader->getPostedGroups(groups, true)) {
for (std::vector<RsPostedGroup>::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<QAction*>(sender()) ;
if (!action) {
return;
}
QString id = action->data().toString();
if (id.isEmpty()) {
return;
}
QList<QTreeWidgetItem*> 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<QAction*>(sender()) ;
if (!action) {
return;
}
QString id = action->data().toString();
if (id.isEmpty()) {
return;
}
QList<QTreeWidgetItem*> 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();
}

View file

@ -73,6 +73,10 @@ private slots:
void openLinkMsg(); void openLinkMsg();
void copyLinkMsg(); void copyLinkMsg();
void retransformMsg(); void retransformMsg();
void fillForumMenu();
void fillPostedMenu();
void addToForum();
void addToPosted();
/* FeedReaderNotify */ /* FeedReaderNotify */
void feedChanged(uint32_t feedId, int type); void feedChanged(uint32_t feedId, int type);

View file

@ -33,3 +33,8 @@ void FeedReaderNotify::notifyMsgChanged(uint32_t feedId, const std::string &msgI
{ {
emit msgChanged(feedId, QString::fromStdString(msgId), type); emit msgChanged(feedId, QString::fromStdString(msgId), type);
} }
void FeedReaderNotify::notifyShrinkImage()
{
emit shrinkImage();
}

View file

@ -34,10 +34,12 @@ public:
/* RsFeedReaderNotify */ /* RsFeedReaderNotify */
virtual void notifyFeedChanged(uint32_t feedId, int type); virtual void notifyFeedChanged(uint32_t feedId, int type);
virtual void notifyMsgChanged(uint32_t feedId, const std::string &msgId, int type); virtual void notifyMsgChanged(uint32_t feedId, const std::string &msgId, int type);
virtual void notifyShrinkImage();
signals: signals:
void feedChanged(uint32_t feedId, int type); void feedChanged(uint32_t feedId, int type);
void msgChanged(uint32_t feedId, const QString &msgId, int type); void msgChanged(uint32_t feedId, const QString &msgId, int type);
void shrinkImage();
}; };
#endif #endif

View file

@ -23,27 +23,27 @@
#include "FeedReaderStringDefs.h" #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; QString error;
switch (result) { switch (result) {
case RS_FEED_ADD_RESULT_SUCCESS: case RS_FEED_RESULT_SUCCESS:
/* no error */ /* no error */
return false; return false;
case RS_FEED_ADD_RESULT_FEED_NOT_FOUND: case RS_FEED_RESULT_FEED_NOT_FOUND:
error = QApplication::translate("FeedReaderStringDefs", "Feed not found."); error = QApplication::translate("FeedReaderStringDefs", "Feed not found.");
break; break;
case RS_FEED_ADD_RESULT_PARENT_NOT_FOUND: case RS_FEED_RESULT_PARENT_NOT_FOUND:
error = QApplication::translate("FeedReaderStringDefs", "Parent not found."); error = QApplication::translate("FeedReaderStringDefs", "Parent not found.");
break; 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."); error = QApplication::translate("FeedReaderStringDefs", "Parent is no folder.");
break; break;
case RS_FEED_ADD_RESULT_FEED_IS_FOLDER: case RS_FEED_RESULT_FEED_IS_FOLDER:
error = QApplication::translate("FeedReaderStringDefs", "Feed is a folder."); error = QApplication::translate("FeedReaderStringDefs", "Feed is a folder.");
break; 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."); error = QApplication::translate("FeedReaderStringDefs", "Feed is no folder.");
break; break;
default: default:
@ -101,6 +101,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con
case RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE: case RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE:
errorText = QApplication::translate("FeedReaderStringDefs", "Unknown response code"); errorText = QApplication::translate("FeedReaderStringDefs", "Unknown response code");
break; break;
case RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED:
errorText = QApplication::translate("FeedReaderStringDefs", "Download blocked");
break;
/* process */ /* process */
case RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR: case RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR:
@ -109,9 +112,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con
case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT: case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT:
errorText = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); errorText = QApplication::translate("FeedReaderStringDefs", "Unknown XML format");
break; break;
case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: // case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE:
errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); // errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum");
break; // break;
case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND: case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND:
errorText = QApplication::translate("FeedReaderStringDefs", "Forum not found"); errorText = QApplication::translate("FeedReaderStringDefs", "Forum not found");
break; break;
@ -121,6 +124,18 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con
case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR: case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR:
errorText = QApplication::translate("FeedReaderStringDefs", "Forum has no author"); errorText = QApplication::translate("FeedReaderStringDefs", "Forum has no author");
break; 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: case RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR:
errorText = QApplication::translate("FeedReaderStringDefs", "Can't read html"); errorText = QApplication::translate("FeedReaderStringDefs", "Can't read html");

View file

@ -30,7 +30,7 @@ class QWidget;
class FeedReaderStringDefs class FeedReaderStringDefs
{ {
public: 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 workState(FeedInfo::WorkState state);
static QString errorString(const FeedInfo &feedInfo); static QString errorString(const FeedInfo &feedInfo);
static QString errorString(RsFeedReaderErrorState errorState, const std::string &errorString); static QString errorString(RsFeedReaderErrorState errorState, const std::string &errorString);

View file

@ -0,0 +1,119 @@
/*******************************************************************************
* plugins/FeedReader/gui/FeedTreeWidget.cpp *
* *
* Copyright (C) 2012 RetroShare Team <retroshare.project@gmail.com> *
* *
* 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 <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QDropEvent>
#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);
}

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* plugins/FeedReader/gui/FeedTreeWidget.h *
* *
* Copyright (C) 2012 by Retroshare Team <retroshare.project@gmail.com> *
* *
* 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 <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#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

View file

@ -25,8 +25,13 @@
#include <inttypes.h> #include <inttypes.h>
#include <string> #include <string>
#include <list> #include <list>
#include <vector>
class RsFeedReader; class RsFeedReader;
class RsGxsForums;
class RsPosted;
class RsGxsForumGroup;
class RsPostedGroup;
extern RsFeedReader *rsFeedReader; extern RsFeedReader *rsFeedReader;
enum RsFeedReaderErrorState { enum RsFeedReaderErrorState {
@ -38,14 +43,19 @@ enum RsFeedReaderErrorState {
RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3, RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3,
RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4, RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4,
RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5, RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5,
RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED = 6,
/* process */ /* process */
RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50,
RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, 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_NOT_FOUND = 101,
RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102,
RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR = 103, 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_HTML_ERROR = 150,
RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR = 151, RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR = 151,
@ -56,14 +66,14 @@ enum RsFeedReaderErrorState {
RS_FEED_ERRORSTATE_PROCESS_XSLT_NO_RESULT = 156 RS_FEED_ERRORSTATE_PROCESS_XSLT_NO_RESULT = 156
}; };
enum RsFeedAddResult enum RsFeedResult
{ {
RS_FEED_ADD_RESULT_SUCCESS, RS_FEED_RESULT_SUCCESS,
RS_FEED_ADD_RESULT_FEED_NOT_FOUND, RS_FEED_RESULT_FEED_NOT_FOUND,
RS_FEED_ADD_RESULT_PARENT_NOT_FOUND, RS_FEED_RESULT_PARENT_NOT_FOUND,
RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER, RS_FEED_RESULT_PARENT_IS_NO_FOLDER,
RS_FEED_ADD_RESULT_FEED_IS_FOLDER, RS_FEED_RESULT_FEED_IS_FOLDER,
RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER RS_FEED_RESULT_FEED_IS_NO_FOLDER
}; };
enum RsFeedTransformationType enum RsFeedTransformationType
@ -102,6 +112,8 @@ public:
flag.deactivated = false; flag.deactivated = false;
flag.forum = false; flag.forum = false;
flag.updateForumInfo = false; flag.updateForumInfo = false;
flag.posted = false;
flag.updatePostedInfo = false;
flag.embedImages = false; flag.embedImages = false;
flag.saveCompletePage = false; flag.saveCompletePage = false;
flag.preview = false; flag.preview = false;
@ -122,6 +134,7 @@ public:
time_t lastUpdate; time_t lastUpdate;
uint32_t storageTime; uint32_t storageTime;
std::string forumId; std::string forumId;
std::string postedId;
WorkState workstate; WorkState workstate;
RsFeedReaderErrorState errorState; RsFeedReaderErrorState errorState;
std::string errorString; std::string errorString;
@ -141,6 +154,11 @@ public:
bool deactivated : 1; bool deactivated : 1;
bool forum : 1; bool forum : 1;
bool updateForumInfo : 1; bool updateForumInfo : 1;
bool posted : 1;
bool updatePostedInfo : 1;
bool postedFirstImage : 1;
bool postedOnlyImage : 1;
bool postedShrinkImage : 1;
bool embedImages : 1; bool embedImages : 1;
bool saveCompletePage : 1; bool saveCompletePage : 1;
bool preview : 1; bool preview : 1;
@ -174,6 +192,28 @@ public:
} flag; } flag;
}; };
class FeedReaderShrinkImageTask
{
public:
enum Type {
POSTED
};
public:
Type mType;
std::vector<unsigned char> mImage;
std::vector<unsigned char> mImageResult;
bool mResult;
public:
FeedReaderShrinkImageTask(Type type, const std::vector<unsigned char> &image)
{
mType = type;
mImage = image;
mResult = false;
}
};
class RsFeedReaderNotify class RsFeedReaderNotify
{ {
public: public:
@ -181,6 +221,7 @@ public:
virtual void notifyFeedChanged(uint32_t /*feedId*/, int /*type*/) {} virtual void notifyFeedChanged(uint32_t /*feedId*/, int /*type*/) {}
virtual void notifyMsgChanged(uint32_t /*feedId*/, const std::string &/*msgId*/, int /*type*/) {} virtual void notifyMsgChanged(uint32_t /*feedId*/, const std::string &/*msgId*/, int /*type*/) {}
virtual void notifyShrinkImage() {}
}; };
class RsFeedReader class RsFeedReader
@ -201,24 +242,33 @@ public:
virtual bool getSaveInBackground() = 0; virtual bool getSaveInBackground() = 0;
virtual void setSaveInBackground(bool saveInBackground) = 0; virtual void setSaveInBackground(bool saveInBackground) = 0;
virtual RsFeedAddResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) = 0; virtual RsFeedResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) = 0;
virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name) = 0; virtual RsFeedResult setFolder(uint32_t feedId, const std::string &name) = 0;
virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; virtual RsFeedResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0;
virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0; virtual RsFeedResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0;
virtual bool removeFeed(uint32_t feedId) = 0; virtual RsFeedResult setParent(uint32_t feedId, uint32_t parentId) = 0;
virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; virtual bool removeFeed(uint32_t feedId) = 0;
virtual void getFeedList(uint32_t parentId, std::list<FeedInfo> &feedInfos) = 0; virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0;
virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo) = 0; virtual void getFeedList(uint32_t parentId, std::list<FeedInfo> &feedInfos) = 0;
virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo) = 0;
virtual bool removeMsg(uint32_t feedId, const std::string &msgId) = 0; virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0;
virtual bool removeMsgs(uint32_t feedId, const std::list<std::string> &msgIds) = 0; virtual bool removeMsg(uint32_t feedId, const std::string &msgId) = 0;
virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; virtual bool removeMsgs(uint32_t feedId, const std::list<std::string> &msgIds) = 0;
virtual bool getFeedMsgList(uint32_t feedId, std::list<FeedMsgInfo> &msgInfos) = 0; virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0;
virtual bool getFeedMsgIdList(uint32_t feedId, std::list<std::string> &msgIds) = 0; virtual bool getFeedMsgList(uint32_t feedId, std::list<FeedMsgInfo> &msgInfos) = 0;
virtual bool processFeed(uint32_t feedId) = 0; virtual bool getFeedMsgIdList(uint32_t feedId, std::list<std::string> &msgIds) = 0;
virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read) = 0; virtual bool processFeed(uint32_t feedId) = 0;
virtual bool retransformMsg(uint32_t feedId, const std::string &msgId) = 0; virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read) = 0;
virtual bool clearMessageCache(uint32_t feedId) = 0; 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<RsGxsForumGroup> &groups, bool onlyOwn) = 0;
virtual bool getPostedGroups(std::vector<RsPostedGroup> &groups, bool onlyOwn) = 0;
virtual FeedReaderShrinkImageTask *getShrinkImageTask() = 0;
virtual void setShrinkImageTaskResult(FeedReaderShrinkImageTask *shrinkImageTask) = 0;
virtual RsFeedReaderErrorState processXPath(const std::list<std::string> &xpathsToUse, const std::list<std::string> &xpathsToRemove, std::string &description, std::string &errorString) = 0; virtual RsFeedReaderErrorState processXPath(const std::list<std::string> &xpathsToUse, const std::list<std::string> &xpathsToRemove, std::string &description, std::string &errorString) = 0;
virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString) = 0; virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString) = 0;

View file

@ -9,7 +9,32 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+79"/> <location line="+398"/>
<source>Board</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+9"/>
<source>Update board information</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+7"/>
<source>Only image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+7"/>
<source>Use first image as board image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+7"/>
<source>Shrink image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="-391"/>
<source>Authentication (not yet supported)</source> <source>Authentication (not yet supported)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -59,12 +84,12 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+121"/> <location line="+88"/>
<source>Embed images</source> <source>Embed images</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="-249"/> <location line="-216"/>
<source>Storage time</source> <source>Storage time</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -99,22 +124,22 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="-148"/> <location line="+200"/>
<source>Type</source> <source>Type</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+20"/> <location line="+24"/>
<source>Forum</source> <source>Forum</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+12"/> <location line="+10"/>
<source>Local Feed</source> <source>Local Feed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+239"/> <location line="-67"/>
<source>Transformation</source> <source>Transformation</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -129,7 +154,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+12"/> <location line="-58"/>
<source>Misc</source> <source>Misc</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -144,17 +169,17 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+7"/> <location line="+100"/>
<source>Update forum information</source> <source>Update forum information</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+14"/> <location line="-86"/>
<source>Save complete web page (experimental for local feeds)</source> <source>Save complete web page (experimental for local feeds)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="-103"/> <location line="-70"/>
<source>Description:</source> <source>Description:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -164,18 +189,18 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+10"/> <location line="+17"/>
<source>Name:</source> <source>Name:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../gui/AddFeedDialog.cpp" line="+77"/> <location filename="../gui/AddFeedDialog.cpp" line="+87"/>
<source>Feed Details</source> <source>Feed Details</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+142"/> <location line="+211"/>
<location line="+115"/> <location line="+152"/>
<location line="+15"/> <location line="+15"/>
<source>Edit feed</source> <source>Edit feed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -277,7 +302,7 @@
<context> <context>
<name>FeedReaderDialog</name> <name>FeedReaderDialog</name>
<message> <message>
<location filename="../gui/FeedReaderDialog.ui" line="+91"/> <location filename="../gui/FeedReaderDialog.ui" line="+98"/>
<source>Feeds</source> <source>Feeds</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -292,7 +317,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../gui/FeedReaderDialog.cpp" line="+92"/> <location filename="../gui/FeedReaderDialog.cpp" line="+101"/>
<source>Message Folders</source> <source>Message Folders</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -342,12 +367,12 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+195"/> <location line="+198"/>
<source>No name</source> <source>No name</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+210"/> <location line="+241"/>
<source>Add new folder</source> <source>Add new folder</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -398,11 +423,21 @@
<source>Please enter a new name for the folder</source> <source>Please enter a new name for the folder</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location line="+61"/>
<source>Move feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+0"/>
<source>Cannot move feed.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FeedReaderFeedItem</name> <name>FeedReaderFeedItem</name>
<message> <message>
<location filename="../gui/FeedReaderFeedItem.ui" line="+195"/> <location filename="../gui/FeedReaderFeedItem.ui" line="+197"/>
<location filename="../gui/FeedReaderFeedItem.cpp" line="+116"/> <location filename="../gui/FeedReaderFeedItem.cpp" line="+116"/>
<source>Expand</source> <source>Expand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -500,7 +535,7 @@
</message> </message>
<message> <message>
<location line="+26"/> <location line="+26"/>
<location filename="../gui/FeedReaderMessageWidget.cpp" line="+113"/> <location filename="../gui/FeedReaderMessageWidget.cpp" line="+117"/>
<source>Title</source> <source>Title</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -542,12 +577,22 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+122"/> <location line="+127"/>
<source>The messages will be added to the forum</source> <source>The messages will be added to the forum</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+15"/> <location line="-3"/>
<source>The messages will be added to the forum and the board</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+6"/>
<source>The messages will be added to the board</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+17"/>
<source>No name</source> <source>No name</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -576,8 +621,18 @@
<source>Remove</source> <source>Remove</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location line="+7"/>
<source>Add to forum</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location line="+5"/> <location line="+5"/>
<source>Add to board</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+7"/>
<source>Retransform</source> <source>Retransform</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -659,12 +714,12 @@
</message> </message>
<message> <message>
<location line="+3"/> <location line="+3"/>
<location line="+96"/> <location line="+111"/>
<source>Unknown</source> <source>Unknown</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="-79"/> <location line="-94"/>
<source>Internal download error</source> <source>Internal download error</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -688,6 +743,11 @@
<source>Unknown response code</source> <source>Unknown response code</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location line="+3"/>
<source>Download blocked</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location line="+5"/> <location line="+5"/>
<source>Internal process error</source> <source>Internal process error</source>
@ -699,12 +759,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+3"/> <location line="+6"/>
<source>Can&apos;t create forum</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+3"/>
<source>Forum not found</source> <source>Forum not found</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -718,6 +773,21 @@
<source>Forum has no author</source> <source>Forum has no author</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location line="+6"/>
<source>Board not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+3"/>
<source>You are not admin of the board</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+3"/>
<source>Board has no author</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location line="+4"/> <location line="+4"/>
<source>Can&apos;t read html</source> <source>Can&apos;t read html</source>
@ -790,7 +860,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+47"/> <location line="+55"/>
<source>Name:</source> <source>Name:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -825,7 +895,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location line="+20"/> <location line="+28"/>
<source>Title:</source> <source>Title:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -24,6 +24,7 @@
#include "rsitems/rsconfigitems.h" #include "rsitems/rsconfigitems.h"
#include "retroshare/rsiface.h" #include "retroshare/rsiface.h"
#include "retroshare/rsgxsforums.h" #include "retroshare/rsgxsforums.h"
#include "retroshare/rsposted.h"
#include "util/rsstring.h" #include "util/rsstring.h"
#include "util/rstime.h" #include "util/rstime.h"
#include "gxs/rsgenexchange.h" #include "gxs/rsgenexchange.h"
@ -34,6 +35,7 @@ RsFeedReader *rsFeedReader = NULL;
#define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour #define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour
#define FEEDREADER_FORUM_PREFIX "RSS: " #define FEEDREADER_FORUM_PREFIX "RSS: "
#define FEEDREADER_POSTED_PREFIX "RSS: "
#define MAX_REQUEST_AGE 30 // 30 seconds #define MAX_REQUEST_AGE 30 // 30 seconds
@ -41,9 +43,9 @@ RsFeedReader *rsFeedReader = NULL;
* #define FEEDREADER_DEBUG * #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), : 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; mNextFeedId = 1;
mNextMsgId = 1; mNextMsgId = 1;
@ -55,6 +57,7 @@ p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums)
mStandardProxyPort = 0; mStandardProxyPort = 0;
mLastClean = 0; mLastClean = 0;
mForums = forums; mForums = forums;
mPosted = posted;
mNotify = NULL; mNotify = NULL;
mSaveInBackground = false; mSaveInBackground = false;
mStopped = false; mStopped = false;
@ -92,6 +95,7 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info)
info.updateInterval = feed->updateInterval; info.updateInterval = feed->updateInterval;
info.lastUpdate = feed->lastUpdate; info.lastUpdate = feed->lastUpdate;
info.forumId = feed->forumId; info.forumId = feed->forumId;
info.postedId = feed->postedId;
info.storageTime = feed->storageTime; info.storageTime = feed->storageTime;
info.errorState = feed->errorState; info.errorState = feed->errorState;
info.errorString = feed->errorString; info.errorString = feed->errorString;
@ -110,6 +114,11 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info)
info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED); info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED);
info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM); info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM);
info.flag.updateForumInfo = (feed->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO); 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.postedShrinkImage = (feed->flag & RS_FEED_FLAG_POSTED_SHRINK_IMAGE);
info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES);
info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE);
@ -151,6 +160,7 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed)
feed->storageTime = info.storageTime; feed->storageTime = info.storageTime;
feed->forumId = info.forumId; feed->forumId = info.forumId;
feed->postedId = info.postedId;
feed->transformationType = info.transformationType; feed->transformationType = info.transformationType;
feed->xpathsToUse.ids = info.xpathsToUse; feed->xpathsToUse.ids = info.xpathsToUse;
@ -193,6 +203,24 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed)
if (info.flag.updateForumInfo) { if (info.flag.updateForumInfo) {
feed->flag |= RS_FEED_FLAG_UPDATE_FORUM_INFO; 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;
}
if (info.flag.postedShrinkImage) {
feed->flag |= RS_FEED_FLAG_POSTED_SHRINK_IMAGE;
}
} }
static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info)
@ -245,7 +273,7 @@ void p3FeedReader::setStandardStorageTime(uint32_t storageTime)
if (mStandardStorageTime != storageTime) { if (mStandardStorageTime != storageTime) {
mStandardStorageTime = storageTime; mStandardStorageTime = storageTime;
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -262,7 +290,7 @@ void p3FeedReader::setStandardUpdateInterval(uint32_t updateInterval)
if (mStandardUpdateInterval != updateInterval) { if (mStandardUpdateInterval != updateInterval) {
mStandardUpdateInterval = updateInterval; mStandardUpdateInterval = updateInterval;
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -284,7 +312,7 @@ void p3FeedReader::setStandardProxy(bool useProxy, const std::string &proxyAddre
mStandardProxyAddress = proxyAddress; mStandardProxyAddress = proxyAddress;
mStandardProxyPort = proxyPort; mStandardProxyPort = proxyPort;
mStandardUseProxy = useProxy; mStandardUseProxy = useProxy;
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -301,7 +329,7 @@ void p3FeedReader::setSaveInBackground(bool saveInBackground)
if (saveInBackground != mSaveInBackground) { if (saveInBackground != mSaveInBackground) {
mSaveInBackground = saveInBackground; mSaveInBackground = saveInBackground;
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -342,7 +370,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; feedId = 0;
@ -356,14 +384,14 @@ RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &na
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::addFolder - parent id " << parentId << " not found" << std::endl; std::cerr << "p3FeedReader::addFolder - parent id " << parentId << " not found" << std::endl;
#endif #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) { if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) {
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::addFolder - parent " << parentIt->second->name << " is no folder" << std::endl; std::cerr << "p3FeedReader::addFolder - parent " << parentIt->second->name << " is no folder" << std::endl;
#endif #endif
return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; return RS_FEED_RESULT_PARENT_IS_NO_FOLDER;
} }
} }
@ -377,16 +405,16 @@ RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &na
feedId = fi->feedId; feedId = fi->feedId;
} }
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); 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 *********/ RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/
@ -400,33 +428,33 @@ RsFeedAddResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::setFolder - feed id " << feedId << " not found" << std::endl; std::cerr << "p3FeedReader::setFolder - feed id " << feedId << " not found" << std::endl;
#endif #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) { if ((feedIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) {
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::setFolder - feed " << feedIt->second->name << " is no folder" << std::endl; std::cerr << "p3FeedReader::setFolder - feed " << feedIt->second->name << " is no folder" << std::endl;
#endif #endif
return RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER; return RS_FEED_RESULT_FEED_IS_NO_FOLDER;
} }
RsFeedReaderFeed *fi = feedIt->second; RsFeedReaderFeed *fi = feedIt->second;
if (fi->name == name) { if (fi->name == name) {
return RS_FEED_ADD_RESULT_SUCCESS; return RS_FEED_RESULT_SUCCESS;
} }
fi->name = name; fi->name = name;
} }
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); 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; feedId = 0;
@ -444,14 +472,14 @@ RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::addFeed - parent id " << feedInfo.parentId << " not found" << std::endl; std::cerr << "p3FeedReader::addFeed - parent id " << feedInfo.parentId << " not found" << std::endl;
#endif #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) { if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) {
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::addFeed - parent " << parentIt->second->name << " is no folder" << std::endl; std::cerr << "p3FeedReader::addFeed - parent " << parentIt->second->name << " is no folder" << std::endl;
#endif #endif
return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; return RS_FEED_RESULT_PARENT_IS_NO_FOLDER;
} }
} }
@ -464,20 +492,23 @@ RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId
feedId = fi->feedId; feedId = fi->feedId;
} }
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); 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 forumId;
std::string forumName; std::string forumName;
std::string forumDescription; std::string forumDescription;
std::string postedId;
std::string postedName;
std::string postedDescription;
{ {
RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/
@ -491,14 +522,14 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo)
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::setFeed - feed id " << feedId << " not found" << std::endl; std::cerr << "p3FeedReader::setFeed - feed id " << feedId << " not found" << std::endl;
#endif #endif
return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; return RS_FEED_RESULT_FEED_NOT_FOUND;
} }
if (feedIt->second->flag & RS_FEED_FLAG_FOLDER) { if (feedIt->second->flag & RS_FEED_FLAG_FOLDER) {
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::setFeed - feed " << feedIt->second->name << " is a folder" << std::endl; std::cerr << "p3FeedReader::setFeed - feed " << feedIt->second->name << " is a folder" << std::endl;
#endif #endif
return RS_FEED_ADD_RESULT_FEED_IS_FOLDER; return RS_FEED_RESULT_FEED_IS_FOLDER;
} }
if (feedInfo.parentId) { if (feedInfo.parentId) {
@ -508,19 +539,20 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo)
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::setFeed - parent id " << feedInfo.parentId << " not found" << std::endl; std::cerr << "p3FeedReader::setFeed - parent id " << feedInfo.parentId << " not found" << std::endl;
#endif #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) { if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) {
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReader::setFeed - parent " << parentIt->second->name << " is no folder" << std::endl; std::cerr << "p3FeedReader::setFeed - parent " << parentIt->second->name << " is no folder" << std::endl;
#endif #endif
return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; return RS_FEED_RESULT_PARENT_IS_NO_FOLDER;
} }
} }
RsFeedReaderFeed *fi = feedIt->second; RsFeedReaderFeed *fi = feedIt->second;
std::string oldForumId = fi->forumId; std::string oldForumId = fi->forumId;
std::string oldPostedId = fi->postedId;
std::string oldName = fi->name; std::string oldName = fi->name;
std::string oldDescription = fi->description; std::string oldDescription = fi->description;
@ -534,9 +566,18 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo)
forumDescription = fi->description; forumDescription = fi->description;
forumName.insert(0, FEEDREADER_FORUM_PREFIX); 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(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD);
@ -550,7 +591,71 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo)
//TODO: error //TODO: error
} }
return RS_FEED_ADD_RESULT_SUCCESS; if (!postedId.empty()) {
RsPostedGroup postedGroup;
if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) {
updatePostedGroup(postedGroup, postedName, postedDescription);
}
//TODO: error
}
return RS_FEED_RESULT_SUCCESS;
}
RsFeedResult 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<uint32_t, RsFeedReaderFeed*>::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_RESULT_FEED_NOT_FOUND;
}
if (parentId) {
/* check parent id */
std::map<uint32_t, RsFeedReaderFeed*>::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_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_RESULT_PARENT_IS_NO_FOLDER;
}
}
RsFeedReaderFeed *fi = feedIt->second;
if (fi->parentId != parentId) {
fi->parentId = parentId;
changed = true;
}
}
if (changed) {
IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD);
}
}
return RS_FEED_RESULT_SUCCESS;
} }
void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi)
@ -628,7 +733,7 @@ bool p3FeedReader::removeFeed(uint32_t feedId)
} }
if (changed) { if (changed) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
if (preview) { if (preview) {
@ -682,6 +787,7 @@ bool p3FeedReader::addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId)
fi->updateInterval = 0; fi->updateInterval = 0;
fi->lastUpdate = 0; fi->lastUpdate = 0;
fi->forumId.clear(); fi->forumId.clear();
fi->postedId.clear();
fi->storageTime = 0; fi->storageTime = 0;
mFeeds[fi->feedId] = fi; mFeeds[fi->feedId] = fi;
@ -808,7 +914,7 @@ bool p3FeedReader::removeMsg(uint32_t feedId, const std::string &msgId)
} }
if (changed) { if (changed) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
if (mNotify) { if (mNotify) {
@ -860,7 +966,7 @@ bool p3FeedReader::removeMsgs(uint32_t feedId, const std::list<std::string> &msg
} }
if (changed) { if (changed) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
if (mNotify && !removedMsgs.empty()) { if (mNotify && !removedMsgs.empty()) {
@ -1158,7 +1264,7 @@ bool p3FeedReader::setMessageRead(uint32_t feedId, const std::string &msgId, boo
} }
if (changed) { if (changed) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD);
mNotify->notifyMsgChanged(feedId, msgId, NOTIFY_TYPE_MOD); mNotify->notifyMsgChanged(feedId, msgId, NOTIFY_TYPE_MOD);
@ -1212,7 +1318,7 @@ bool p3FeedReader::retransformMsg(uint32_t feedId, const std::string &msgId)
} }
if (feedChanged || msgChanged) { if (feedChanged || msgChanged) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
if (feedChanged) { if (feedChanged) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD);
@ -1266,7 +1372,7 @@ bool p3FeedReader::clearMessageCache(uint32_t feedId)
} }
} }
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
return true; return true;
} }
@ -1343,10 +1449,21 @@ int p3FeedReader::tick()
} }
} }
// check images
bool imageToShrink = false;
{
RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/
imageToShrink = !mImages.empty();
}
if (mNotify) { if (mNotify) {
for (it = notifyIds.begin(); it != notifyIds.end(); ++it) { for (it = notifyIds.begin(); it != notifyIds.end(); ++it) {
mNotify->notifyFeedChanged(*it, NOTIFY_TYPE_MOD); mNotify->notifyFeedChanged(*it, NOTIFY_TYPE_MOD);
} }
if (imageToShrink) {
mNotify->notifyShrinkImage();
}
} }
return 0; return 0;
@ -1397,7 +1514,7 @@ void p3FeedReader::cleanFeeds()
mLastClean = currentTime; mLastClean = currentTime;
if (removedMsgIds.size()) { if (removedMsgIds.size()) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
if (mNotify) { if (mNotify) {
std::list<std::pair<uint32_t, std::string> >::iterator it; std::list<std::pair<uint32_t, std::string> >::iterator it;
@ -1709,7 +1826,7 @@ void p3FeedReader::onDownloadSuccess(uint32_t feedId, const std::string &content
fi->icon = icon; fi->icon = icon;
if (!preview) { if (!preview) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -1760,7 +1877,7 @@ void p3FeedReader::onDownloadError(uint32_t feedId, RsFeedReaderErrorState resul
#endif #endif
if (!fi->preview) { if (!fi->preview) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -1872,7 +1989,7 @@ void p3FeedReader::onProcessSuccess_filterMsg(uint32_t feedId, std::list<RsFeedR
fi->errorString.clear(); fi->errorString.clear();
if (!fi->preview) { if (!fi->preview) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
} }
@ -1885,8 +2002,12 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
std::list<std::string> addedMsgs; std::list<std::string> addedMsgs;
std::string forumId; std::string forumId;
RsGxsId authorId; RsGxsId forumAuthorId;
std::list<RsFeedReaderMsg> forumMsgs; std::list<RsFeedReaderMsg> forumMsgs;
std::string postedId;
RsGxsId postedAuthorId;
std::list<RsFeedReaderMsg> postedMsgs;
uint32_t feedFlag = 0;
{ {
RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/
@ -1903,7 +2024,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
RsFeedReaderFeed *fi = it->second; RsFeedReaderFeed *fi = it->second;
bool forum = (fi->flag & RS_FEED_FLAG_FORUM) && !fi->preview; 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; RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK;
feedFlag = fi->flag;
if (forum && !msgs.empty()) { if (forum && !msgs.empty()) {
if (mForums) { if (mForums) {
@ -1913,9 +2036,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
if (getForumGroup(RsGxsGroupId(fi->forumId), forumGroup)) { if (getForumGroup(RsGxsGroupId(fi->forumId), forumGroup)) {
if (IS_GROUP_PUBLISHER(forumGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(forumGroup.mMeta.mSubscribeFlags)) { if (IS_GROUP_PUBLISHER(forumGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(forumGroup.mMeta.mSubscribeFlags)) {
forumId = fi->forumId; 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; errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR;
} }
} else { } else {
@ -1933,6 +2056,34 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
} }
} }
if (posted && !msgs.empty()) {
if (mPosted) {
if (!fi->postedId.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 */ /* process msgs */
if (errorState == RS_FEED_ERRORSTATE_OK) { if (errorState == RS_FEED_ERRORSTATE_OK) {
/* process msgs */ /* process msgs */
@ -1949,9 +2100,14 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
} else { } else {
rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); rs_sprintf(miNew->msgId, "%lu", mNextMsgId++);
} }
if (forum) { if (forum || posted) {
miNew->flag = RS_FEEDMSG_FLAG_DELETED; 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->description.clear();
miNew->descriptionTransformed.clear(); miNew->descriptionTransformed.clear();
} else { } else {
@ -1978,7 +2134,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
} }
if (!fi->preview) { if (!fi->preview) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -1996,7 +2152,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
RsGxsForumMsg forumMsg; RsGxsForumMsg forumMsg;
forumMsg.mMeta.mGroupId = RsGxsGroupId(forumId); forumMsg.mMeta.mGroupId = RsGxsGroupId(forumId);
forumMsg.mMeta.mMsgName = mi.title; forumMsg.mMeta.mMsgName = mi.title;
forumMsg.mMeta.mAuthorId = authorId; forumMsg.mMeta.mAuthorId = forumAuthorId;
std::string description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; std::string description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed;
/* add link */ /* add link */
@ -2006,7 +2162,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
forumMsg.mMsg = description; forumMsg.mMsg = description;
uint32_t token; uint32_t token;
if (mForums->createMsg(token, forumMsg) && waitForToken(token)) { if (mForums->createMsg(token, forumMsg) && waitForToken(mForums, token)) {
RsGxsGrpMsgIdPair msgPair; RsGxsGrpMsgIdPair msgPair;
if (mForums->acknowledgeMsg(token, msgPair)) { if (mForums->acknowledgeMsg(token, msgPair)) {
/* set to new */ /* set to new */
@ -2026,6 +2182,75 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list<RsFeedRea
} }
} }
if (!postedId.empty() && !postedMsgs.empty()) {
if (mPosted) {
/* a bit tricky */
RsGenExchange *genExchange = dynamic_cast<RsGenExchange*>(mPosted);
if (genExchange) {
/* add messages as posted messages */
std::list<RsFeedReaderMsg>::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 */
if (feedFlag & RS_FEED_FLAG_POSTED_SHRINK_IMAGE) {
// shrink image
std::vector<unsigned char> 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 {
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) { if (mNotify) {
mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD);
@ -2064,7 +2289,7 @@ void p3FeedReader::onProcessError(uint32_t feedId, RsFeedReaderErrorState result
#endif #endif
if (!fi->preview) { if (!fi->preview) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
} }
@ -2080,6 +2305,9 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s
std::string forumId; std::string forumId;
std::string forumName; std::string forumName;
std::string forumDescription; std::string forumDescription;
std::string postedId;
std::string postedName;
std::string postedDescription;
{ {
RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/
@ -2118,11 +2346,19 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s
forumDescription = fi->description; forumDescription = fi->description;
forumName.insert(0, FEEDREADER_FORUM_PREFIX); 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) { if (changed) {
if (!preview) { if (!preview) {
IndicateConfigChanged(); IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
} }
if (mNotify) { if (mNotify) {
@ -2137,6 +2373,14 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s
} }
//TODO: error //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) bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup)
@ -2159,7 +2403,7 @@ bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &f
uint32_t token; uint32_t token;
mForums->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); 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; std::cerr << "p3FeedReader::getForumGroup - waitForToken for request failed" << std::endl;
return false; return false;
} }
@ -2202,7 +2446,7 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std
return false; return false;
} }
if (!waitForToken(token)) { if (!waitForToken(mForums, token)) {
std::cerr << "p3FeedReader::updateForumGroup - waitForToken for update failed" << std::endl; std::cerr << "p3FeedReader::updateForumGroup - waitForToken for update failed" << std::endl;
return false; return false;
} }
@ -2211,13 +2455,85 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std
return true; 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; return false;
} }
RsTokenService *service = mForums->getTokenService(); if (groupId.isNull()) {
std::cerr << "p3FeedReader::getPostedGroup - group id is not valid" << std::endl;
return false;
}
std::list<RsGxsGroupId> 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<RsPostedGroup> 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; int count = MAX_REQUEST_AGE * 2;
while (!mStopped) { while (!mStopped) {
@ -2239,3 +2555,168 @@ bool p3FeedReader::waitForToken(uint32_t token)
return false; return false;
} }
bool p3FeedReader::getForumGroups(std::vector<RsGxsForumGroup> &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<RsGxsForumGroup>::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<RsPostedGroup> &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<RsPostedGroup>::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;
}
bool p3FeedReader::shrinkImage(FeedReaderShrinkImageTask::Type type, const std::vector<unsigned char> &image, std::vector<unsigned char> &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<FeedReaderShrinkImageTask*>::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<FeedReaderShrinkImageTask*>::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);
}

View file

@ -33,11 +33,14 @@ class p3FeedReaderThread;
class RsGxsForums; class RsGxsForums;
struct RsGxsForumGroup; struct RsGxsForumGroup;
class RsPosted;
struct RsPostedGroup;
class RsGxsIfaceHelper;
class p3FeedReader : public RsPQIService, public RsFeedReader class p3FeedReader : public RsPQIService, public RsFeedReader
{ {
public: public:
p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums); p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums, RsPosted *posted);
/****************** FeedReader Interface *************/ /****************** FeedReader Interface *************/
virtual void stop(); virtual void stop();
@ -52,24 +55,33 @@ public:
virtual bool getSaveInBackground(); virtual bool getSaveInBackground();
virtual void setSaveInBackground(bool saveInBackground); virtual void setSaveInBackground(bool saveInBackground);
virtual RsFeedAddResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId); virtual RsFeedResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId);
virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name); virtual RsFeedResult setFolder(uint32_t feedId, const std::string &name);
virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId); virtual RsFeedResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId);
virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo); virtual RsFeedResult setFeed(uint32_t feedId, const FeedInfo &feedInfo);
virtual bool removeFeed(uint32_t feedId); virtual RsFeedResult setParent(uint32_t feedId, uint32_t parentId);
virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId); virtual bool removeFeed(uint32_t feedId);
virtual void getFeedList(uint32_t parentId, std::list<FeedInfo> &feedInfos); virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId);
virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo); virtual void getFeedList(uint32_t parentId, std::list<FeedInfo> &feedInfos);
virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo); virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo);
virtual bool removeMsg(uint32_t feedId, const std::string &msgId); virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo);
virtual bool removeMsgs(uint32_t feedId, const std::list<std::string> &msgIds); virtual bool removeMsg(uint32_t feedId, const std::string &msgId);
virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); virtual bool removeMsgs(uint32_t feedId, const std::list<std::string> &msgIds);
virtual bool getFeedMsgList(uint32_t feedId, std::list<FeedMsgInfo> &msgInfos); virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount);
virtual bool getFeedMsgIdList(uint32_t feedId, std::list<std::string> &msgIds); virtual bool getFeedMsgList(uint32_t feedId, std::list<FeedMsgInfo> &msgInfos);
virtual bool processFeed(uint32_t feedId); virtual bool getFeedMsgIdList(uint32_t feedId, std::list<std::string> &msgIds);
virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read); virtual bool processFeed(uint32_t feedId);
virtual bool retransformMsg(uint32_t feedId, const std::string &msgId); virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read);
virtual bool clearMessageCache(uint32_t feedId); 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<RsGxsForumGroup> &groups, bool onlyOwn);
virtual bool getPostedGroups(std::vector<RsPostedGroup> &groups, bool onlyOwn);
virtual FeedReaderShrinkImageTask *getShrinkImageTask();
virtual void setShrinkImageTaskResult(FeedReaderShrinkImageTask *shrinkedImageTask);
virtual RsFeedReaderErrorState processXPath(const std::list<std::string> &xpathsToUse, const std::list<std::string> &xpathsToRemove, std::string &description, std::string &errorString); virtual RsFeedReaderErrorState processXPath(const std::list<std::string> &xpathsToUse, const std::list<std::string> &xpathsToRemove, std::string &description, std::string &errorString);
virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString); virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString);
@ -92,7 +104,10 @@ public:
bool getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup); bool getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup);
bool updateForumGroup(const RsGxsForumGroup &forumGroup, const std::string &groupName, const std::string &groupDescription); 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);
bool shrinkImage(FeedReaderShrinkImageTask::Type type, const std::vector<unsigned char> &image, std::vector<unsigned char> &resultImage);
protected: protected:
/****************** p3Config STUFF *******************/ /****************** p3Config STUFF *******************/
@ -109,6 +124,7 @@ private:
private: private:
time_t mLastClean; time_t mLastClean;
RsGxsForums *mForums; RsGxsForums *mForums;
RsPosted *mPosted;
RsFeedReaderNotify *mNotify; RsFeedReaderNotify *mNotify;
volatile bool mStopped; volatile bool mStopped;
@ -133,6 +149,10 @@ private:
RsMutex mProcessMutex; RsMutex mProcessMutex;
std::list<uint32_t> mProcessFeeds; std::list<uint32_t> mProcessFeeds;
RsMutex mImageMutex;
std::list<FeedReaderShrinkImageTask*> mImages;
std::list<FeedReaderShrinkImageTask*> mResultImages;
RsMutex mPreviewMutex; RsMutex mPreviewMutex;
p3FeedReaderThread *mPreviewDownloadThread; p3FeedReaderThread *mPreviewDownloadThread;
p3FeedReaderThread *mPreviewProcessThread; p3FeedReaderThread *mPreviewProcessThread;

View file

@ -204,8 +204,14 @@ static std::string calculateLink(const std::string &baseLink, const std::string
/* calculate link of base link */ /* calculate link of base link */
std::string resultLink = baseLink; std::string resultLink = baseLink;
int hostStart = 0;
/* link should begin with "http://" or "https://" */ /* 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://"); resultLink.insert(0, "http://");
} }
@ -216,7 +222,7 @@ static std::string calculateLink(const std::string &baseLink, const std::string
if (*link.begin() == '/') { if (*link.begin() == '/') {
/* link begins with "/" */ /* link begins with "/" */
size_t found = resultLink.find('/', 7); size_t found = resultLink.find('/', hostStart);
if (found != std::string::npos) { if (found != std::string::npos) {
resultLink.erase(found); resultLink.erase(found);
} }
@ -245,7 +251,7 @@ static bool getFavicon(CURLWrapper &CURL, const std::string &url, std::string &i
if (code == CURLE_OK) { if (code == CURLE_OK) {
if (CURL.responseCode() == 200) { if (CURL.responseCode() == 200) {
std::string contentType = CURL.contentType(); std::string contentType = CURL.contentType();
if (isContentType(contentType, "image/x-icon") || if (isContentType(contentType, "image/") ||
isContentType(contentType, "application/octet-stream") || isContentType(contentType, "application/octet-stream") ||
isContentType(contentType, "text/plain")) { isContentType(contentType, "text/plain")) {
if (!vicon.empty()) { if (!vicon.empty()) {
@ -296,6 +302,9 @@ RsFeedReaderErrorState p3FeedReaderThread::download(const RsFeedReaderFeed &feed
} }
} }
break; break;
case 403:
result = RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED;
break;
case 404: case 404:
result = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; result = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND;
break; break;
@ -1070,12 +1079,15 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (isRunning()) { if (isRunning()) {
/* process description */ /* process description */
bool processPostedFirstImage = (feed.flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) ? TRUE : FALSE;
//long todo; // encoding //long todo; // encoding
HTMLWrapper html; HTMLWrapper html;
if (html.readHTML(msg->description.c_str(), url.c_str())) { if (html.readHTML(msg->description.c_str(), url.c_str())) {
xmlNodePtr root = html.getRootElement(); xmlNodePtr root = html.getRootElement();
if (root) { if (root) {
std::list<xmlNodePtr> nodesToDelete; std::list<xmlNodePtr> nodesToDelete;
xmlNodePtr postedFirstImageNode = NULL;
/* process all children */ /* process all children */
std::list<xmlNodePtr> nodes; std::list<xmlNodePtr> nodes;
@ -1206,6 +1218,12 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str());
if (html.setAttr(node, "src", imageBase64.c_str())) { if (html.setAttr(node, "src", imageBase64.c_str())) {
removeImage = false; removeImage = false;
if (processPostedFirstImage && postedFirstImageNode == NULL) {
/* set first image */
msg->postedFirstImage = data;
postedFirstImageNode = node;
}
} }
} }
} }
@ -1241,7 +1259,22 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (result == RS_FEED_ERRORSTATE_OK) { if (result == RS_FEED_ERRORSTATE_OK) {
if (isRunning()) { 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(); errorString = html.lastError();
#ifdef FEEDREADER_DEBUG #ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;

View file

@ -46,6 +46,7 @@ void RsFeedReaderFeed::clear()
storageTime = 0; storageTime = 0;
flag = 0; flag = 0;
forumId.clear(); forumId.clear();
postedId.clear();
description.clear(); description.clear();
icon.clear(); icon.clear();
errorState = RS_FEED_ERRORSTATE_OK; errorState = RS_FEED_ERRORSTATE_OK;
@ -85,6 +86,7 @@ uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item)
s += item->xpathsToUse.TlvSize(); s += item->xpathsToUse.TlvSize();
s += item->xpathsToRemove.TlvSize(); s += item->xpathsToRemove.TlvSize();
s += GetTlvStringSize(item->xslt); s += GetTlvStringSize(item->xslt);
s += GetTlvStringSize(item->postedId);
return s; return s;
} }
@ -108,7 +110,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u
offset += 8; offset += 8;
/* add values */ /* 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->feedId);
ok &= setRawUInt32(data, tlvsize, &offset, item->parentId); ok &= setRawUInt32(data, tlvsize, &offset, item->parentId);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->url); 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->storageTime);
ok &= setRawUInt32(data, tlvsize, &offset, item->flag); 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->forumId);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->postedId);
ok &= setRawUInt32(data, tlvsize, &offset, item->errorState); ok &= setRawUInt32(data, tlvsize, &offset, item->errorState);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString);
ok &= setRawUInt32(data, tlvsize, &offset, item->transformationType); 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->storageTime));
ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); ok &= getRawUInt32(data, rssize, &offset, &(item->flag));
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->forumId); 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; uint32_t errorState = 0;
ok &= getRawUInt32(data, rssize, &offset, &errorState); ok &= getRawUInt32(data, rssize, &offset, &errorState);
item->errorState = (RsFeedReaderErrorState) errorState; item->errorState = (RsFeedReaderErrorState) errorState;

View file

@ -34,17 +34,22 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03;
/**************************************************************************/ /**************************************************************************/
#define RS_FEED_FLAG_FOLDER 0x001 #define RS_FEED_FLAG_FOLDER 0x0001
#define RS_FEED_FLAG_INFO_FROM_FEED 0x002 #define RS_FEED_FLAG_INFO_FROM_FEED 0x0002
#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x004 #define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x0004
#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x008 #define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x0008
#define RS_FEED_FLAG_STANDARD_PROXY 0x010 #define RS_FEED_FLAG_STANDARD_PROXY 0x0010
#define RS_FEED_FLAG_AUTHENTICATION 0x020 #define RS_FEED_FLAG_AUTHENTICATION 0x0020
#define RS_FEED_FLAG_DEACTIVATED 0x040 #define RS_FEED_FLAG_DEACTIVATED 0x0040
#define RS_FEED_FLAG_FORUM 0x080 #define RS_FEED_FLAG_FORUM 0x0080
#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x100 #define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x0100
#define RS_FEED_FLAG_EMBED_IMAGES 0x200 #define RS_FEED_FLAG_EMBED_IMAGES 0x0200
#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x400 #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
#define RS_FEED_FLAG_POSTED_SHRINK_IMAGE 0x8000
class RsFeedReaderFeed : public RsItem class RsFeedReaderFeed : public RsItem
{ {
@ -62,6 +67,7 @@ public:
virtual ~RsFeedReaderFeed() {} virtual ~RsFeedReaderFeed() {}
virtual void clear(); virtual void clear();
virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&) {}
uint32_t feedId; uint32_t feedId;
uint32_t parentId; uint32_t parentId;
@ -75,6 +81,7 @@ public:
time_t lastUpdate; time_t lastUpdate;
uint32_t flag; // RS_FEED_FLAG_... uint32_t flag; // RS_FEED_FLAG_...
std::string forumId; std::string forumId;
std::string postedId;
uint32_t storageTime; uint32_t storageTime;
std::string description; std::string description;
std::string icon; std::string icon;
@ -105,6 +112,7 @@ public:
virtual ~RsFeedReaderMsg() {} virtual ~RsFeedReaderMsg() {}
virtual void clear(); virtual void clear();
virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&) {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
std::string msgId; std::string msgId;
@ -116,6 +124,10 @@ public:
std::string descriptionTransformed; std::string descriptionTransformed;
time_t pubDate; time_t pubDate;
uint32_t flag; // RS_FEEDMSG_FLAG_... uint32_t flag; // RS_FEEDMSG_FLAG_...
// Only in memory when receiving messages
std::vector<unsigned char> postedFirstImage;
std::string postedDescriptionWithoutFirstImage;
}; };
class RsFeedReaderSerialiser: public RsSerialType class RsFeedReaderSerialiser: public RsSerialType

View file

@ -21,6 +21,8 @@
#include "CURLWrapper.h" #include "CURLWrapper.h"
#include <string.h> #include <string.h>
#define USERAGENT "Mozilla/5.0 (rv:109.0) Gecko/20100101 Firefox/112.0"
CURLWrapper::CURLWrapper(const std::string &proxy) CURLWrapper::CURLWrapper(const std::string &proxy)
{ {
mCurl = curl_easy_init(); 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_WRITEFUNCTION, writeFunctionString);
curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data); curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data);
curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(mCurl, CURLOPT_USERAGENT, USERAGENT);
return curl_easy_perform(mCurl); return curl_easy_perform(mCurl);
} }
@ -95,6 +98,7 @@ CURLcode CURLWrapper::downloadBinary(const std::string &link, std::vector<unsign
curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, writeFunctionBinary); curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, writeFunctionBinary);
curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data); curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data);
curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(mCurl, CURLOPT_USERAGENT, USERAGENT);
return curl_easy_perform(mCurl); return curl_easy_perform(mCurl);
} }

View file

@ -37,6 +37,7 @@
#include "gui/advsearch/advancedsearchdialog.h" #include "gui/advsearch/advancedsearchdialog.h"
#include "gui/common/RSTreeWidgetItem.h" #include "gui/common/RSTreeWidgetItem.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include "util/qtthreadsutils.h"
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
#include <retroshare/rsturtle.h> #include <retroshare/rsturtle.h>
@ -217,6 +218,15 @@ SearchDialog::SearchDialog(QWidget *parent)
checkText(ui.lineEdit->text()); checkText(ui.lineEdit->text());
// add an event handler to get search results (previously available through notifyQt)
mEventHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event)
{
RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this );
}, mEventHandlerId, RsEventType::FILE_TRANSFER );
} }
SearchDialog::~SearchDialog() SearchDialog::~SearchDialog()
@ -235,6 +245,29 @@ SearchDialog::~SearchDialog()
ui.searchResultWidget->setItemDelegateForColumn(SR_SIZE_COL, nullptr); ui.searchResultWidget->setItemDelegateForColumn(SR_SIZE_COL, nullptr);
ui.searchResultWidget->setItemDelegateForColumn(SR_AGE_COL, nullptr); ui.searchResultWidget->setItemDelegateForColumn(SR_AGE_COL, nullptr);
rsEvents->unregisterEventsHandler(mEventHandlerId);
}
void SearchDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
if(event->mType != RsEventType::FILE_TRANSFER)
return;
auto fe = dynamic_cast<const RsFileTransferEvent*>(event.get());
if(!fe || fe->mFileTransferEventCode!=RsFileTransferEventCode::NEW_DISTANT_SEARCH_RESULTS)
return;
for(uint32_t i=0;i<fe->mResults.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) void SearchDialog::processSettings(bool bLoad)
@ -961,7 +994,7 @@ void SearchDialog::processResultQueue()
while(!searchResultsQueue.empty() && nb_treated_elements++ < 250) while(!searchResultsQueue.empty() && nb_treated_elements++ < 250)
{ {
qulonglong search_id = searchResultsQueue.back().first ; qulonglong search_id = searchResultsQueue.back().first ;
FileDetail& file = searchResultsQueue.back().second ; const FileDetail& file = searchResultsQueue.back().second ;
#ifdef DEBUG #ifdef DEBUG
std::cout << "Updating file detail:" << std::endl ; std::cout << "Updating file detail:" << std::endl ;

View file

@ -22,6 +22,7 @@
#define _SEARCHDIALOG_H #define _SEARCHDIALOG_H
#include "retroshare/rstypes.h" #include "retroshare/rstypes.h"
#include "retroshare/rsevents.h"
#include "ui_SearchDialog.h" #include "ui_SearchDialog.h"
#include "retroshare-gui/mainpage.h" #include "retroshare-gui/mainpage.h"
@ -125,6 +126,7 @@ private:
void setIconAndType(QTreeWidgetItem *item, const QString& filename); void setIconAndType(QTreeWidgetItem *item, const QString& filename);
void downloadDirectory(const QTreeWidgetItem *item, const QString &base); void downloadDirectory(const QTreeWidgetItem *item, const QString &base);
void getSourceFriendsForHash(const RsFileHash &hash,std::list<RsPeerId> &srcIds); void getSourceFriendsForHash(const RsFileHash &hash,std::list<RsPeerId> &srcIds);
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
/** the advanced search dialog instance */ /** the advanced search dialog instance */
AdvancedSearchDialog * advSearchDialog; AdvancedSearchDialog * advSearchDialog;
@ -176,6 +178,8 @@ private:
bool _queueIsAlreadyTakenCareOf ; bool _queueIsAlreadyTakenCareOf ;
std::vector<std::pair<qulonglong,FileDetail> > searchResultsQueue ; std::vector<std::pair<qulonglong,FileDetail> > searchResultsQueue ;
RsEventsHandlerId_t mEventHandlerId ;
}; };
#endif #endif

View file

@ -301,8 +301,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>634</width> <width>456</width>
<height>538</height> <height>731</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout"> <layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
@ -338,21 +338,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>518</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QFrame" name="info_Frame_Invite"> <widget class="QFrame" name="info_Frame_Invite">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette"> <property name="palette">
<palette> <palette>
<active> <active>
@ -490,6 +483,9 @@
<property name="text"> <property name="text">
<string notr="true">Invite messages stay into your Outbox until an acknowledgement of receipt has been received.</string> <string notr="true">Invite messages stay into your Outbox until an acknowledgement of receipt has been received.</string>
</property> </property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -895,9 +891,12 @@ border-image: url(:/images/closepressed.png)
</item> </item>
<item row="11" column="1"> <item row="11" column="1">
<widget class="QCheckBox" name="autoBanIdentities_CB"> <widget class="QCheckBox" name="autoBanIdentities_CB">
<property name="text"> <property name="toolTip">
<string>Auto-Ban all identities signed by the same node</string> <string>Auto-Ban all identities signed by the same node</string>
</property> </property>
<property name="text">
<string>Auto-Ban profile</string>
</property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="4" column="1">

View file

@ -50,6 +50,8 @@
#define IMG_ATTACH 0 #define IMG_ATTACH 0
#define IMG_PICTURE 1 #define IMG_PICTURE 1
const int MAXMESSAGESIZE = 199000;
PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGroupId& grpId, const RsGxsId& default_author, QWidget *parent): 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), QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
mPosted(posted), mGrpId(grpId), mPosted(posted), mGrpId(grpId),
@ -226,7 +228,7 @@ void PostedCreatePostDialog::addPicture()
} }
QImage opt; 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->imageLabel->setPixmap(QPixmap::fromImage(opt));
ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE);
ui->removeButton->show(); ui->removeButton->show();
@ -274,7 +276,7 @@ void PostedCreatePostDialog::pastePicture()
image = (qvariant_cast<QImage>(mimeData->imageData())); image = (qvariant_cast<QImage>(mimeData->imageData()));
QImage opt; 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->imageLabel->setPixmap(QPixmap::fromImage(opt));
ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE);
ui->removeButton->show(); 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() int PostedCreatePostDialog::viewMode()
{ {
if (ui->viewPostButton->isChecked()) { if (ui->viewPostButton->isChecked()) {
@ -330,3 +338,18 @@ void PostedCreatePostDialog::reject()
QDialog::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);
}

View file

@ -41,10 +41,15 @@ public:
explicit PostedCreatePostDialog(RsPosted* posted, const RsGxsGroupId& grpId, const RsGxsId& default_author=RsGxsId(),QWidget *parent = 0); explicit PostedCreatePostDialog(RsPosted* posted, const RsGxsGroupId& grpId, const RsGxsId& default_author=RsGxsId(),QWidget *parent = 0);
~PostedCreatePostDialog(); ~PostedCreatePostDialog();
void setTitle(const QString& title);
void setNotes(const QString& notes);
void setLink(const QString& link);
static bool optimizeImage(const QImage &image, QByteArray &imagebytes, QImage &imageOpt);
private: private:
QString imagefilename; QString imagefilename;
QByteArray imagebytes; QByteArray imagebytes;
const int MAXMESSAGESIZE = 199000;
private slots: private slots:
void createPost(); void createPost();

View file

@ -454,22 +454,6 @@ p, li { white-space: pre-wrap; }
</item> </item>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="LineEditClear" name="filter_LE"> <widget class="LineEditClear" name="filter_LE">
<property name="placeholderText"> <property name="placeholderText">

View file

@ -42,15 +42,26 @@ PulseAddDialog::PulseAddDialog(QWidget *parent)
connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) );
connect(ui.textEdit_Pulse, SIGNAL( textChanged( void ) ), this, SLOT( pulseTextChanged( void ) ) ); connect(ui.textEdit_Pulse, SIGNAL( textChanged( void ) ), this, SLOT( pulseTextChanged( void ) ) );
connect(ui.pushButton_picture, SIGNAL(clicked()), this, SLOT( toggle())); 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() // this connection is from browse push button to the slot function onBrowseButtonClicked()
connect(ui.pushButton_Browse, SIGNAL(clicked()), this, SLOT( onBrowseButtonClicked())); connect(ui.pushButton_Browse, SIGNAL(clicked()), this, SLOT( onBrowseButtonClicked()));
ui.pushButton_picture->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/photo.png"))); 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.frame_picture->hide();
ui.pushButton_picture->hide();
// initially hiding the browse button as the attach image button is not pressed // 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); setAcceptDrops(true);
} }
@ -160,11 +171,10 @@ void PulseAddDialog::cleanup()
ui.label_image4->clear(); ui.label_image4->clear();
ui.label_image4->setText(tr("Drag and Drop Image")); ui.label_image4->setText(tr("Drag and Drop Image"));
ui.lineEdit_FilePath->clear();
// Hide Drag & Drop Frame and the browse frame // Hide Drag & Drop Frame and the browse frame
ui.frame_picture->hide(); ui.frame_picture->hide();
ui.frame_PictureBrowse->hide(); //ui.frame_PictureBrowse->hide();
ui.pushButton_picture->hide();
ui.pushButton_picture->setChecked(false); ui.pushButton_picture->setChecked(false);
} }
@ -489,24 +499,29 @@ void PulseAddDialog::addImage(const QString &path)
std::cerr << "PulseAddDialog::addImage() Installing in Image1"; std::cerr << "PulseAddDialog::addImage() Installing in Image1";
std::cerr << std::endl; std::cerr << std::endl;
ui.label_image1->setPixmap(icon); ui.label_image1->setPixmap(icon);
ui.label_image1->show();
ui.frame_picture->show();
mImage1.copy((uint8_t *) ba.data(), ba.size()); mImage1.copy((uint8_t *) ba.data(), ba.size());
std::cerr << "PulseAddDialog::addImage() Installing in Image1 Size: " << mImage1.mSize; std::cerr << "PulseAddDialog::addImage() Installing in Image1 Size: " << mImage1.mSize;
std::cerr << std::endl; std::cerr << std::endl;
} }
else if (mImage2.empty()) { else if (mImage2.empty()) {
ui.label_image2->setPixmap(icon); ui.label_image2->setPixmap(icon);
ui.label_image2->show();
mImage2.copy((uint8_t *) ba.data(), ba.size()); mImage2.copy((uint8_t *) ba.data(), ba.size());
std::cerr << "PulseAddDialog::addImage() Installing in Image2 Size: " << mImage2.mSize; std::cerr << "PulseAddDialog::addImage() Installing in Image2 Size: " << mImage2.mSize;
std::cerr << std::endl; std::cerr << std::endl;
} }
else if (mImage3.empty()) { else if (mImage3.empty()) {
ui.label_image3->setPixmap(icon); ui.label_image3->setPixmap(icon);
ui.label_image3->show();
mImage3.copy((uint8_t *) ba.data(), ba.size()); mImage3.copy((uint8_t *) ba.data(), ba.size());
std::cerr << "PulseAddDialog::addImage() Installing in Image3 Size: " << mImage3.mSize; std::cerr << "PulseAddDialog::addImage() Installing in Image3 Size: " << mImage3.mSize;
std::cerr << std::endl; std::cerr << std::endl;
} }
else if (mImage4.empty()) { else if (mImage4.empty()) {
ui.label_image4->setPixmap(icon); ui.label_image4->setPixmap(icon);
ui.label_image4->show();
mImage4.copy((uint8_t *) ba.data(), ba.size()); mImage4.copy((uint8_t *) ba.data(), ba.size());
std::cerr << "PulseAddDialog::addImage() Installing in Image4 Size: " << mImage4.mSize; std::cerr << "PulseAddDialog::addImage() Installing in Image4 Size: " << mImage4.mSize;
std::cerr << std::endl; std::cerr << std::endl;
@ -523,7 +538,6 @@ void PulseAddDialog::toggle()
{ {
// Show the input methods (drag and drop field and the browse button) // Show the input methods (drag and drop field and the browse button)
ui.frame_picture->show(); ui.frame_picture->show();
ui.frame_PictureBrowse->show();
ui.pushButton_picture->setToolTip(tr("Hide Pictures")); 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) // Hide the input methods (drag and drop field and the browse button)
ui.frame_picture->hide(); ui.frame_picture->hide();
ui.frame_PictureBrowse->hide();
ui.pushButton_picture->setToolTip(tr("Add Pictures")); ui.pushButton_picture->setToolTip(tr("Add Pictures"));
} }
@ -543,8 +556,27 @@ void PulseAddDialog::onBrowseButtonClicked()
QString filePath; QString filePath;
misc::getOpenFileName(this, RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", filePath); misc::getOpenFileName(this, RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", filePath);
if (!filePath.isEmpty()) { if (!filePath.isEmpty()) {
ui.lineEdit_FilePath->setText(filePath); //ui.lineEdit_FilePath->setText(filePath);
addImage(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();
}

View file

@ -53,7 +53,8 @@ private slots:
void clearDialog(); void clearDialog();
void pulseTextChanged(); void pulseTextChanged();
void toggle(); void toggle();
void onBrowseButtonClicked(); void onBrowseButtonClicked();
void removePictures();
private: private:
// OLD VERSIONs, private now. // OLD VERSIONs, private now.

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>720</width> <width>735</width>
<height>513</height> <height>513</height>
</rect> </rect>
</property> </property>
@ -52,6 +52,7 @@
<property name="font"> <property name="font">
<font> <font>
<pointsize>12</pointsize> <pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
@ -249,6 +250,12 @@
</item> </item>
<item> <item>
<widget class="QFrame" name="frame_picture"> <widget class="QFrame" name="frame_picture">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
@ -278,6 +285,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QLabel" name="label_image4">
<property name="minimumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>Drag and Drop Image</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_image3"> <widget class="QLabel" name="label_image3">
<property name="minimumSize"> <property name="minimumSize">
@ -310,63 +333,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="0" column="2" rowspan="2">
<widget class="QLabel" name="label_image4"> <widget class="QToolButton" name="pushButton_remove">
<property name="minimumSize"> <property name="toolTip">
<size> <string>Remove all images</string>
<width>40</width>
<height>40</height>
</size>
</property> </property>
<property name="text"> <property name="text">
<string>Drag and Drop Image</string> <string/>
</property> </property>
<property name="alignment"> <property name="iconSize">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_PictureBrowse">
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit_FilePath">
<property name="minimumSize">
<size> <size>
<width>541</width> <width>24</width>
<height>25</height> <height>24</height>
</size> </size>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="pushButton_Browse">
<property name="minimumSize">
<size>
<width>101</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -413,7 +395,6 @@
</layout> </layout>
<zorder>frame_URL</zorder> <zorder>frame_URL</zorder>
<zorder>frame_picture</zorder> <zorder>frame_picture</zorder>
<zorder>frame_PictureBrowse</zorder>
<zorder>textEdit_Pulse</zorder> <zorder>textEdit_Pulse</zorder>
</widget> </widget>
</item> </item>
@ -423,7 +404,7 @@
<number>6</number> <number>6</number>
</property> </property>
<item> <item>
<widget class="QPushButton" name="pushButton_picture"> <widget class="QToolButton" name="pushButton_picture">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
@ -438,6 +419,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QToolButton" name="pushButton_Browse">
<property name="toolTip">
<string>Add Picture</string>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item> <item>
<spacer name="buttonHSpacer"> <spacer name="buttonHSpacer">
<property name="orientation"> <property name="orientation">
@ -456,6 +453,7 @@
<property name="font"> <property name="font">
<font> <font>
<pointsize>12</pointsize> <pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>

View file

@ -402,7 +402,7 @@
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="textInteractionFlags"> <property name="textInteractionFlags">
@ -534,7 +534,7 @@ p, li { white-space: pre-wrap; }
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_6"> <layout class="QVBoxLayout" name="verticalLayout_6">
<item> <item>
<widget class="QLabel" name="postName_LB"> <widget class="ElidedLabel" name="postName_LB">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>

View file

@ -68,19 +68,19 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->postButton); mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->postButton);
mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->innerFrame); mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->innerFrame);
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName); 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->addClear(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName);
mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->postButton); mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->postButton);
mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->innerFrame); mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->innerFrame);
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName); 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->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName);
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->postButton); mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->postButton);
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->innerFrame); mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->innerFrame);
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName); 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); mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName);

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1215</width> <width>800</width>
<height>825</height> <height>650</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View file

@ -482,6 +482,8 @@ void NotifyQt::notifyTurtleSearchResult(uint32_t /*search_id*/,const std::list<T
std::cerr << "(EE) missing code to handle GXS turtle search result." << std::endl; std::cerr << "(EE) missing code to handle GXS turtle search result." << std::endl;
} }
#ifdef TO_REMOVE
// Mai 2023: distant turtle search now uses RsEvents.
void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,const std::list<TurtleFileInfo>& files) void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,const std::list<TurtleFileInfo>& files)
{ {
{ {
@ -507,6 +509,7 @@ void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,c
emit gotTurtleSearchResult(search_id,det) ; emit gotTurtleSearchResult(search_id,det) ;
} }
} }
#endif
void NotifyQt::notifyHistoryChanged(uint32_t msgId, int type) void NotifyQt::notifyHistoryChanged(uint32_t msgId, int type)
{ {

View file

@ -67,7 +67,9 @@ class NotifyQt: public QObject, public NotifyClient
virtual void notifyChatStatus(const ChatId &chat_id,const std::string& status_string); virtual void notifyChatStatus(const ChatId &chat_id,const std::string& status_string);
virtual void notifyChatCleared(const ChatId &chat_id); virtual void notifyChatCleared(const ChatId &chat_id);
virtual void notifyCustomState(const std::string& peer_id, const std::string& status_string); 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<TurtleFileInfo>& found_files); virtual void notifyTurtleSearchResult(const RsPeerId &pid, uint32_t search_id, const std::list<TurtleFileInfo>& found_files);
#endif
virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list<TurtleGxsInfo>& found_groups); virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list<TurtleGxsInfo>& found_groups);
virtual void notifyPeerHasNewAvatar(std::string peer_id) ; virtual void notifyPeerHasNewAvatar(std::string peer_id) ;
virtual void notifyOwnAvatarChanged() ; virtual void notifyOwnAvatarChanged() ;

View file

@ -540,7 +540,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
qRegisterMetaType<RsPeerId>("RsPeerId") ; qRegisterMetaType<RsPeerId>("RsPeerId") ;
std::cerr << "connecting signals and slots" << std::endl ; 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(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),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))) ; QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ;