mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
commit
44f297156e
@ -459,8 +459,12 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
|
|||||||
msgMeta.signSet.TlvClear();
|
msgMeta.signSet.TlvClear();
|
||||||
|
|
||||||
RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId;
|
RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId;
|
||||||
|
|
||||||
|
if(msgMeta.mOrigMsgId == msgMeta.mMsgId) // message is not versionned, then the signature was made with mOrigMsgId==NULL
|
||||||
msgMeta.mOrigMsgId.clear();
|
msgMeta.mOrigMsgId.clear();
|
||||||
|
|
||||||
msgMeta.mMsgId.clear();
|
msgMeta.mMsgId.clear();
|
||||||
|
|
||||||
int signOk = 0 ;
|
int signOk = 0 ;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -2137,7 +2137,9 @@ void RsGenExchange::publishMsgs()
|
|||||||
if(createOk && validSize)
|
if(createOk && validSize)
|
||||||
{
|
{
|
||||||
// empty orig msg id means this is the original
|
// empty orig msg id means this is the original
|
||||||
// msg
|
// msg.
|
||||||
|
// (csoler) Why are we doing this???
|
||||||
|
|
||||||
if(msg->metaData->mOrigMsgId.isNull())
|
if(msg->metaData->mOrigMsgId.isNull())
|
||||||
{
|
{
|
||||||
msg->metaData->mOrigMsgId = msg->metaData->mMsgId;
|
msg->metaData->mOrigMsgId = msg->metaData->mMsgId;
|
||||||
|
@ -45,12 +45,13 @@
|
|||||||
#define CREATEGXSFORUMMSG_FORUMINFO 1
|
#define CREATEGXSFORUMMSG_FORUMINFO 1
|
||||||
#define CREATEGXSFORUMMSG_PARENTMSG 2
|
#define CREATEGXSFORUMMSG_PARENTMSG 2
|
||||||
#define CREATEGXSFORUMMSG_CIRCLENFO 3
|
#define CREATEGXSFORUMMSG_CIRCLENFO 3
|
||||||
|
#define CREATEGXSFORUMMSG_ORIGMSG 4
|
||||||
|
|
||||||
//#define ENABLE_GENERATE
|
//#define ENABLE_GENERATE
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId)
|
CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId,const RsGxsMessageId& mOId,const RsGxsId& posterId)
|
||||||
: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mForumId(fId), mParentId(pId)
|
: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
@ -75,7 +76,14 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
|
|||||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumSubject);
|
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumSubject);
|
||||||
mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName);
|
mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName);
|
||||||
|
|
||||||
QString text = pId.isNull() ? tr("Start New Thread") : tr("Post Forum Message");
|
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.buttonBox->button(QDialogButtonBox::Ok));
|
||||||
|
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.innerFrame);
|
||||||
|
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName);
|
||||||
|
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumSubject);
|
||||||
|
mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName);
|
||||||
|
|
||||||
|
|
||||||
|
QString text = mOId.isNull()?(pId.isNull() ? tr("Start New Thread") : tr("Post Forum Message")):tr("Edit Message");
|
||||||
setWindowTitle(text);
|
setWindowTitle(text);
|
||||||
|
|
||||||
ui.headerFrame->setHeaderImage(QPixmap(":/images/konversation64.png"));
|
ui.headerFrame->setHeaderImage(QPixmap(":/images/konversation64.png"));
|
||||||
@ -129,13 +137,24 @@ void CreateGxsForumMsg::newMsg()
|
|||||||
|
|
||||||
//std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
|
//std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
|
||||||
|
|
||||||
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
if(!mPosterId.isNull())
|
||||||
|
{
|
||||||
|
std::set<RsGxsId> id_set ;
|
||||||
|
id_set.insert(mPosterId) ;
|
||||||
|
|
||||||
|
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE, mPosterId);
|
||||||
|
ui.idChooser->setIdConstraintSet(id_set);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, mPosterId);
|
||||||
|
|
||||||
if (mForumId.isNull()) {
|
if (mForumId.isNull()) {
|
||||||
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
|
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
|
||||||
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false);
|
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false);
|
||||||
|
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||||
mStateHelper->clear(CREATEGXSFORUMMSG_FORUMINFO);
|
mStateHelper->clear(CREATEGXSFORUMMSG_FORUMINFO);
|
||||||
mStateHelper->clear(CREATEGXSFORUMMSG_PARENTMSG);
|
mStateHelper->clear(CREATEGXSFORUMMSG_PARENTMSG);
|
||||||
|
mStateHelper->clear(CREATEGXSFORUMMSG_ORIGMSG);
|
||||||
ui.forumName->setText(tr("No Forum"));
|
ui.forumName->setText(tr("No Forum"));
|
||||||
return;
|
return;
|
||||||
}//if ( mForumId.isNull())
|
}//if ( mForumId.isNull())
|
||||||
@ -174,11 +193,53 @@ void CreateGxsForumMsg::newMsg()
|
|||||||
uint32_t token;
|
uint32_t token;
|
||||||
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG);
|
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG);
|
||||||
}//if (mParentId.isNull())
|
}//if (mParentId.isNull())
|
||||||
|
|
||||||
|
if (mOrigMsgId.isNull()) {
|
||||||
|
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||||
|
mOrigMsgLoaded = true;
|
||||||
|
} else {
|
||||||
|
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||||
|
|
||||||
|
RsTokReqOptions opts;
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
|
||||||
|
GxsMsgReq msgIds;
|
||||||
|
std::vector<RsGxsMessageId> &vect = msgIds[mForumId];
|
||||||
|
vect.push_back(mOrigMsgId);
|
||||||
|
|
||||||
|
//std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")";
|
||||||
|
//std::cerr << std::endl;
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_ORIGMSG);
|
||||||
|
}//if (mParentId.isNull())
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateGxsForumMsg::loadFormInformation()
|
void CreateGxsForumMsg::loadFormInformation()
|
||||||
{
|
{
|
||||||
if (!mParentId.isNull()) {
|
if (!mOrigMsgId.isNull())
|
||||||
|
{
|
||||||
|
if (mOrigMsgLoaded) {
|
||||||
|
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||||
|
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||||
|
} else {
|
||||||
|
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet";
|
||||||
|
//std::cerr << std::endl;
|
||||||
|
|
||||||
|
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||||
|
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!mParentId.isNull())
|
||||||
|
{
|
||||||
if (mParentMsgLoaded) {
|
if (mParentMsgLoaded) {
|
||||||
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
|
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
|
||||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
|
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
|
||||||
@ -190,7 +251,9 @@ void CreateGxsForumMsg::loadFormInformation()
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
|
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
|
||||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
|
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
|
||||||
}
|
}
|
||||||
@ -212,14 +275,24 @@ void CreateGxsForumMsg::loadFormInformation()
|
|||||||
|
|
||||||
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
|
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
|
||||||
|
|
||||||
|
uint32_t fl = IDCHOOSER_ID_REQUIRED ;
|
||||||
|
|
||||||
if( (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) || (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN))
|
if( (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) || (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN))
|
||||||
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ;
|
fl |= IDCHOOSER_NON_ANONYMOUS ;
|
||||||
else
|
|
||||||
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED) ;
|
if(!mPosterId.isNull())
|
||||||
|
fl |= IDCHOOSER_NO_CREATE;
|
||||||
|
|
||||||
|
ui.idChooser->setFlags(fl) ;
|
||||||
|
|
||||||
QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str());
|
QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str());
|
||||||
QString subj;
|
QString subj;
|
||||||
if (!mParentId.isNull())
|
|
||||||
|
if(!mOrigMsgId.isNull())
|
||||||
|
{
|
||||||
|
subj = QString::fromUtf8(mOrigMsg.mMeta.mMsgName.c_str());
|
||||||
|
}
|
||||||
|
else if (!mParentId.isNull())
|
||||||
{
|
{
|
||||||
QString title = QString::fromUtf8(mParentMsg.mMeta.mMsgName.c_str());
|
QString title = QString::fromUtf8(mParentMsg.mMeta.mMsgName.c_str());
|
||||||
name += " " + tr("In Reply to") + ": ";
|
name += " " + tr("In Reply to") + ": ";
|
||||||
@ -228,17 +301,14 @@ void CreateGxsForumMsg::loadFormInformation()
|
|||||||
QString text = title;
|
QString text = title;
|
||||||
|
|
||||||
if (text.startsWith("Re:", Qt::CaseInsensitive))
|
if (text.startsWith("Re:", Qt::CaseInsensitive))
|
||||||
{
|
|
||||||
subj = title;
|
subj = title;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
subj = "Re: " + title;
|
subj = "Re: " + title;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ui.forumName->setText(misc::removeNewLine(name));
|
ui.forumName->setText(misc::removeNewLine(name));
|
||||||
ui.forumSubject->setText(misc::removeNewLine(subj));
|
ui.forumSubject->setText(misc::removeNewLine(subj));
|
||||||
|
ui.forumSubject->setReadOnly(!mOrigMsgId.isNull());
|
||||||
|
|
||||||
if (ui.forumSubject->text().isEmpty())
|
if (ui.forumSubject->text().isEmpty())
|
||||||
{
|
{
|
||||||
@ -286,6 +356,7 @@ void CreateGxsForumMsg::createMsg()
|
|||||||
RsGxsForumMsg msg;
|
RsGxsForumMsg msg;
|
||||||
msg.mMeta.mGroupId = mForumId;
|
msg.mMeta.mGroupId = mForumId;
|
||||||
msg.mMeta.mParentId = mParentId;
|
msg.mMeta.mParentId = mParentId;
|
||||||
|
msg.mMeta.mOrigMsgId = mOrigMsgId;
|
||||||
msg.mMeta.mMsgId.clear() ;
|
msg.mMeta.mMsgId.clear() ;
|
||||||
if (mParentMsgLoaded) {
|
if (mParentMsgLoaded) {
|
||||||
msg.mMeta.mThreadId = mParentMsg.mMeta.mThreadId;
|
msg.mMeta.mThreadId = mParentMsg.mMeta.mThreadId;
|
||||||
@ -377,9 +448,9 @@ void CreateGxsForumMsg::reject()
|
|||||||
{
|
{
|
||||||
if (ui.forumMessage->document()->isModified()) {
|
if (ui.forumMessage->document()->isModified()) {
|
||||||
QMessageBox::StandardButton ret;
|
QMessageBox::StandardButton ret;
|
||||||
ret = QMessageBox::warning(this, tr("Forum Message"),
|
ret = QMessageBox::warning(this, tr("Cancel Forum Message"),
|
||||||
tr("Forum Message has not been Sent.\n"
|
tr("Forum Message has not been sent yet!\n"
|
||||||
"Do you want to reject this message?"),
|
"Do you want to discard this message?"),
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case QMessageBox::Yes:
|
case QMessageBox::Yes:
|
||||||
@ -521,6 +592,35 @@ void CreateGxsForumMsg::loadForumCircleInfo(const uint32_t& token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateGxsForumMsg::loadOrigMsg(const uint32_t &token)
|
||||||
|
{
|
||||||
|
//std::cerr << "CreateGxsForumMsg::loadParentMsg()";
|
||||||
|
//std::cerr << std::endl;
|
||||||
|
|
||||||
|
// Only grab one.... ignore more (shouldn't be any).
|
||||||
|
std::vector<RsGxsForumMsg> msgs;
|
||||||
|
if (rsGxsForums->getMsgData(token, msgs))
|
||||||
|
{
|
||||||
|
if (msgs.size() != 1)
|
||||||
|
{
|
||||||
|
/* error */
|
||||||
|
std::cerr << "CreateGxsForumMsg::loadOrigMsg() ERROR wrong number of msgs";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||||
|
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOrigMsg = msgs[0];
|
||||||
|
mOrigMsgLoaded = true;
|
||||||
|
|
||||||
|
loadFormInformation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
|
void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
|
||||||
{
|
{
|
||||||
//std::cerr << "CreateGxsForumMsg::loadParentMsg()";
|
//std::cerr << "CreateGxsForumMsg::loadParentMsg()";
|
||||||
@ -562,6 +662,9 @@ void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest
|
|||||||
case CREATEGXSFORUMMSG_FORUMINFO:
|
case CREATEGXSFORUMMSG_FORUMINFO:
|
||||||
loadForumInfo(req.mToken);
|
loadForumInfo(req.mToken);
|
||||||
break;
|
break;
|
||||||
|
case CREATEGXSFORUMMSG_ORIGMSG:
|
||||||
|
loadOrigMsg(req.mToken);
|
||||||
|
break;
|
||||||
case CREATEGXSFORUMMSG_PARENTMSG:
|
case CREATEGXSFORUMMSG_PARENTMSG:
|
||||||
loadParentMsg(req.mToken);
|
loadParentMsg(req.mToken);
|
||||||
break;
|
break;
|
||||||
|
@ -36,7 +36,7 @@ class CreateGxsForumMsg : public QDialog, public TokenResponse
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId);
|
CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId &moId, const RsGxsId &posterId = RsGxsId());
|
||||||
~CreateGxsForumMsg();
|
~CreateGxsForumMsg();
|
||||||
|
|
||||||
void newMsg(); /* cleanup */
|
void newMsg(); /* cleanup */
|
||||||
@ -61,16 +61,22 @@ private:
|
|||||||
|
|
||||||
void loadForumInfo(const uint32_t &token);
|
void loadForumInfo(const uint32_t &token);
|
||||||
void loadParentMsg(const uint32_t &token);
|
void loadParentMsg(const uint32_t &token);
|
||||||
|
void loadOrigMsg(const uint32_t &token);
|
||||||
void loadForumCircleInfo(const uint32_t &token);
|
void loadForumCircleInfo(const uint32_t &token);
|
||||||
|
|
||||||
RsGxsGroupId mForumId;
|
RsGxsGroupId mForumId;
|
||||||
RsGxsCircleId mCircleId ;
|
RsGxsCircleId mCircleId ;
|
||||||
RsGxsMessageId mParentId;
|
RsGxsMessageId mParentId;
|
||||||
|
RsGxsMessageId mOrigMsgId;
|
||||||
|
RsGxsId mPosterId;
|
||||||
|
|
||||||
bool mParentMsgLoaded;
|
bool mParentMsgLoaded;
|
||||||
|
bool mOrigMsgLoaded;
|
||||||
bool mForumMetaLoaded;
|
bool mForumMetaLoaded;
|
||||||
bool mForumCircleLoaded ;
|
bool mForumCircleLoaded ;
|
||||||
|
|
||||||
RsGxsForumMsg mParentMsg;
|
RsGxsForumMsg mParentMsg;
|
||||||
|
RsGxsForumMsg mOrigMsg;
|
||||||
RsGroupMetaData mForumMeta;
|
RsGroupMetaData mForumMeta;
|
||||||
RsGxsCircleGroup mForumCircleData ;
|
RsGxsCircleGroup mForumCircleData ;
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
mTokenTypeNegativeAuthor = nextTokenType();
|
mTokenTypeNegativeAuthor = nextTokenType();
|
||||||
mTokenTypeNeutralAuthor = nextTokenType();
|
mTokenTypeNeutralAuthor = nextTokenType();
|
||||||
mTokenTypePositiveAuthor = nextTokenType();
|
mTokenTypePositiveAuthor = nextTokenType();
|
||||||
|
mTokenTypeEditForumMessage = nextTokenType();
|
||||||
|
|
||||||
setUpdateWhenInvisible(true);
|
setUpdateWhenInvisible(true);
|
||||||
|
|
||||||
@ -199,6 +200,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
|
|
||||||
ui->threadTreeWidget->setItemDelegateForColumn(COLUMN_THREAD_DISTRIBUTION,new DistributionItemDelegate()) ;
|
ui->threadTreeWidget->setItemDelegateForColumn(COLUMN_THREAD_DISTRIBUTION,new DistributionItemDelegate()) ;
|
||||||
|
|
||||||
|
connect(ui->versions_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(changedVersion()));
|
||||||
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
||||||
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
||||||
|
|
||||||
@ -483,11 +485,14 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
|
|
||||||
QMenu contextMnu(this);
|
QMenu contextMnu(this);
|
||||||
|
|
||||||
|
QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Edit"), &contextMnu);
|
||||||
|
connect(editAct, SIGNAL(triggered()), this, SLOT(editforummessage()));
|
||||||
|
|
||||||
QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu);
|
QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu);
|
||||||
connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage()));
|
connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage()));
|
||||||
|
|
||||||
QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply to author with private message"), &contextMnu);
|
QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply to author with private message"), &contextMnu);
|
||||||
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage()));
|
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(reply_with_private_message()));
|
||||||
|
|
||||||
QAction *flagaspositiveAct = new QAction(QIcon(IMAGE_POSITIVE_OPINION), tr("Give positive opinion"), &contextMnu);
|
QAction *flagaspositiveAct = new QAction(QIcon(IMAGE_POSITIVE_OPINION), tr("Give positive opinion"), &contextMnu);
|
||||||
flagaspositiveAct->setToolTip(tr("This will block/hide messages from this person, and notify friend nodes.")) ;
|
flagaspositiveAct->setToolTip(tr("This will block/hide messages from this person, and notify friend nodes.")) ;
|
||||||
@ -572,6 +577,18 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
replyauthorAct->setDisabled (true);
|
replyauthorAct->setDisabled (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QTreeWidgetItem*> selectedItems = ui->threadTreeWidget->selectedItems();
|
||||||
|
|
||||||
|
if(selectedItems.size() == 1)
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *item = *selectedItems.begin();
|
||||||
|
GxsIdRSTreeWidgetItem *gxsIdItem = dynamic_cast<GxsIdRSTreeWidgetItem*>(item);
|
||||||
|
|
||||||
|
RsGxsId author_id;
|
||||||
|
if(gxsIdItem && gxsIdItem->getId(author_id) && rsIdentity->isOwnId(author_id))
|
||||||
|
contextMnu.addAction(editAct);
|
||||||
|
}
|
||||||
|
|
||||||
contextMnu.addAction(replyAct);
|
contextMnu.addAction(replyAct);
|
||||||
contextMnu.addAction(newthreadAct);
|
contextMnu.addAction(newthreadAct);
|
||||||
QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()));
|
QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()));
|
||||||
@ -585,8 +602,6 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
contextMnu.addAction(expandAll);
|
contextMnu.addAction(expandAll);
|
||||||
contextMnu.addAction(collapseAll);
|
contextMnu.addAction(collapseAll);
|
||||||
|
|
||||||
QList<QTreeWidgetItem*> selectedItems = ui->threadTreeWidget->selectedItems();
|
|
||||||
|
|
||||||
if(selectedItems.size() == 1)
|
if(selectedItems.size() == 1)
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *item = *selectedItems.begin();
|
QTreeWidgetItem *item = *selectedItems.begin();
|
||||||
@ -680,6 +695,17 @@ void GxsForumThreadWidget::togglethreadview_internal()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::changedVersion()
|
||||||
|
{
|
||||||
|
mThreadId = RsGxsMessageId(ui->versions_CB->itemData(ui->versions_CB->currentIndex()).toString().toStdString()) ;
|
||||||
|
|
||||||
|
if (mFillThread) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ui->postText->resetImagesStatus(Settings->getForumLoadEmbeddedImages()) ;
|
||||||
|
insertMessage();
|
||||||
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::changedThread()
|
void GxsForumThreadWidget::changedThread()
|
||||||
{
|
{
|
||||||
/* just grab the ids of the current item */
|
/* just grab the ids of the current item */
|
||||||
@ -687,8 +713,10 @@ void GxsForumThreadWidget::changedThread()
|
|||||||
|
|
||||||
if (!item || !item->isSelected()) {
|
if (!item || !item->isSelected()) {
|
||||||
mThreadId.clear();
|
mThreadId.clear();
|
||||||
|
mOrigThreadId.clear();
|
||||||
} else {
|
} else {
|
||||||
mThreadId = RsGxsMessageId(item->data(COLUMN_THREAD_MSGID, Qt::DisplayRole).toString().toStdString());
|
|
||||||
|
mThreadId = mOrigThreadId = RsGxsMessageId(item->data(COLUMN_THREAD_MSGID, Qt::DisplayRole).toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFillThread) {
|
if (mFillThread) {
|
||||||
@ -1014,10 +1042,12 @@ void GxsForumThreadWidget::fillThreadFinished()
|
|||||||
mLastViewType = thread->mViewType;
|
mLastViewType = thread->mViewType;
|
||||||
mLastForumID = groupId();
|
mLastForumID = groupId();
|
||||||
ui->threadTreeWidget->insertTopLevelItems(0, thread->mItems);
|
ui->threadTreeWidget->insertTopLevelItems(0, thread->mItems);
|
||||||
|
mPostVersions = thread->mPostVersions;
|
||||||
|
|
||||||
// clear list
|
// clear list
|
||||||
thread->mItems.clear();
|
thread->mItems.clear();
|
||||||
} else {
|
} else {
|
||||||
|
mPostVersions = thread->mPostVersions;
|
||||||
fillThreads(thread->mItems, thread->mExpandNewMessages, thread->mItemToExpand);
|
fillThreads(thread->mItems, thread->mExpandNewMessages, thread->mItemToExpand);
|
||||||
|
|
||||||
// cleanup list
|
// cleanup list
|
||||||
@ -1507,6 +1537,9 @@ void GxsForumThreadWidget::insertMessage()
|
|||||||
mStateHelper->setActive(mTokenTypeMessageData, false);
|
mStateHelper->setActive(mTokenTypeMessageData, false);
|
||||||
mStateHelper->clear(mTokenTypeMessageData);
|
mStateHelper->clear(mTokenTypeMessageData);
|
||||||
|
|
||||||
|
ui->versions_CB->hide();
|
||||||
|
ui->time_label->show();
|
||||||
|
|
||||||
ui->postText->clear();
|
ui->postText->clear();
|
||||||
//ui->threadTitle->clear();
|
//ui->threadTitle->clear();
|
||||||
return;
|
return;
|
||||||
@ -1517,6 +1550,9 @@ void GxsForumThreadWidget::insertMessage()
|
|||||||
mStateHelper->setActive(mTokenTypeMessageData, false);
|
mStateHelper->setActive(mTokenTypeMessageData, false);
|
||||||
mStateHelper->clear(mTokenTypeMessageData);
|
mStateHelper->clear(mTokenTypeMessageData);
|
||||||
|
|
||||||
|
ui->versions_CB->hide();
|
||||||
|
ui->time_label->show();
|
||||||
|
|
||||||
//ui->threadTitle->setText(tr("Forum Description"));
|
//ui->threadTitle->setText(tr("Forum Description"));
|
||||||
ui->postText->setText(mForumDescription);
|
ui->postText->setText(mForumDescription);
|
||||||
return;
|
return;
|
||||||
@ -1535,6 +1571,8 @@ void GxsForumThreadWidget::insertMessage()
|
|||||||
// there is something wrong
|
// there is something wrong
|
||||||
mStateHelper->setWidgetEnabled(ui->previousButton, false);
|
mStateHelper->setWidgetEnabled(ui->previousButton, false);
|
||||||
mStateHelper->setWidgetEnabled(ui->nextButton, false);
|
mStateHelper->setWidgetEnabled(ui->nextButton, false);
|
||||||
|
ui->versions_CB->hide();
|
||||||
|
ui->time_label->show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1549,6 +1587,47 @@ void GxsForumThreadWidget::insertMessage()
|
|||||||
ui->by_text_label->hide();
|
ui->by_text_label->hide();
|
||||||
ui->by_label->hide();
|
ui->by_label->hide();
|
||||||
|
|
||||||
|
// add/show combobox for versions, if applicable, and enable it. If no older versions of the post available, hide the combobox.
|
||||||
|
|
||||||
|
std::cerr << "Looking into existing versions for post " << mThreadId << ", thread history: " << mPostVersions.size() << std::endl;
|
||||||
|
|
||||||
|
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::const_iterator it = mPostVersions.find(mOrigThreadId) ;
|
||||||
|
|
||||||
|
ui->versions_CB->blockSignals(true) ;
|
||||||
|
|
||||||
|
while(ui->versions_CB->count() > 0)
|
||||||
|
ui->versions_CB->removeItem(0);
|
||||||
|
|
||||||
|
if(it != mPostVersions.end())
|
||||||
|
{
|
||||||
|
std::cerr << (*it).size() << " versions found " << std::endl;
|
||||||
|
|
||||||
|
ui->versions_CB->setVisible(true) ;
|
||||||
|
ui->time_label->hide();
|
||||||
|
|
||||||
|
int current_index = 0 ;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<(*it).size();++i)
|
||||||
|
{
|
||||||
|
ui->versions_CB->insertItem(i, ((i==0)?tr("(Latest) "):tr("(Old) "))+" "+DateTime::formatLongDateTime( (*it)[i].first));
|
||||||
|
ui->versions_CB->setItemData(i,QString::fromStdString((*it)[i].second.toStdString()));
|
||||||
|
|
||||||
|
std::cerr << " added new post version " << (*it)[i].first << " " << (*it)[i].second << std::endl;
|
||||||
|
|
||||||
|
if(mThreadId == (*it)[i].second)
|
||||||
|
current_index = i ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->versions_CB->setCurrentIndex(current_index) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->versions_CB->hide();
|
||||||
|
ui->time_label->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->versions_CB->blockSignals(false) ;
|
||||||
|
|
||||||
/* request Post */
|
/* request Post */
|
||||||
RsGxsGrpMsgIdPair msgId = std::make_pair(groupId(), mThreadId);
|
RsGxsGrpMsgIdPair msgId = std::make_pair(groupId(), mThreadId);
|
||||||
requestMessageData(msgId);
|
requestMessageData(msgId);
|
||||||
@ -1951,7 +2030,7 @@ void GxsForumThreadWidget::createmessage()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId);
|
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId,RsGxsMessageId());
|
||||||
cfm->show();
|
cfm->show();
|
||||||
|
|
||||||
/* window will destroy itself! */
|
/* window will destroy itself! */
|
||||||
@ -1964,7 +2043,7 @@ void GxsForumThreadWidget::createthread()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), RsGxsMessageId());
|
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), RsGxsMessageId(),RsGxsMessageId());
|
||||||
cfm->show();
|
cfm->show();
|
||||||
|
|
||||||
/* window will destroy itself! */
|
/* window will destroy itself! */
|
||||||
@ -2018,7 +2097,7 @@ void GxsForumThreadWidget::flagperson()
|
|||||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, token_type);
|
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, token_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::replytomessage()
|
void GxsForumThreadWidget::reply_with_private_message()
|
||||||
{
|
{
|
||||||
if (groupId().isNull() || mThreadId.isNull()) {
|
if (groupId().isNull() || mThreadId.isNull()) {
|
||||||
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
||||||
@ -2027,9 +2106,19 @@ void GxsForumThreadWidget::replytomessage()
|
|||||||
|
|
||||||
// Get Message ... then complete replyMessageData().
|
// Get Message ... then complete replyMessageData().
|
||||||
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||||
requestMsgData_ReplyMessage(postId);
|
requestMsgData_ReplyWithPrivateMessage(postId);
|
||||||
}
|
}
|
||||||
|
void GxsForumThreadWidget::editforummessage()
|
||||||
|
{
|
||||||
|
if (groupId().isNull() || mThreadId.isNull()) {
|
||||||
|
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Message ... then complete replyMessageData().
|
||||||
|
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||||
|
requestMsgData_EditForumMessage(postId);
|
||||||
|
}
|
||||||
void GxsForumThreadWidget::replytoforummessage()
|
void GxsForumThreadWidget::replytoforummessage()
|
||||||
{
|
{
|
||||||
if (groupId().isNull() || mThreadId.isNull()) {
|
if (groupId().isNull() || mThreadId.isNull()) {
|
||||||
@ -2082,6 +2171,29 @@ void GxsForumThreadWidget::showAuthorInPeople(const RsGxsForumMsg& msg)
|
|||||||
requestMsgData_ShowAuthorInPeople(postId);
|
requestMsgData_ShowAuthorInPeople(postId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::editForumMessageData(const RsGxsForumMsg& msg)
|
||||||
|
{
|
||||||
|
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
||||||
|
{
|
||||||
|
std::cerr << "GxsForumThreadWidget::replyMessageData() ERROR Message Ids have changed!";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!msg.mMeta.mAuthorId.isNull())
|
||||||
|
{
|
||||||
|
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), msg.mMeta.mParentId, msg.mMeta.mMsgId, msg.mMeta.mAuthorId);
|
||||||
|
|
||||||
|
cfm->insertPastedText(QString::fromUtf8(msg.mMsg.c_str())) ;
|
||||||
|
cfm->show();
|
||||||
|
|
||||||
|
/* window will destroy itself! */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author"));
|
||||||
|
}
|
||||||
|
}
|
||||||
void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
||||||
{
|
{
|
||||||
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
||||||
@ -2093,10 +2205,12 @@ void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
|||||||
|
|
||||||
if (!msg.mMeta.mAuthorId.isNull())
|
if (!msg.mMeta.mAuthorId.isNull())
|
||||||
{
|
{
|
||||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId);
|
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId,RsGxsMessageId());
|
||||||
QTextDocument doc ;
|
|
||||||
|
// QTextDocument doc ;
|
||||||
// doc.setHtml(QString::fromUtf8(msg.mMsg.c_str()) );
|
// doc.setHtml(QString::fromUtf8(msg.mMsg.c_str()) );
|
||||||
// std::string cited_text(doc.toPlainText().toStdString()) ;
|
// std::string cited_text(doc.toPlainText().toStdString()) ;
|
||||||
|
|
||||||
RsHtml::makeQuotedText(ui->postText);
|
RsHtml::makeQuotedText(ui->postText);
|
||||||
|
|
||||||
cfm->insertPastedText(RsHtml::makeQuotedText(ui->postText)) ;
|
cfm->insertPastedText(RsHtml::makeQuotedText(ui->postText)) ;
|
||||||
@ -2317,7 +2431,8 @@ void GxsForumThreadWidget::loadMessageData(const uint32_t &token)
|
|||||||
/*********************** **** **** **** ***********************/
|
/*********************** **** **** **** ***********************/
|
||||||
/*********************** **** **** **** ***********************/
|
/*********************** **** **** **** ***********************/
|
||||||
|
|
||||||
void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId)
|
|
||||||
|
void GxsForumThreadWidget::requestMsgData_ReplyWithPrivateMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||||
{
|
{
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
@ -2352,7 +2467,23 @@ void GxsForumThreadWidget::requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgId
|
|||||||
uint32_t token;
|
uint32_t token;
|
||||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeShowAuthorInPeople);
|
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeShowAuthorInPeople);
|
||||||
}
|
}
|
||||||
|
void GxsForumThreadWidget::requestMsgData_EditForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||||
|
{
|
||||||
|
RsTokReqOptions opts;
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "GxsForumThreadWidget::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GxsMsgReq msgIds;
|
||||||
|
std::vector<RsGxsMessageId> &vect = msgIds[msgId.first];
|
||||||
|
vect.push_back(msgId.second);
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeEditForumMessage);
|
||||||
|
}
|
||||||
void GxsForumThreadWidget::requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
void GxsForumThreadWidget::requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||||
{
|
{
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
@ -2396,6 +2527,31 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::loadMsgData_EditForumMessage(const uint32_t &token)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_EditMessage()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<RsGxsForumMsg> msgs;
|
||||||
|
if (rsGxsForums->getMsgData(token, msgs))
|
||||||
|
{
|
||||||
|
if (msgs.size() != 1)
|
||||||
|
{
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_EditMessage() ERROR Wrong number of answers";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
editForumMessageData(msgs[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Missing Message Data...";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
void GxsForumThreadWidget::loadMsgData_ReplyForumMessage(const uint32_t &token)
|
void GxsForumThreadWidget::loadMsgData_ReplyForumMessage(const uint32_t &token)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_FORUMS
|
#ifdef DEBUG_FORUMS
|
||||||
@ -2523,6 +2679,10 @@ void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenReque
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.mUserType == mTokenTypeEditForumMessage) {
|
||||||
|
loadMsgData_EditForumMessage(req.mToken);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (req.mUserType == mTokenTypeShowAuthorInPeople) {
|
if (req.mUserType == mTokenTypeShowAuthorInPeople) {
|
||||||
loadMsgData_ShowAuthorInPeople(req.mToken);
|
loadMsgData_ShowAuthorInPeople(req.mToken);
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef GXSFORUMTHREADWIDGET_H
|
#ifndef GXSFORUMTHREADWIDGET_H
|
||||||
#define GXSFORUMTHREADWIDGET_H
|
#define GXSFORUMTHREADWIDGET_H
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
#include "gui/gxs/GxsMessageFrameWidget.h"
|
#include "gui/gxs/GxsMessageFrameWidget.h"
|
||||||
#include <retroshare/rsgxsforums.h>
|
#include <retroshare/rsgxsforums.h>
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
@ -73,12 +75,15 @@ private slots:
|
|||||||
void contextMenuTextBrowser(QPoint point);
|
void contextMenuTextBrowser(QPoint point);
|
||||||
|
|
||||||
void changedThread();
|
void changedThread();
|
||||||
|
void changedVersion();
|
||||||
void clickedThread (QTreeWidgetItem *item, int column);
|
void clickedThread (QTreeWidgetItem *item, int column);
|
||||||
|
|
||||||
void replytomessage();
|
void reply_with_private_message();
|
||||||
void replytoforummessage();
|
void replytoforummessage();
|
||||||
|
void editforummessage();
|
||||||
|
|
||||||
void replyMessageData(const RsGxsForumMsg &msg);
|
void replyMessageData(const RsGxsForumMsg &msg);
|
||||||
|
void editForumMessageData(const RsGxsForumMsg &msg);
|
||||||
void replyForumMessageData(const RsGxsForumMsg &msg);
|
void replyForumMessageData(const RsGxsForumMsg &msg);
|
||||||
void showAuthorInPeople(const RsGxsForumMsg& msg);
|
void showAuthorInPeople(const RsGxsForumMsg& msg);
|
||||||
|
|
||||||
@ -147,19 +152,22 @@ private:
|
|||||||
static void loadAuthorIdCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/);
|
static void loadAuthorIdCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/);
|
||||||
|
|
||||||
void requestMessageData(const RsGxsGrpMsgIdPair &msgId);
|
void requestMessageData(const RsGxsGrpMsgIdPair &msgId);
|
||||||
void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId);
|
void requestMsgData_ReplyWithPrivateMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||||
void requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgIdPair &msgId);
|
void requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgIdPair &msgId);
|
||||||
void requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
void requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||||
|
void requestMsgData_EditForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||||
|
|
||||||
void loadMessageData(const uint32_t &token);
|
void loadMessageData(const uint32_t &token);
|
||||||
void loadMsgData_ReplyMessage(const uint32_t &token);
|
void loadMsgData_ReplyMessage(const uint32_t &token);
|
||||||
void loadMsgData_ReplyForumMessage(const uint32_t &token);
|
void loadMsgData_ReplyForumMessage(const uint32_t &token);
|
||||||
|
void loadMsgData_EditForumMessage(const uint32_t &token);
|
||||||
void loadMsgData_ShowAuthorInPeople(const uint32_t &token);
|
void loadMsgData_ShowAuthorInPeople(const uint32_t &token);
|
||||||
void loadMsgData_SetAuthorOpinion(const uint32_t &token, RsReputations::Opinion opinion);
|
void loadMsgData_SetAuthorOpinion(const uint32_t &token, RsReputations::Opinion opinion);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsGxsGroupId mLastForumID;
|
RsGxsGroupId mLastForumID;
|
||||||
RsGxsMessageId mThreadId;
|
RsGxsMessageId mThreadId;
|
||||||
|
RsGxsMessageId mOrigThreadId;
|
||||||
RsGxsForumGroup mForumGroup;
|
RsGxsForumGroup mForumGroup;
|
||||||
QString mForumDescription;
|
QString mForumDescription;
|
||||||
int mSubscribeFlags;
|
int mSubscribeFlags;
|
||||||
@ -177,6 +185,7 @@ private:
|
|||||||
uint32_t mTokenTypeMessageData;
|
uint32_t mTokenTypeMessageData;
|
||||||
uint32_t mTokenTypeReplyMessage;
|
uint32_t mTokenTypeReplyMessage;
|
||||||
uint32_t mTokenTypeReplyForumMessage;
|
uint32_t mTokenTypeReplyForumMessage;
|
||||||
|
uint32_t mTokenTypeEditForumMessage;
|
||||||
uint32_t mTokenTypeShowAuthorInPeople;
|
uint32_t mTokenTypeShowAuthorInPeople;
|
||||||
uint32_t mTokenTypeNegativeAuthor;
|
uint32_t mTokenTypeNegativeAuthor;
|
||||||
uint32_t mTokenTypePositiveAuthor;
|
uint32_t mTokenTypePositiveAuthor;
|
||||||
@ -192,6 +201,8 @@ private:
|
|||||||
RsGxsMessageId mNavigatePendingMsgId;
|
RsGxsMessageId mNavigatePendingMsgId;
|
||||||
QList<RsGxsMessageId> mIgnoredMsgId;
|
QList<RsGxsMessageId> mIgnoredMsgId;
|
||||||
|
|
||||||
|
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mPostVersions ; // holds older versions of posts
|
||||||
|
|
||||||
Ui::GxsForumThreadWidget *ui;
|
Ui::GxsForumThreadWidget *ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -289,14 +289,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="7">
|
<item row="0" column="13">
|
||||||
<widget class="QLabel" name="time_label">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="12">
|
|
||||||
<widget class="QPushButton" name="nextUnreadButton">
|
<widget class="QPushButton" name="nextUnreadButton">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
@ -332,7 +325,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="14">
|
<item row="0" column="15">
|
||||||
<widget class="QPushButton" name="expandButton">
|
<widget class="QPushButton" name="expandButton">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
@ -372,7 +365,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="11">
|
<item row="0" column="12">
|
||||||
<spacer name="postHSpacer">
|
<spacer name="postHSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@ -464,20 +457,30 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="10">
|
<item row="0" column="11">
|
||||||
<widget class="GxsIdLabel" name="by_label">
|
<widget class="GxsIdLabel" name="by_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="9">
|
<item row="0" column="10">
|
||||||
<widget class="QLabel" name="by_text_label">
|
<widget class="QLabel" name="by_text_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>By </string>
|
<string>By </string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="9">
|
||||||
|
<widget class="QComboBox" name="versions_CB"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="7">
|
||||||
|
<widget class="QLabel" name="time_label">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -562,8 +565,8 @@
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -89,6 +89,8 @@ void GxsForumsFillThread::calculateExpand(const RsGxsForumMsg &msg, QTreeWidgetI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool decreasing_time_comp(const QPair<time_t,RsGxsMessageId>& e1,const QPair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }
|
||||||
|
|
||||||
void GxsForumsFillThread::run()
|
void GxsForumsFillThread::run()
|
||||||
{
|
{
|
||||||
RsTokenService *service = rsGxsForums->getTokenService();
|
RsTokenService *service = rsGxsForums->getTokenService();
|
||||||
@ -185,6 +187,99 @@ void GxsForumsFillThread::run()
|
|||||||
std::map<RsGxsMessageId,std::list<RsGxsMessageId> > kids_array ;
|
std::map<RsGxsMessageId,std::list<RsGxsMessageId> > kids_array ;
|
||||||
std::set<RsGxsMessageId> missing_parents;
|
std::set<RsGxsMessageId> missing_parents;
|
||||||
|
|
||||||
|
// First of all, remove all older versions of posts. This is done by first adding all posts into a hierarchy structure
|
||||||
|
// and then removing all posts which have a new versions available. The older versions are kept appart.
|
||||||
|
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "GxsForumsFillThread::run() Collecting post versions" << std::endl;
|
||||||
|
#endif
|
||||||
|
mPostVersions.clear();
|
||||||
|
std::list<RsGxsMessageId> msg_stack ;
|
||||||
|
|
||||||
|
for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
|
||||||
|
if(!msgIt->second.mMeta.mOrigMsgId.isNull() && msgIt->second.mMeta.mOrigMsgId != msgIt->second.mMeta.mMsgId)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << " Post " << msgIt->second.mMeta.mMsgId << " is a new version of " << msgIt->second.mMeta.mOrigMsgId << std::endl;
|
||||||
|
#endif
|
||||||
|
std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt2 = msgs.find(msgIt->second.mMeta.mOrigMsgId);
|
||||||
|
|
||||||
|
// Ensuring that the post exists allows to only collect the existing data.
|
||||||
|
|
||||||
|
if(msgIt2 == msgs.end())
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
// Make sure that the author is the same than the original message. This should always happen, but nothing can prevent someone to
|
||||||
|
// craft a new version of a message with his own signature.
|
||||||
|
|
||||||
|
if(msgIt2->second.mMeta.mAuthorId != msgIt->second.mMeta.mAuthorId)
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
// always add the post a self version
|
||||||
|
|
||||||
|
if(mPostVersions[msgIt->second.mMeta.mOrigMsgId].empty())
|
||||||
|
mPostVersions[msgIt->second.mMeta.mOrigMsgId].push_back(QPair<time_t,RsGxsMessageId>(msgIt2->second.mMeta.mPublishTs,msgIt2->second.mMeta.mMsgId)) ;
|
||||||
|
|
||||||
|
mPostVersions[msgIt->second.mMeta.mOrigMsgId].push_back(QPair<time_t,RsGxsMessageId>(msgIt->second.mMeta.mPublishTs,msgIt->second.mMeta.mMsgId)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following code assembles all new versions of a given post into the same array, indexed by the oldest version of the post.
|
||||||
|
|
||||||
|
for(QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::iterator it(mPostVersions.begin());it!=mPostVersions.end();++it)
|
||||||
|
{
|
||||||
|
QVector<QPair<time_t,RsGxsMessageId> >& v(*it) ;
|
||||||
|
|
||||||
|
for(int32_t i=0;i<v.size();++i)
|
||||||
|
if(v[i].second != it.key())
|
||||||
|
{
|
||||||
|
RsGxsMessageId sub_msg_id = v[i].second ;
|
||||||
|
|
||||||
|
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::iterator it2 = mPostVersions.find(sub_msg_id);
|
||||||
|
|
||||||
|
if(it2 != mPostVersions.end())
|
||||||
|
{
|
||||||
|
for(int32_t j=0;j<(*it2).size();++j)
|
||||||
|
if((*it2)[j].second != sub_msg_id) // dont copy it, since it is already present at slot i
|
||||||
|
v.append((*it2)[j]) ;
|
||||||
|
|
||||||
|
mPostVersions.erase(it2) ; // it2 is never equal to it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove from msg ids, all posts except the most recent one. And make the mPostVersion be indexed by the most recent version of the post,
|
||||||
|
// which corresponds to the item in the tree widget.
|
||||||
|
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "Final post versions: " << std::endl;
|
||||||
|
#endif
|
||||||
|
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mTmp;
|
||||||
|
|
||||||
|
for(QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::iterator it(mPostVersions.begin());it!=mPostVersions.end();++it)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "Original post: " << it.key() << std::endl;
|
||||||
|
#endif
|
||||||
|
// Finally, sort the posts from newer to older
|
||||||
|
|
||||||
|
qSort((*it).begin(),(*it).end(),decreasing_time_comp) ;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << " most recent version " << (*it)[0].first << " " << (*it)[0].second << std::endl;
|
||||||
|
#endif
|
||||||
|
for(int32_t i=1;i<(*it).size();++i)
|
||||||
|
{
|
||||||
|
msgs.erase((*it)[i].second) ;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << " older version " << (*it)[i].first << " " << (*it)[i].second << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
mTmp[(*it)[0].second] = *it ; // index the versions map by the ID of the most recent post.
|
||||||
|
}
|
||||||
|
mPostVersions = mTmp ;
|
||||||
|
|
||||||
// The first step is to find the top level thread messages. These are defined as the messages without
|
// The first step is to find the top level thread messages. These are defined as the messages without
|
||||||
// any parent message ID.
|
// any parent message ID.
|
||||||
|
|
||||||
@ -194,6 +289,8 @@ void GxsForumsFillThread::run()
|
|||||||
std::map<RsGxsMessageId,RsGxsForumMsg> kept_msgs;
|
std::map<RsGxsMessageId,RsGxsForumMsg> kept_msgs;
|
||||||
|
|
||||||
for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
|
for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
|
||||||
|
{
|
||||||
|
|
||||||
if(mFlatView || msgIt->second.mMeta.mParentId.isNull())
|
if(mFlatView || msgIt->second.mMeta.mParentId.isNull())
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -234,9 +331,12 @@ void GxsForumsFillThread::run()
|
|||||||
kids_array[msgIt->second.mMeta.mParentId].push_back(msgIt->first) ;
|
kids_array[msgIt->second.mMeta.mParentId].push_back(msgIt->first) ;
|
||||||
kept_msgs.insert(*msgIt) ;
|
kept_msgs.insert(*msgIt) ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msgs = kept_msgs;
|
msgs = kept_msgs;
|
||||||
|
|
||||||
|
// Also create a list of posts by time, when they are new versions of existing posts. Only the last one will have an item created.
|
||||||
|
|
||||||
// Add a fake toplevel item for the parent IDs that we dont actually have.
|
// Add a fake toplevel item for the parent IDs that we dont actually have.
|
||||||
|
|
||||||
for(std::set<RsGxsMessageId>::const_iterator it(missing_parents.begin());it!=missing_parents.end();++it)
|
for(std::set<RsGxsMessageId>::const_iterator it(missing_parents.begin());it!=missing_parents.end();++it)
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define GXSFORUMSFILLTHREAD_H
|
#define GXSFORUMSFILLTHREAD_H
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QPair>
|
||||||
#include "retroshare/rsgxsifacetypes.h"
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
|
|
||||||
class GxsForumThreadWidget;
|
class GxsForumThreadWidget;
|
||||||
@ -39,6 +41,7 @@ public:
|
|||||||
QList<QTreeWidgetItem*> mItems;
|
QList<QTreeWidgetItem*> mItems;
|
||||||
QList<QTreeWidgetItem*> mItemToExpand;
|
QList<QTreeWidgetItem*> mItemToExpand;
|
||||||
|
|
||||||
|
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mPostVersions ;
|
||||||
private:
|
private:
|
||||||
void calculateExpand(const RsGxsForumMsg &msg, QTreeWidgetItem *item);
|
void calculateExpand(const RsGxsForumMsg &msg, QTreeWidgetItem *item);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user