Merge pull request #682 from csoler/v0.6-EditPosts

V0.6 edit posts
This commit is contained in:
csoler 2017-03-14 20:04:22 +01:00 committed by GitHub
commit 44f297156e
9 changed files with 446 additions and 54 deletions

View File

@ -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 ;
{ {

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}; };

View File

@ -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>

View File

@ -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)

View File

@ -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);