Merge pull request #2658 from csoler/v0.6-BugFixing_20

Full rework on Mail system
This commit is contained in:
csoler 2022-12-12 13:55:05 +01:00 committed by GitHub
commit 97390d3f44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 632 additions and 498 deletions

@ -1 +1 @@
Subproject commit 8f3a3070519322a66b0e83ecb2035e0ac7e67e58
Subproject commit 5d7c50e2161ca11661b7b61c5a2663364aab5b59

View File

@ -127,11 +127,45 @@ FriendSelectionWidget::FriendSelectionWidget(QWidget *parent)
/* Refresh style to have the correct text color */
Rshare::refreshStyleSheet(this, false);
mEventHandlerId_identities = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId_identities, RsEventType::GXS_IDENTITY );
mEventHandlerId_peers = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId_peers, RsEventType::PEER_CONNECTION );
}
void FriendSelectionWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
const RsGxsIdentityEvent *fe = dynamic_cast<const RsGxsIdentityEvent*>(event.get());
if(fe)
{
updateDisplay(true);
update(); // Qt flush
return;
}
const RsConnectionEvent *fp = dynamic_cast<const RsConnectionEvent*>(event.get());
if(fp)
switch(fp->mConnectionInfoCode)
{
case RsConnectionEventCode::PEER_REMOVED:
case RsConnectionEventCode::PEER_ADDED:
updateDisplay(true);
update(); // Qt flush
break;
default: break ;
}
}
FriendSelectionWidget::~FriendSelectionWidget()
{
delete ui;
rsEvents->unregisterEventsHandler(mEventHandlerId_peers);
rsEvents->unregisterEventsHandler(mEventHandlerId_identities);
delete ui;
}
void FriendSelectionWidget::changeEvent(QEvent *e)

View File

@ -24,6 +24,7 @@
#include <QWidget>
#include <QDialog>
#include "retroshare/rsevents.h"
#include <gui/gxs/RsGxsUpdateBroadcastPage.h>
namespace Ui {
@ -151,6 +152,8 @@ private:
void setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add);
private:
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
bool mStarted;
RSTreeWidgetItemCompareRole *mCompareRole;
Modus mListModus;
@ -173,6 +176,9 @@ private:
QList<QAction*> mContextMenuActions;
std::set<std::string> mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
RsEventsHandlerId_t mEventHandlerId_identities;
RsEventsHandlerId_t mEventHandlerId_peers;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes)

View File

@ -229,7 +229,7 @@ void ChatMsgItem::sendMessage()
mi.title = tr("Quick Message").toUtf8().constData();
mi.msg = quickmsgText->toHtml().toUtf8().constData();
mi.rspeerid_msgto.insert(mPeerId);
mi.destinations.insert(MsgAddress(mPeerId,MsgAddress::MSG_ADDRESS_MODE_TO));
rsMail->MessageSend(mi);

View File

@ -146,39 +146,39 @@ void MsgItem::updateItemStatic()
/* get peer Id */
if (mi.msgflags & RS_MSG_DISTANT)
avatar->setGxsId(mi.rsgxsid_srcId) ;
avatar->setGxsId(mi.from.toGxsId()) ;
else
avatar->setId(ChatId(mi.rspeerid_srcId)) ;
avatar->setId(ChatId(mi.from.toRsPeerId())) ;
QString title;
QString srcName;
if ((mi.msgflags & RS_MSG_SYSTEM) && mi.rspeerid_srcId == rsPeers->getOwnId())
if ((mi.msgflags & RS_MSG_SYSTEM) && mi.from.toRsPeerId() == rsPeers->getOwnId())
srcName = "RetroShare";
else
{
if(mi.msgflags & RS_MSG_DISTANT)
{
RsIdentityDetails details ;
rsIdentity->getIdDetails(mi.rsgxsid_srcId, details) ;
rsIdentity->getIdDetails(mi.from.toGxsId(), details) ;
srcName = QString::fromUtf8(details.mNickname.c_str());
}
else
srcName = QString::fromUtf8(rsPeers->getPeerName(mi.rspeerid_srcId).c_str());
srcName = QString::fromUtf8(rsPeers->getPeerName(mi.from.toRsPeerId()).c_str());
}
if (!mIsHome)
{
if ((mi.msgflags & RS_MSG_USER_REQUEST) && (!mi.rsgxsid_srcId.isNull()))
if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) // !mi.rsgxsid_srcId.isNull()))
{
title = QString::fromUtf8(mi.title.c_str()) + " " + tr("from") + " " + srcName;
replyButton->setText(tr("Reply to invite"));
subjectLabel->hide();
info_Frame_Invite->show();
}
else if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.rsgxsid_srcId.isNull())
else if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.from.type()!=MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) // mi.rsgxsid_srcId.isNull())
{
title = QString::fromUtf8(mi.title.c_str()) + " " + " " + srcName;
subjectLabel->hide();
@ -233,7 +233,11 @@ void MsgItem::updateItemStatic()
for(it = mi.files.begin(); it != mi.files.end(); ++it)
{
/* add file */
SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->path, it->size, SFI_STATE_REMOTE, mi.rspeerid_srcId);
RsPeerId srcId ;
if(mi.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
srcId = mi.from.toRsPeerId();
SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->path, it->size, SFI_STATE_REMOTE, srcId);
mFileItems.push_back(fi);
QLayout *layout = expandFrame->layout();
@ -395,9 +399,12 @@ void MsgItem::sendInvite()
if (!rsMail->getMessage(mMsgId, mi))
return;
if(mi.from.type()!=MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
return;
//if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
//{
MessageComposer::sendInvite(mi.rsgxsid_srcId,false);
MessageComposer::sendInvite(mi.from.toGxsId(),false);
//}
}

View File

@ -25,6 +25,7 @@
#include "gui/common/FilesDefs.h"
#include "gui/Identity/IdEditDialog.h"
#include "util/misc.h"
#include "util/qtthreadsutils.h"
#include <retroshare/rspeers.h>
@ -76,6 +77,24 @@ GxsIdChooser::GxsIdChooser(QWidget *parent)
/* Connect signals */
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(myCurrentIndexChanged(int)));
connect(this, SIGNAL(activated(int)), this, SLOT(indexActivated(int)));
// also capture identity creation/deletion events so as to update the UI accordingly
mEventHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId, RsEventType::GXS_IDENTITY );
}
void GxsIdChooser::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
if(event->mType != RsEventType::GXS_IDENTITY) return;
const RsGxsIdentityEvent *fe = dynamic_cast<const RsGxsIdentityEvent*>(event.get());
if(!fe)
return;
updateDisplay(true);
update(); // Qt flush
}
void GxsIdChooser::setFlags(uint32_t flags)
@ -86,6 +105,7 @@ void GxsIdChooser::setFlags(uint32_t flags)
GxsIdChooser::~GxsIdChooser()
{
rsEvents->unregisterEventsHandler(mEventHandlerId);
}
void GxsIdChooser::fillDisplay(bool complete)

View File

@ -21,6 +21,7 @@
#ifndef _GXS_ID_CHOOSER_H
#define _GXS_ID_CHOOSER_H
#include "retroshare/rsevents.h"
#include "gui/common/RSComboBox.h"
#include "retroshare/rsgxsifacetypes.h"
@ -78,6 +79,7 @@ private slots:
private:
void loadPrivateIds();
void setDefaultItem();
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
uint32_t mFlags;
RsGxsId mDefaultId;
@ -86,6 +88,8 @@ private:
std::set<RsGxsId> mConstraintIdsSet ; // leave empty if all allowed
// RsGxsUpdateBroadcastBase *mBase;
RsEventsHandlerId_t mEventHandlerId;
};
#endif

View File

@ -109,7 +109,9 @@ public:
QList<QIcon> icons;
QString comment;
if(rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages)
if(id.isNull())
name = QObject::tr("[System]");
else if(RsPeerId(id)==rsPeers->getOwnId() || rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages)
name = QString::fromUtf8(rsPeers->getPeerName(RsPeerId(id)).c_str()) ;
else if(!GxsIdDetails::MakeIdDesc(id, false, name, icons, comment,GxsIdDetails::ICON_TYPE_NONE))
return false;
@ -123,8 +125,13 @@ public:
bool exist = false;
if(rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages)
{
if(id.isNull())
{
name = QObject::tr("[System]");
icon = QIcon();
}
else if(RsPeerId(id)==rsPeers->getOwnId() || rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages)
{
name = QString::fromUtf8(rsPeers->getPeerName(RsPeerId(id)).c_str()) ;
icon = FilesDefs::getIconFromQtResourcePath(":/icons/avatar_128.png");
}

View File

@ -122,6 +122,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags)
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);
mAlreadySent = false;
m_msgType = NORMAL;
// needed to send system flags with reply
msgFlags = 0;
@ -149,7 +151,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags)
ui.hashBox->hide();
// connect up the buttons.
connect( ui.actionSend, SIGNAL( triggered(bool)), this, SLOT( sendMessage() ) );
connect( ui.actionSend, SIGNAL( triggered(bool)), this, SLOT( sendMessage() ), Qt::UniqueConnection );
//connect( ui.actionReply, SIGNAL( triggered (bool)), this, SLOT( replyMessage( ) ) );
connect(ui.boldbtn, SIGNAL(clicked()), this, SLOT(textBold()));
connect(ui.underlinebtn, SIGNAL(clicked()), this, SLOT(textUnderline()));
@ -658,61 +660,20 @@ void MessageComposer::addConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId
std::list<MsgInfoSummary> msgList;
std::list<MsgInfoSummary>::const_iterator it;
rsMail->getMessageSummaries(msgList);
for(it = msgList.begin(); it != msgList.end(); ++it) {
if (it->msgflags & RS_MSG_TRASH) {
continue;
}
if ((it->msgflags & RS_MSG_BOXMASK) != RS_MSG_INBOX) {
continue;
}
if ((it->msgflags & RS_MSG_USER_REQUEST) == 0) {
continue;
}
if (it->title == title.toUtf8().constData()) {
rsMail->getMessageSummaries(Rs::Msgs::BoxName::BOX_INBOX,msgList);
// do not re-add an existing request.
// note: the test with name() is very unsecure. We should use the ID instead.
for(it = msgList.begin(); it != msgList.end(); ++it)
if((it->msgflags & RS_MSG_USER_REQUEST) && it->title == title.toUtf8().constData())
return;
}
}
/* create a message */
QString msgText = tr("Hi %1,<br><br>%2 wants to be friends with you on RetroShare.<br><br>Respond now:<br>%3<br><br>Thanks,<br>The RetroShare Team").arg(QString::fromUtf8(rsPeers->getGPGName(rsPeers->getGPGOwnId()).c_str()), link.name(), link.toHtml());
rsMail->SystemMessage(title.toUtf8().constData(), msgText.toUtf8().constData(), RS_MSG_USER_REQUEST);
}
#ifdef UNUSED_CODE
void MessageComposer::sendChannelPublishKey(RsGxsChannelGroup &group)
{
// QString channelName = QString::fromUtf8(group.mMeta.mGroupName.c_str());
// RetroShareLink link;
// if (!link.createGxsGroupLink(RetroShareLink::TYPE_CHANNEL, group.mMeta.mGroupId, channelName)) {
// return;
// }
// QString title = tr("Publish key for channel %1").arg(channelName);
// /* create a message */
// QString msgText = tr("... %1 ...<br>%2").arg(channelName, link.toHtml());
// rsMail->SystemMessage(title.toUtf8().constData(), msgText.toUtf8().constData(), RS_MSG_PUBLISH_KEY);
}
void MessageComposer::sendForumPublishKey(RsGxsForumGroup &group)
{
// QString forumName = QString::fromUtf8(group.mMeta.mGroupName.c_str());
// RetroShareLink link;
// if (!link.createGxsGroupLink(RetroShareLink::TYPE_FORUM, group.mMeta.mGroupId, forumName)) {
// return;
// }
// QString title = tr("Publish key for forum %1").arg(forumName);
// /* create a message */
// QString msgText = tr("... %1 ...<br>%2").arg(forumName, link.toHtml());
// rsMail->SystemMessage(title.toUtf8().constData(), msgText.toUtf8().constData(), RS_MSG_PUBLISH_KEY);
}
#endif
void MessageComposer::closeEvent (QCloseEvent * event)
{
bool bClose = true;
@ -930,6 +891,7 @@ void MessageComposer::addFile(const FileInfo &fileInfo)
void MessageComposer::titleChanged()
{
calculateTitle();
std::cerr << "Setting modified 004 = true" << std::endl;
ui.msgText->document()->setModified(true);
}
@ -1065,36 +1027,63 @@ MessageComposer *MessageComposer::newMsg(const std::string &msgId /* = ""*/)
std::list<RsGroupInfo> groupInfoList;
rsPeers->getGroupInfoList(groupInfoList);
// std::list<std::string> groupIds;
// std::list<std::string>::iterator groupIt;
// std::list<std::string> groupIds;
// std::list<std::string>::iterator groupIt;
// calculateGroupsOfSslIds(groupInfoList, msgInfo.msgto, groupIds);
// for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) {
// msgComposer->addRecipient(MessageComposer::TO, *groupIt, true) ;
// }
// calculateGroupsOfSslIds(groupInfoList, msgInfo.msgto, groupIds);
// for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) {
// msgComposer->addRecipient(MessageComposer::TO, *groupIt, true) ;
// }
// calculateGroupsOfSslIds(groupInfoList, msgInfo.msgcc, groupIds);
// for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) {
// msgComposer->addRecipient(MessageComposer::CC, *groupIt, true) ;
// }
// calculateGroupsOfSslIds(groupInfoList, msgInfo.msgcc, groupIds);
// for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) {
// msgComposer->addRecipient(MessageComposer::CC, *groupIt, true) ;
// }
// calculateGroupsOfSslIds(groupInfoList, msgInfo.msgbcc, groupIds);
// for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) {
// msgComposer->addRecipient(MessageComposer::BCC, *groupIt, true) ;
// }
// calculateGroupsOfSslIds(groupInfoList, msgInfo.msgbcc, groupIds);
// for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) {
// msgComposer->addRecipient(MessageComposer::BCC, *groupIt, true) ;
// }
for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgto.begin(); it != msgInfo.rspeerid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ;
for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgcc.begin(); it != msgInfo.rspeerid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ;
for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgbcc.begin(); it != msgInfo.rspeerid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ;
for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgto.begin(); it != msgInfo.rsgxsid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ;
for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgcc.begin(); it != msgInfo.rsgxsid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ;
for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgbcc.begin(); it != msgInfo.rsgxsid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ;
for(auto m:msgInfo.destinations)
switch(m.mode())
{
case MsgAddress::MSG_ADDRESS_MODE_TO:
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
msgComposer->addRecipient(MessageComposer::TO,m.toGxsId());
else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
msgComposer->addRecipient(MessageComposer::TO,m.toRsPeerId());
break;
case MsgAddress::MSG_ADDRESS_MODE_CC:
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
msgComposer->addRecipient(MessageComposer::CC,m.toGxsId());
else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
msgComposer->addRecipient(MessageComposer::CC,m.toRsPeerId());
break;
case MsgAddress::MSG_ADDRESS_MODE_BCC:
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
msgComposer->addRecipient(MessageComposer::BCC,m.toGxsId());
else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
msgComposer->addRecipient(MessageComposer::BCC,m.toRsPeerId());
break;
default:break;
}
// for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgto.begin(); it != msgInfo.rspeerid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ;
// for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgcc.begin(); it != msgInfo.rspeerid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ;
// for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgbcc.begin(); it != msgInfo.rspeerid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ;
// for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgto.begin(); it != msgInfo.rsgxsid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ;
// for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgcc.begin(); it != msgInfo.rsgxsid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ;
// for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgbcc.begin(); it != msgInfo.rsgxsid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ;
MsgTagInfo tagInfo;
rsMail->getMessageTag(msgId, tagInfo);
msgComposer->m_tagIds = tagInfo.tagIds;
msgComposer->m_tagIds = tagInfo;
msgComposer->showTagLabels();
std::cerr << "Setting modified 005 = false" << std::endl;
msgComposer->ui.msgText->document()->setModified(false);
}
@ -1110,7 +1099,7 @@ QString MessageComposer::buildReplyHeader(const MessageInfo &msgInfo)
QString from;
if(msgInfo.msgflags & RS_MSG_DISTANT)
{
link = RetroShareLink::createMessage(msgInfo.rsgxsid_srcId, "");
link = RetroShareLink::createMessage(msgInfo.from.toGxsId(), "");
if (link.valid())
{
from += link.toHtml();
@ -1118,57 +1107,39 @@ QString MessageComposer::buildReplyHeader(const MessageInfo &msgInfo)
}
else
{
link = RetroShareLink::createMessage(msgInfo.rspeerid_srcId, "");
link = RetroShareLink::createMessage(msgInfo.from.toRsPeerId(), "");
if (link.valid())
{
from += link.toHtml();
}
}
QString to,cc;
QString to;
for ( std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgto.begin(); it != msgInfo.rspeerid_msgto.end(); ++it)
for(auto m:msgInfo.destinations)
{
link = RetroShareLink::createMessage(*it, "");
RetroShareLink link;
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
link = RetroShareLink::createMessage(m.toGxsId(), "");
else
link = RetroShareLink::createMessage(m.toRsPeerId(), "");
if (link.valid())
{
if (!to.isEmpty())
to += ", ";
if(m.mode()==MsgAddress::MSG_ADDRESS_MODE_TO)
{
if (!to.isEmpty())
to += ", ";
to += link.toHtml();
}
}
for ( std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgto.begin(); it != msgInfo.rsgxsid_msgto.end(); ++it)
{
link = RetroShareLink::createMessage(*it, "");
if (link.valid())
{
if (!to.isEmpty())
to += ", ";
to += link.toHtml();
}
}
QString cc;
for (std::set<RsPeerId>::const_iterator it = msgInfo.rspeerid_msgcc.begin(); it != msgInfo.rspeerid_msgcc.end(); ++it) {
link = RetroShareLink::createMessage(*it, "");
if (link.valid()) {
if (!cc.isEmpty()) {
cc += ", ";
to += link.toHtml();
}
cc += link.toHtml();
}
}
for (std::set<RsGxsId>::const_iterator it = msgInfo.rsgxsid_msgcc.begin(); it != msgInfo.rsgxsid_msgcc.end(); ++it) {
link = RetroShareLink::createMessage(*it, "");
if (link.valid()) {
if (!cc.isEmpty()) {
cc += ", ";
}
cc += link.toHtml();
}
}
else if(m.mode()==MsgAddress::MSG_ADDRESS_MODE_CC)
{
if (!cc.isEmpty())
cc += ", ";
cc += link.toHtml();
}
}
QString header = QString("<span>-----%1-----").arg(tr("Original Message"));
header += QString("<br><font size='3'><strong>%1: </strong>%2</font><br>").arg(tr("From"), from);
@ -1220,6 +1191,7 @@ void MessageComposer::setQuotedMsg(const QString &msg, const QString &header)
ui.msgText->moveCursor(QTextCursor::Start);
ui.msgText->setUndoRedoEnabled(true);
std::cerr << "Setting modified 006 = true" << std::endl;
ui.msgText->document()->setModified(true);
ui.msgText->setFocus( Qt::OtherFocusReason );
@ -1232,6 +1204,11 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all)
return NULL;
}
if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID && msgInfo.from.toRsPeerId().isNull())
{
QMessageBox::warning(nullptr,tr("Will not reply"),tr("There is no point in replying to a notification message!"));
return nullptr;
}
MessageComposer *msgComposer = MessageComposer::newMsg();
msgComposer->m_msgParentId = msgId;
msgComposer->m_msgType = REPLY;
@ -1241,14 +1218,18 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all)
msgComposer->setTitleText(QString::fromUtf8(msgInfo.title.c_str()), REPLY);
msgComposer->setQuotedMsg(QString::fromUtf8(msgInfo.msg.c_str()), buildReplyHeader(msgInfo));
if(!msgInfo.rspeerid_srcId.isNull()) msgComposer->addRecipient(MessageComposer::TO, msgInfo.rspeerid_srcId);
if(!msgInfo.rsgxsid_srcId.isNull()) msgComposer->addRecipient(MessageComposer::TO, msgInfo.rsgxsid_srcId);
if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
msgComposer->addRecipient(MessageComposer::TO, msgInfo.from.toGxsId());
else if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
msgComposer->addRecipient(MessageComposer::TO, msgInfo.from.toRsPeerId());
// make sure the current ID is among the ones the msg was actually sent to.
for(auto it(msgInfo.rsgxsid_msgto.begin());it!=msgInfo.rsgxsid_msgto.end();++it)
if(rsIdentity->isOwnId(*it))
#warning: We do not know here what is the atual destination of the message, since it may have been sent to two of our IDs at once.
for(auto m:msgInfo.destinations)
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID && rsIdentity->isOwnId(m.toGxsId()))
{
msgComposer->ui.respond_to_CB->setDefaultId(*it) ;
msgComposer->ui.respond_to_CB->setDefaultId(m.toGxsId()) ;
break ;
}
// Note: another solution is to do
@ -1257,23 +1238,27 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all)
if (all)
{
RsPeerId ownId = rsPeers->getOwnId();
for(auto m:msgInfo.destinations)
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
msgComposer->addRecipient(MessageComposer::TO,m.toGxsId());
else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
msgComposer->addRecipient(MessageComposer::TO,m.toRsPeerId());
for (std::set<RsPeerId>::iterator tli = msgInfo.rspeerid_msgto.begin(); tli != msgInfo.rspeerid_msgto.end(); ++tli)
if (ownId != *tli)
msgComposer->addRecipient(MessageComposer::TO, *tli) ;
// for (std::set<RsPeerId>::iterator tli = msgInfo.rspeerid_msgto.begin(); tli != msgInfo.rspeerid_msgto.end(); ++tli)
// if (ownId != *tli)
// msgComposer->addRecipient(MessageComposer::TO, *tli) ;
for (std::set<RsPeerId>::iterator tli = msgInfo.rspeerid_msgcc.begin(); tli != msgInfo.rspeerid_msgcc.end(); ++tli)
if (ownId != *tli)
msgComposer->addRecipient(MessageComposer::TO, *tli) ;
// for (std::set<RsPeerId>::iterator tli = msgInfo.rspeerid_msgcc.begin(); tli != msgInfo.rspeerid_msgcc.end(); ++tli)
// if (ownId != *tli)
// msgComposer->addRecipient(MessageComposer::TO, *tli) ;
for (std::set<RsGxsId>::iterator tli = msgInfo.rsgxsid_msgto.begin(); tli != msgInfo.rsgxsid_msgto.end(); ++tli)
//if (ownId != *tli)
msgComposer->addRecipient(MessageComposer::TO, *tli) ;
// for (std::set<RsGxsId>::iterator tli = msgInfo.rsgxsid_msgto.begin(); tli != msgInfo.rsgxsid_msgto.end(); ++tli)
// //if (ownId != *tli)
// msgComposer->addRecipient(MessageComposer::TO, *tli) ;
for (std::set<RsGxsId>::iterator tli = msgInfo.rsgxsid_msgcc.begin(); tli != msgInfo.rsgxsid_msgcc.end(); ++tli)
//if (ownId != *tli)
msgComposer->addRecipient(MessageComposer::TO, *tli) ;
// for (std::set<RsGxsId>::iterator tli = msgInfo.rsgxsid_msgcc.begin(); tli != msgInfo.rsgxsid_msgcc.end(); ++tli)
// //if (ownId != *tli)
// msgComposer->addRecipient(MessageComposer::TO, *tli) ;
}
// needed to send system flags with reply
@ -1282,7 +1267,7 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all)
MsgTagInfo tagInfo;
rsMail->getMessageTag(msgId, tagInfo);
msgComposer->m_tagIds = tagInfo.tagIds;
msgComposer->m_tagIds = tagInfo;
msgComposer->showTagLabels();
msgComposer->calculateTitle();
@ -1363,26 +1348,29 @@ void MessageComposer::setMsgText(const QString &msg, bool asHtml)
c.movePosition(QTextCursor::End);
ui.msgText->setTextCursor(c);
std::cerr << "Setting modified 007 = true" << std::endl;
ui.msgText->document()->setModified(true);
}
void MessageComposer::sendMessage()
{
if (sendMessage_internal(false)) {
/* check for existing title */
if (ui.titleEdit->text().isNull())
if (QMessageBox::warning(this, tr("RetroShare"), tr("Do you want to send the message without a subject ?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
ui.titleEdit->setFocus();
return ; // Don't send with an empty subject
}
if (sendMessage_internal(false))
close();
}
}
bool MessageComposer::sendMessage_internal(bool bDraftbox)
bool MessageComposer::buildMessage(MessageInfo& mi)
{
/* construct a message */
MessageInfo mi;
// add a GXS signer/from in case the message is to be sent to a distant peer
// add a GXS signer/from in case the message is to be sent to a distant peer
mi.rsgxsid_srcId = RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()) ;
//std::cerr << "MessageSend: setting 'from' field to GXS id = " << mi.rsgxsid_srcId << std::endl;
//std::cerr << "MessageSend: setting 'from' field to GXS id = " << mi.rsgxsid_srcId << std::endl;
mi.title = misc::removeNewLine(ui.titleEdit->text()).toUtf8().constData();
// needed to send system flags with reply
@ -1392,14 +1380,6 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
RsHtml::optimizeHtml(ui.msgText, text);
mi.msg = text.toUtf8().constData();
/* check for existing title */
if (bDraftbox == false && mi.title.empty()) {
if (QMessageBox::warning(this, tr("RetroShare"), tr("Do you want to send the message without a subject ?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
ui.titleEdit->setFocus();
return false; // Don't send with an empty subject
}
}
int filesCount = ui.msgFileList->topLevelItemCount();
for (int i = 0; i < filesCount; ++i) {
QTreeWidgetItem *item = ui.msgFileList->topLevelItem(i);
@ -1456,12 +1436,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
switch (type)
{
case TO: mi.rspeerid_msgto.insert(*sslIt);
break;
case CC: mi.rspeerid_msgcc.insert(*sslIt);
break;
case BCC:mi.rspeerid_msgbcc.insert(*sslIt);
break;
case TO: mi.destinations.insert(MsgAddress(*sslIt,MsgAddress::MSG_ADDRESS_MODE_TO)); break;
case CC: mi.destinations.insert(MsgAddress(*sslIt,MsgAddress::MSG_ADDRESS_MODE_CC)); break;
case BCC: mi.destinations.insert(MsgAddress(*sslIt,MsgAddress::MSG_ADDRESS_MODE_BCC)); break;
}
}
}
@ -1473,12 +1450,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
switch (type)
{
case TO: mi.rspeerid_msgto.insert(pid);
break ;
case CC: mi.rspeerid_msgcc.insert(pid);
break ;
case BCC:mi.rspeerid_msgbcc.insert(pid);
break ;
case TO: mi.destinations.insert(MsgAddress(pid,MsgAddress::MSG_ADDRESS_MODE_TO)); break;
case CC: mi.destinations.insert(MsgAddress(pid,MsgAddress::MSG_ADDRESS_MODE_CC)); break;
case BCC: mi.destinations.insert(MsgAddress(pid,MsgAddress::MSG_ADDRESS_MODE_BCC)); break;
}
}
break ;
@ -1488,12 +1462,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
switch (type)
{
case TO: mi.rsgxsid_msgto.insert(gid) ;
break ;
case CC: mi.rsgxsid_msgcc.insert(gid) ;
break ;
case BCC:mi.rsgxsid_msgbcc.insert(gid) ;
break ;
case TO: mi.destinations.insert(MsgAddress(gid,MsgAddress::MSG_ADDRESS_MODE_TO)); break;
case CC: mi.destinations.insert(MsgAddress(gid,MsgAddress::MSG_ADDRESS_MODE_CC)); break;
case BCC: mi.destinations.insert(MsgAddress(gid,MsgAddress::MSG_ADDRESS_MODE_BCC)); break;
}
}
break ;
@ -1503,6 +1474,49 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
break ;
}
}
bool at_least_one_gxsid = false;
for(auto m:mi.destinations)
if(m.type() == MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
{
at_least_one_gxsid=true;
break;
}
if(!at_least_one_gxsid)
mi.from = Rs::Msgs::MsgAddress(rsPeers->getOwnId(),MsgAddress::MSG_ADDRESS_MODE_TO);
else
{
auto gxs_id_from = RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString());
if(gxs_id_from.isNull())
{
QMessageBox::warning(this, tr("RetroShare"), tr("Please create an identity to sign distant messages, or remove the distant peers from the destination list."), QMessageBox::Ok);
return false; // Don't send if cannot sign.
}
mi.from = MsgAddress(RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()),MsgAddress::MSG_ADDRESS_MODE_TO) ;
}
return true;
}
bool MessageComposer::sendMessage_internal(bool bDraftbox)
{
if(mAlreadySent)
{
std::cerr << "Already_sent is true. Giving up." << std::endl;
return true;
}
/* construct a message */
MessageInfo mi;
if(!buildMessage(mi))
return false;
std::cerr << "Setting already_sent=true" << std::endl;
mAlreadySent = true;
if (bDraftbox)
{
@ -1527,21 +1541,15 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
else
{
/* check for the recipient */
if (mi.rspeerid_msgto.empty() && mi.rspeerid_msgcc.empty() && mi.rspeerid_msgbcc.empty()
&& mi.rsgxsid_msgto.empty() && mi.rsgxsid_msgcc.empty() && mi.rsgxsid_msgbcc.empty())
if (mi.destinations.empty())
{
QMessageBox::warning(this, tr("RetroShare"), tr("Please insert at least one recipient."), QMessageBox::Ok);
return false; // Don't send with no recipient
}
if(mi.rsgxsid_srcId.isNull() && !(mi.rsgxsid_msgto.empty() && mi.rsgxsid_msgcc.empty() && mi.rsgxsid_msgbcc.empty()))
{
QMessageBox::warning(this, tr("RetroShare"), tr("Please create an identity to sign distant messages, or remove the distant peers from the destination list."), QMessageBox::Ok);
return false; // Don't send if cannot sign.
}
if (rsMail->MessageSend(mi) == false) {
if (rsMail->MessageSend(mi) == false)
return false;
}
if (m_msgParentId.empty() == false) {
switch (m_msgType) {
@ -1563,19 +1571,17 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
/* insert new tags */
std::list<uint32_t>::iterator tag;
for (tag = m_tagIds.begin(); tag != m_tagIds.end(); ++tag) {
if (std::find(tagInfo.tagIds.begin(), tagInfo.tagIds.end(), *tag) == tagInfo.tagIds.end()) {
rsMail->setMessageTag(mi.msgId, *tag, true);
} else {
tagInfo.tagIds.remove(*tag);
}
}
for (auto tag:m_tagIds)
if (tagInfo.find(tag) == tagInfo.end())
rsMail->setMessageTag(mi.msgId, tag, true);
else
tagInfo.erase(tag);
/* remove deleted tags */
for (tag = tagInfo.tagIds.begin(); tag != tagInfo.tagIds.end(); ++tag) {
rsMail->setMessageTag(mi.msgId, *tag, false);
}
for (auto tag:tagInfo)
rsMail->setMessageTag(mi.msgId, tag, false);
}
std::cerr << "Setting modified 001 = false" << std::endl;
ui.msgText->document()->setModified(false);
return true;
@ -2394,6 +2400,7 @@ bool MessageComposer::fileSave()
QTextStream ts(&file);
ts.setCodec(QTextCodec::codecForName("UTF-8"));
ts << ui.msgText->document()->toHtml("UTF-8");
std::cerr << "Setting modified 002 = false" << std::endl;
ui.msgText->document()->setModified(false);
return true;
}
@ -2448,6 +2455,7 @@ void MessageComposer::filePrintPdf()
void MessageComposer::setCurrentFileName(const QString &fileName)
{
this->fileName = fileName;
std::cerr << "Setting modified 003 = false" << std::endl;
ui.msgText->document()->setModified(false);
setWindowModified(false);
@ -2798,17 +2806,17 @@ void MessageComposer::tagSet(int tagId, bool set)
return;
}
std::list<uint32_t>::iterator tag = std::find(m_tagIds.begin(), m_tagIds.end(), tagId);
if (tag == m_tagIds.end()) {
if (set) {
m_tagIds.push_back(tagId);
/* Keep the list sorted */
m_tagIds.sort();
}
} else {
if (set == false) {
m_tagIds.remove(tagId);
}
auto tag = m_tagIds.find(tagId);
if (tag == m_tagIds.end())
{
if (set)
m_tagIds.insert(tagId);
}
else
{
if (set == false)
m_tagIds.erase(tagId);
}
showTagLabels();
@ -2835,8 +2843,8 @@ void MessageComposer::showTagLabels()
rsMail->getMessageTagTypes(tags);
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator tag;
for (std::list<uint32_t>::iterator tagId = m_tagIds.begin(); tagId != m_tagIds.end(); ++tagId) {
tag = tags.types.find(*tagId);
for (auto tagId:m_tagIds) {
tag = tags.types.find(tagId);
if (tag != tags.types.end()) {
QLabel *tagLabel = new QLabel(TagDefs::name(tag->first, tag->second.first), this);
tagLabel->setMaximumHeight(QFontMetrics(tagLabel->font()).height()*1.2);

View File

@ -172,6 +172,7 @@ private slots:
private:
static QString buildReplyHeader(const MessageInfo &msgInfo);
bool buildMessage(MessageInfo& mi);
void processSettings(bool bLoad);
@ -250,7 +251,7 @@ private:
std::string m_msgParentId; // parent message id
std::string m_sDraftMsgId; // existing message id
enumMessageType m_msgType;
std::list<uint32_t> m_tagIds;
std::set<uint32_t> m_tagIds;
QList<QLabel*> tagLabels;
// needed to send system flags with reply
@ -264,6 +265,7 @@ private:
QLabel *lineLabel;
bool has_gxs;
bool mAlreadySent; // prevents a Qt bug that calls the same action twice.
/** Qt Designer generated object */
Ui::MessageComposer ui;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>750</height>
<width>1215</width>
<height>825</height>
</rect>
</property>
<property name="windowTitle">
@ -31,12 +31,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>524287</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>220</width>
@ -86,12 +80,6 @@
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>220</width>
@ -1310,8 +1298,8 @@ border-image: url(:/images/closepressed.png)
<rect>
<x>0</x>
<y>0</y>
<width>1176</width>
<height>20</height>
<width>1215</width>
<height>25</height>
</rect>
</property>
</widget>
@ -1452,8 +1440,8 @@ border-image: url(:/images/closepressed.png)
<tabstop>hashBox</tabstop>
</tabstops>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -53,7 +53,7 @@ const QString RsMessageModel::FilterString("filtered");
RsMessageModel::RsMessageModel(QObject *parent)
: QAbstractItemModel(parent)
{
mCurrentBox = BOX_NONE;
mCurrentBox = Rs::Msgs::BoxName::BOX_NONE;
mQuickViewFilter = QUICK_VIEW_ALL;
mFilterType = FILTER_TYPE_NONE;
mFilterStrings.clear();
@ -88,7 +88,7 @@ int RsMessageModel::rowCount(const QModelIndex& parent) const
int RsMessageModel::columnCount(const QModelIndex &/*parent*/) const
{
return COLUMN_THREAD_NB_COLUMNS ;
return COLUMN_THREAD_NB_COLUMNS;
}
bool RsMessageModel::getMessageData(const QModelIndex& i,Rs::Msgs::MessageInfo& fmpe) const
@ -167,7 +167,8 @@ QVariant RsMessageModel::headerData(int section, Qt::Orientation /*orientation*/
{
case COLUMN_THREAD_DATE: return tr("Date");
case COLUMN_THREAD_AUTHOR: return tr("From");
case COLUMN_THREAD_SUBJECT: return tr("Subject");
case COLUMN_THREAD_TO: return tr("To");
case COLUMN_THREAD_SUBJECT: return tr("Subject");
case COLUMN_THREAD_TAGS: return tr("Tags");
default:
return QVariant();
@ -189,8 +190,9 @@ QVariant RsMessageModel::headerData(int section, Qt::Orientation /*orientation*/
{
case COLUMN_THREAD_ATTACHMENT: return tr("Click to sort by attachments");
case COLUMN_THREAD_SUBJECT: return tr("Click to sort by subject");
case COLUMN_THREAD_READ: return tr("Click to sort by read");
case COLUMN_THREAD_AUTHOR: return tr("Click to sort by from");
case COLUMN_THREAD_READ: return tr("Click to sort by read status");
case COLUMN_THREAD_AUTHOR: return tr("Click to sort by author");
case COLUMN_THREAD_TO: return tr("Click to sort by destination");
case COLUMN_THREAD_DATE: return tr("Click to sort by date");
case COLUMN_THREAD_TAGS: return tr("Click to sort by tags");
case COLUMN_THREAD_STAR: return tr("Click to sort by star");
@ -269,7 +271,7 @@ QVariant RsMessageModel::data(const QModelIndex &index, int role) const
case MsgFlagsRole: return fmpe.msgflags ;
case UnreadRole: return fmpe.msgflags & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER);
case MsgIdRole: return QString::fromStdString(fmpe.msgId) ;
case SrcIdRole: return QString::fromStdString(fmpe.srcId.toStdString()) ;
case SrcIdRole: return QString::fromStdString(fmpe.from.toStdString()) ;
default:
return QVariant();
}
@ -312,6 +314,11 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int /*col
if(s.isNull())
passes_strings = false;
break;
case FILTER_TYPE_TO: s = sortRole(fmpe,COLUMN_THREAD_TO).toString();
if(s.isNull())
passes_strings = false;
break;
case FILTER_TYPE_DATE: s = displayRole(fmpe,COLUMN_THREAD_DATE).toString();
break;
case FILTER_TYPE_CONTENT: {
@ -390,15 +397,18 @@ void RsMessageModel::setFilter(FilterType filter_type, const QStringList& string
QVariant RsMessageModel::toolTipRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const
{
if(column == COLUMN_THREAD_AUTHOR)
if(column == COLUMN_THREAD_AUTHOR || column == COLUMN_THREAD_TO)
{
QString str,comment ;
QList<QIcon> icons;
if(!GxsIdDetails::MakeIdDesc(RsGxsId(fmpe.srcId.toStdString()), true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
if(column == COLUMN_THREAD_AUTHOR && !GxsIdDetails::MakeIdDesc(RsGxsId(fmpe.from.toStdString()), true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
return QVariant();
int S = QFontMetricsF(QApplication::font()).height();
if(column == COLUMN_THREAD_TO && !GxsIdDetails::MakeIdDesc(RsGxsId(fmpe.to.toStdString()), true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
return QVariant();
int S = QFontMetricsF(QApplication::font()).height();
QImage pix( (*icons.begin()).pixmap(QSize(5*S,5*S)).toImage());
QString embeddedImage;
@ -429,7 +439,8 @@ QVariant RsMessageModel::sizeHintRole(int col) const
case COLUMN_THREAD_SUBJECT: return QVariant( QSize(factor * 170, factor*14 ));
case COLUMN_THREAD_DATE: return QVariant( QSize(factor * 75 , factor*14 ));
case COLUMN_THREAD_AUTHOR: return QVariant( QSize(factor * 75 , factor*14 ));
}
case COLUMN_THREAD_TO: return QVariant( QSize(factor * 75 , factor*14 ));
}
}
QVariant RsMessageModel::authorRole(const Rs::Msgs::MsgInfoSummary& /*fmpe*/,int /*column*/) const
@ -449,10 +460,18 @@ QVariant RsMessageModel::sortRole(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
case COLUMN_THREAD_SPAM: return QVariant((fmpe.msgflags & RS_MSG_SPAM)? 1:0);
case COLUMN_THREAD_AUTHOR:{
case COLUMN_THREAD_TO: {
QString name;
if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.to.toStdString()),name))
return name;
return ""; //Not Found
}
case COLUMN_THREAD_AUTHOR:{
QString name;
if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.srcId.toStdString()),name))
if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.from.toStdString()),name))
return name;
return ""; //Not Found
}
@ -463,70 +482,111 @@ QVariant RsMessageModel::sortRole(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
QVariant RsMessageModel::displayRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col) const
{
switch(col)
{
case COLUMN_THREAD_SUBJECT: return QVariant(QString::fromUtf8(fmpe.title.c_str()));
case COLUMN_THREAD_ATTACHMENT:return QVariant(QString::number(fmpe.count));
switch(col)
{
case COLUMN_THREAD_SUBJECT: return QVariant(QString::fromUtf8(fmpe.title.c_str()));
case COLUMN_THREAD_ATTACHMENT:return QVariant(QString::number(fmpe.count));
case COLUMN_THREAD_STAR:
case COLUMN_THREAD_SPAM:
case COLUMN_THREAD_READ:return QVariant();
case COLUMN_THREAD_DATE:{
QDateTime qtime;
qtime.setTime_t(fmpe.ts);
case COLUMN_THREAD_STAR:
case COLUMN_THREAD_SPAM:
case COLUMN_THREAD_READ:return QVariant();
case COLUMN_THREAD_DATE:{
QDateTime qtime;
qtime.setTime_t(fmpe.ts);
return QVariant(DateTime::formatDateTime(qtime));
}
return QVariant(DateTime::formatDateTime(qtime));
}
case COLUMN_THREAD_TAGS:{
// Tags
Rs::Msgs::MsgTagInfo tagInfo;
rsMsgs->getMessageTag(fmpe.msgId, tagInfo);
case COLUMN_THREAD_TAGS:{
// Tags
Rs::Msgs::MsgTagInfo tagInfo;
rsMsgs->getMessageTag(fmpe.msgId, tagInfo);
Rs::Msgs::MsgTagType Tags;
rsMsgs->getMessageTagTypes(Tags);
Rs::Msgs::MsgTagType Tags;
rsMsgs->getMessageTagTypes(Tags);
QString text;
QString text;
// build tag names
for (auto tagit = tagInfo.tagIds.begin(); tagit != tagInfo.tagIds.end(); ++tagit)
{
if (!text.isNull())
text += ",";
// build tag names
for (auto tag:tagInfo)
{
if (!text.isNull())
text += ",";
auto Tag = Tags.types.find(*tagit);
auto Tag = Tags.types.find(tag);
if (Tag != Tags.types.end())
text += TagDefs::name(Tag->first, Tag->second.first);
else
RS_WARN("Unknown tag ", (int)Tag->first, " in message ", fmpe.msgId);
}
return text;
}
case COLUMN_THREAD_AUTHOR:{
QString name;
RsGxsId id = RsGxsId(fmpe.srcId.toStdString());
if (Tag != Tags.types.end())
text += TagDefs::name(Tag->first, Tag->second.first);
else
RS_WARN("Unknown tag ", (int)Tag->first, " in message ", fmpe.msgId);
}
return text;
}
case COLUMN_THREAD_TO: {
QString name;
if(id.isNull())
return QVariant(tr("[Notification]"));
if(GxsIdTreeItemDelegate::computeName(id,name))
return name;
return QVariant(tr("[Unknown]"));
}
switch(mCurrentBox)
{
case Rs::Msgs::BoxName::BOX_DRAFTS: // in this case, we display the full list of destinations
case Rs::Msgs::BoxName::BOX_TRASH: // in this case, we display the full list of destinations
case Rs::Msgs::BoxName::BOX_SENT: // in this case, we display the full list of destinations
{
for(auto d:fmpe.destinations)
{
QString tmp;
GxsIdTreeItemDelegate::computeName(RsGxsId(d.toStdString()),tmp); // not nice, but works.
if(tmp.isNull())
name += QString(tr("[Notification]") + ", ");
else
name += tmp + ", " ;
}
name.chop(2);
return name;
}
break;
case Rs::Msgs::BoxName::BOX_NONE: // in these cases, we display the actual destination
case Rs::Msgs::BoxName::BOX_INBOX: // in these cases, we display the actual destination
case Rs::Msgs::BoxName::BOX_OUTBOX:
{
RsGxsId id = RsGxsId(fmpe.to.toStdString()); // use "to" field, which is populated in Outbox, .
if(id.isNull())
return QVariant(tr("[Notification]"));
else
{
GxsIdTreeItemDelegate::computeName(id,name);
return name;
}
}
break;
}
}
break;
default:
return QVariant("[ TODO ]");
}
case COLUMN_THREAD_AUTHOR:{
QString name;
RsGxsId id = RsGxsId(fmpe.from.toStdString());
return QVariant("[ERROR]");
if(id.isNull())
return QVariant(tr("[Notification]"));
if(GxsIdTreeItemDelegate::computeName(id,name))
return name;
return QVariant(tr("[Unknown]"));
}
default:
return QVariant("[ TODO ]");
}
return QVariant("[ERROR]");
}
QVariant RsMessageModel::userRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col) const
{
switch(col)
{
case COLUMN_THREAD_AUTHOR: return QVariant(QString::fromStdString(fmpe.srcId.toStdString()));
case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(fmpe.msgId));
case COLUMN_THREAD_AUTHOR: return QVariant(QString::fromStdString(fmpe.from.toStdString()));
case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(fmpe.msgId));
case COLUMN_THREAD_TO: return QVariant(QString::fromStdString(fmpe.to.toStdString()));
default:
return QVariant();
}
@ -569,8 +629,10 @@ QVariant RsMessageModel::decorationRole(const Rs::Msgs::MsgInfoSummary& fmpe,int
case COLUMN_THREAD_SPAM:
return FilesDefs::getIconFromQtResourcePath((fmpe.msgflags & RS_MSG_SPAM) ? (IMAGE_SPAM_ON ): (IMAGE_SPAM_OFF));
case COLUMN_THREAD_AUTHOR://Return icon as place holder.
return FilesDefs::getIconFromGxsIdCache(RsGxsId(fmpe.srcId.toStdString()),QIcon(), exist);
case COLUMN_THREAD_TO://Return icon as place holder.
return FilesDefs::getIconFromGxsIdCache(RsGxsId(fmpe.to.toStdString()),QIcon(), exist);
case COLUMN_THREAD_AUTHOR://Return icon as place holder.
return FilesDefs::getIconFromGxsIdCache(RsGxsId(fmpe.from.toStdString()),QIcon(), exist);
}
return QVariant();
}
@ -597,7 +659,7 @@ void RsMessageModel::setMessages(const std::list<Rs::Msgs::MsgInfoSummary>& msgs
for(auto it(msgs.begin());it!=msgs.end();++it)
{
mMessagesMap[(*it).msgId] = mMessages.size();
mMessages.push_back(*it);
mMessages.push_back(*it);
}
// now update prow for all posts
@ -615,7 +677,7 @@ void RsMessageModel::setMessages(const std::list<Rs::Msgs::MsgInfoSummary>& msgs
emit messagesLoaded();
}
void RsMessageModel::setCurrentBox(BoxName bn)
void RsMessageModel::setCurrentBox(Rs::Msgs::BoxName bn)
{
if(mCurrentBox != bn)
{
@ -632,47 +694,20 @@ void RsMessageModel::setQuickViewFilter(QuickViewFilter fn)
std::cerr << "Changing new quickview filter to " << fn << std::endl;
#endif
mQuickViewFilter = fn ;
updateMessages();
mQuickViewFilter = fn ;
if(rowCount() > 0)
emit dataChanged(createIndex(0,0),createIndex(rowCount()-1,RsMessageModel::columnCount()-1));
}
}
void RsMessageModel::getMessageSummaries(BoxName box,std::list<Rs::Msgs::MsgInfoSummary>& msgs)
{
rsMsgs->getMessageSummaries(msgs);
// filter out messages that are not in the right box.
for(auto it(msgs.begin());it!=msgs.end();)
{
bool ok = false;
switch(box)
{
case BOX_INBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_INBOX && !(it->msgflags & RS_MSG_TRASH); break ;
case BOX_SENT : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_SENTBOX && !(it->msgflags & RS_MSG_TRASH); break ;
case BOX_OUTBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_OUTBOX && !(it->msgflags & RS_MSG_TRASH); break ;
case BOX_DRAFTS : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_DRAFTBOX && !(it->msgflags & RS_MSG_TRASH); break ;
case BOX_TRASH : ok = (it->msgflags & RS_MSG_TRASH) ; break ;
default:
++it;
continue;
}
if(ok)
++it;
else
it = msgs.erase(it) ;
}
}
void RsMessageModel::updateMessages()
{
emit messagesAboutToLoad();
std::list<Rs::Msgs::MsgInfoSummary> msgs;
getMessageSummaries(mCurrentBox,msgs);
rsMsgs->getMessageSummaries(mCurrentBox,msgs);
setMessages(msgs);
emit messagesLoaded();

View File

@ -43,28 +43,20 @@ public:
explicit RsMessageModel(QObject *parent = NULL);
~RsMessageModel(){}
enum BoxName {
BOX_NONE = 0x00,
BOX_INBOX = 0x01,
BOX_OUTBOX = 0x02,
BOX_DRAFTS = 0x03,
BOX_SENT = 0x04,
BOX_TRASH = 0x05
};
enum Columns {
COLUMN_THREAD_STAR = 0x00,
COLUMN_THREAD_ATTACHMENT = 0x01,
COLUMN_THREAD_SUBJECT = 0x02,
COLUMN_THREAD_READ = 0x03,
COLUMN_THREAD_AUTHOR = 0x04,
COLUMN_THREAD_SPAM = 0x05,
COLUMN_THREAD_DATE = 0x06,
COLUMN_THREAD_TAGS = 0x07,
COLUMN_THREAD_MSGID = 0x08,
COLUMN_THREAD_NB_COLUMNS = 0x09,
COLUMN_THREAD_CONTENT = 0x09
};
COLUMN_THREAD_TO = 0x05,
COLUMN_THREAD_SPAM = 0x06,
COLUMN_THREAD_DATE = 0x07,
COLUMN_THREAD_TAGS = 0x08,
COLUMN_THREAD_MSGID = 0x09,
COLUMN_THREAD_CONTENT = 0x0a,
COLUMN_THREAD_NB_COLUMNS = 0x0b
};
enum QuickViewFilter {
QUICK_VIEW_ALL = 0x00,
@ -84,10 +76,11 @@ public:
FILTER_TYPE_NONE = 0x00,
FILTER_TYPE_SUBJECT = 0x01, // These numbers have been carefuly chosen to match the ones in rsmsgs.h
FILTER_TYPE_FROM = 0x02,
FILTER_TYPE_DATE = 0x03,
FILTER_TYPE_CONTENT = 0x04,
FILTER_TYPE_TAGS = 0x05,
FILTER_TYPE_ATTACHMENTS = 0x06,
FILTER_TYPE_TO = 0x03,
FILTER_TYPE_DATE = 0x04,
FILTER_TYPE_CONTENT = 0x05,
FILTER_TYPE_TAGS = 0x06,
FILTER_TYPE_ATTACHMENTS = 0x07,
};
enum Roles{ SortRole = Qt::UserRole+1,
@ -103,11 +96,10 @@ public:
QModelIndex getIndexOfMessage(const std::string &mid) const;
static const QString FilterString ;
static void getMessageSummaries(BoxName box, std::list<Rs::Msgs::MsgInfoSummary>& msgs);
// This method will asynchroneously update the data
void setCurrentBox(BoxName bn) ;
void setCurrentBox(Rs::Msgs::BoxName bn) ;
void setQuickViewFilter(QuickViewFilter fn) ;
void setFilter(FilterType filter_type, const QStringList& strings) ;
@ -187,7 +179,7 @@ private:
QColor mTextColorNotSubscribed ;
QColor mTextColorMissing ;
BoxName mCurrentBox ;
Rs::Msgs::BoxName mCurrentBox ;
QuickViewFilter mQuickViewFilter ;
QStringList mFilterStrings;
FilterType mFilterType;

View File

@ -391,7 +391,8 @@ void MessageWidget::getcurrentrecommended()
}
std::list<RsPeerId> srcIds;
srcIds.push_back(msgInfo.rspeerid_srcId);
if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
srcIds.push_back(msgInfo.from.toRsPeerId());
QModelIndexList list = ui.msgList->selectionModel()->selectedIndexes();
@ -439,7 +440,10 @@ void MessageWidget::getallrecommended()
for(it = recList.begin(); it != recList.end(); ++it) {
std::cerr << "MessageWidget::getallrecommended() Calling File Request" << std::endl;
std::list<RsPeerId> srcIds;
srcIds.push_back(msgInfo.rspeerid_srcId);
if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
srcIds.push_back(msgInfo.from.toRsPeerId());
rsFiles->FileRequest(it->fname, it->hash, it->size, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds);
}
}
@ -471,15 +475,17 @@ void MessageWidget::showTagLabels()
MsgTagInfo tagInfo;
rsMail->getMessageTag(currMsgId, tagInfo);
if (tagInfo.tagIds.empty() == false) {
if (!tagInfo.empty())
{
ui.tagsLabel->setVisible(true);
MsgTagType Tags;
rsMail->getMessageTagTypes(Tags);
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (std::list<uint32_t>::iterator tagId = tagInfo.tagIds.begin(); tagId != tagInfo.tagIds.end(); ++tagId) {
Tag = Tags.types.find(*tagId);
for (auto tag:tagInfo)
{
Tag = Tags.types.find(tag);
if (Tag != Tags.types.end()) {
QLabel *tagLabel = new QLabel(TagDefs::name(Tag->first, Tag->second.first), this);
tagLabel->setMaximumHeight(16);
@ -565,17 +571,21 @@ void MessageWidget::fill(const std::string &msgId)
return;
}
if ((msgInfo.msgflags & RS_MSG_USER_REQUEST) && msgInfo.rsgxsid_srcId.isNull()){
ui.info_Frame_Invite->show();
ui.sendInviteButton->hide();
ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request."));
} else if ((msgInfo.msgflags & RS_MSG_USER_REQUEST) && (!msgInfo.rsgxsid_srcId.isNull())){
ui.info_Frame_Invite->show();
ui.sendInviteButton->show();
ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request and send your own Certificate back"));
} else {
ui.info_Frame_Invite->hide();
}
if (msgInfo.msgflags & RS_MSG_USER_REQUEST)
if(msgInfo.from.type() == MsgAddress::MSG_ADDRESS_TYPE_RSPEERID)
{
ui.info_Frame_Invite->show();
ui.sendInviteButton->hide();
ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request."));
}
else
{
ui.info_Frame_Invite->show();
ui.sendInviteButton->show();
ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request and send your own Certificate back"));
}
else
ui.info_Frame_Invite->hide();
const std::list<FileInfo> &recList = msgInfo.files;
std::list<FileInfo>::const_iterator it;
@ -604,63 +614,45 @@ void MessageWidget::fill(const std::string &msgId)
/* iterate through the sources */
RetroShareLink link;
QString text;
QString to_text,cc_text,bcc_text;
for(auto m:msgInfo.destinations)
{
if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
link = RetroShareLink::createMessage(m.toGxsId(), "");
else
link = RetroShareLink::createMessage(m.toRsPeerId(), "");
for(std::set<RsPeerId>::const_iterator pit = msgInfo.rspeerid_msgto.begin(); pit != msgInfo.rspeerid_msgto.end(); ++pit) {
link = RetroShareLink::createMessage(*pit, "");
if (link.valid())
text += link.toHtml() + " ";
}
for(std::set<RsGxsId >::const_iterator pit = msgInfo.rsgxsid_msgto.begin(); pit != msgInfo.rsgxsid_msgto.end(); ++pit) {
link = RetroShareLink::createMessage(*pit, "");
if (link.valid())
text += link.toHtml() + " ";
}
switch(m.mode())
{
case MsgAddress::MSG_ADDRESS_MODE_TO: to_text += link.toHtml() + " "; break;
case MsgAddress::MSG_ADDRESS_MODE_CC: cc_text += link.toHtml() + " "; break;
case MsgAddress::MSG_ADDRESS_MODE_BCC: bcc_text += link.toHtml() + " "; break;
default: break;
}
}
ui.trans_ToText->setText(text);
ui.trans_ToText->setText(to_text);
if (!msgInfo.rspeerid_msgcc.empty() || !msgInfo.rsgxsid_msgcc.empty())
if (!cc_text.isNull())
{
ui.ccLabel->setVisible(true);
ui.trans_CCText->setVisible(true);
text.clear();
for(std::set<RsPeerId>::const_iterator pit = msgInfo.rspeerid_msgcc.begin(); pit != msgInfo.rspeerid_msgcc.end(); ++pit) {
link = RetroShareLink::createMessage(*pit, "");
if (link.valid())
text += link.toHtml() + " ";
}
for(std::set<RsGxsId>::const_iterator pit = msgInfo.rsgxsid_msgcc.begin(); pit != msgInfo.rsgxsid_msgcc.end(); ++pit) {
link = RetroShareLink::createMessage(*pit, "");
if (link.valid())
text += link.toHtml() + " ";
}
ui.trans_CCText->setText(text);
ui.trans_CCText->setText(cc_text);
} else {
ui.ccLabel->setVisible(false);
ui.trans_CCText->setVisible(false);
ui.trans_CCText->clear();
}
if (!msgInfo.rspeerid_msgbcc.empty() || !msgInfo.rsgxsid_msgbcc.empty())
if (!bcc_text.isNull())
{
ui.bccLabel->setVisible(true);
ui.trans_BCCText->setVisible(true);
text.clear();
for(std::set<RsPeerId>::const_iterator pit = msgInfo.rspeerid_msgbcc.begin(); pit != msgInfo.rspeerid_msgbcc.end(); ++pit) {
link = RetroShareLink::createMessage(*pit, "");
if (link.valid())
text += link.toHtml() + " ";
}
for(std::set<RsGxsId>::const_iterator pit = msgInfo.rsgxsid_msgbcc.begin(); pit != msgInfo.rsgxsid_msgbcc.end(); ++pit) {
link = RetroShareLink::createMessage(*pit, "");
if (link.valid())
text += link.toHtml() + " ";
}
ui.trans_BCCText->setText(text);
ui.trans_BCCText->setText(bcc_text);
} else {
ui.bccLabel->setVisible(false);
ui.trans_BCCText->setVisible(false);
@ -678,21 +670,24 @@ void MessageWidget::fill(const std::string &msgId)
// link.createMessage(ownId, "");
// }
if(msgInfo.msgflags & RS_MSG_DISTANT) // distant message
if(msgInfo.from.type()==Rs::Msgs::MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) // distant message
{
tooltip_string = PeerDefs::rsidFromId(msgInfo.rsgxsid_srcId) ;
link = RetroShareLink::createMessage(msgInfo.rsgxsid_srcId, "");
tooltip_string = PeerDefs::rsidFromId(msgInfo.from.toGxsId()) ;
link = RetroShareLink::createMessage(msgInfo.from.toGxsId(), "");
}
else
{
tooltip_string = PeerDefs::rsidFromId(msgInfo.rspeerid_srcId) ;
link = RetroShareLink::createMessage(msgInfo.rspeerid_srcId, "");
tooltip_string = PeerDefs::rsidFromId(msgInfo.from.toRsPeerId()) ;
link = RetroShareLink::createMessage(msgInfo.from.toRsPeerId(), "");
}
if (((msgInfo.msgflags & RS_MSG_SYSTEM) && msgInfo.rspeerid_srcId == ownId) || msgInfo.rspeerid_srcId.isNull()) {
if ((msgInfo.msgflags & RS_MSG_SYSTEM) && msgInfo.from.toRsPeerId() == ownId)
{
ui.fromText->setText("[Notification]");
if (toolButtonReply) toolButtonReply->setEnabled(false);
} else {
}
else
{
ui.fromText->setText(link.toHtml());
ui.fromText->setToolTip(tooltip_string) ;
if (toolButtonReply) toolButtonReply->setEnabled(true);
@ -706,7 +701,7 @@ void MessageWidget::fill(const std::string &msgId)
if (Settings->valueFromGroup(QString("Messages"), QString::fromUtf8("Emoticons"), true).toBool()) {
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS ;
}
text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), formatTextFlag);
QString text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), formatTextFlag);
ui.msgText->resetImagesStatus(Settings->getMsgLoadEmbeddedImages() || (msgInfo.msgflags & RS_MSG_LOAD_EMBEDDED_IMAGES));
ui.msgText->setHtml(text);
@ -883,19 +878,21 @@ void MessageWidget::loadImagesAlways()
void MessageWidget::sendInvite()
{
MessageInfo mi;
MessageInfo mi;
if (!rsMail)
return;
if (!rsMail)
return;
if (!rsMail->getMessage(currMsgId, mi))
return;
if (!rsMail->getMessage(currMsgId, mi))
return;
//if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
//{
MessageComposer::sendInvite(mi.rsgxsid_srcId,false);
//}
if(mi.from.type()!=MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
return;
if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Cancel))== QMessageBox::Yes)
{
MessageComposer::sendInvite(mi.from.toGxsId(),false);
}
}
void MessageWidget::setToolbarButtonStyle(Qt::ToolButtonStyle style)

View File

@ -150,7 +150,7 @@ void MessageWindow::tagAboutToShow()
MsgTagInfo tagInfo;
rsMail->getMessageTag(msgWidget->msgId(), tagInfo);
menu->activateActions(tagInfo.tagIds);
menu->activateActions(tagInfo);
}
void MessageWindow::tagRemoveAll()

View File

@ -140,6 +140,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
inChange = false;
lockUpdate = 0;
lastSelectedIndex = QModelIndex();
mLastCurrentQuickViewRow = -1;
msgWidget = new MessageWidget(true, this);
ui.msgLayout->addWidget(msgWidget);
@ -147,7 +148,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
connectActions();
listMode = LIST_NOTHING;
//listMode = LIST_NOTHING;
mMessageModel = new RsMessageModel(this);
mMessageProxyModel = new MessageSortFilterProxyModel(this);
@ -166,6 +167,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
ui.messageTreeWidget->setItemDelegateForColumn(RsMessageModel::COLUMN_THREAD_SUBJECT,itemDelegate);
ui.messageTreeWidget->setItemDelegateForColumn(RsMessageModel::COLUMN_THREAD_AUTHOR,new GxsIdTreeItemDelegate()) ;
ui.messageTreeWidget->setItemDelegateForColumn(RsMessageModel::COLUMN_THREAD_TO,new GxsIdTreeItemDelegate()) ;
// workaround for Qt bug, should be solved in next Qt release 4.7.0
// http://bugreports.qt.nokia.com/browse/QTBUG-8270
@ -190,6 +192,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
/* add filter actions */
ui.filterLineEdit->addFilter(QIcon(), tr("Subject"), RsMessageModel::COLUMN_THREAD_SUBJECT, tr("Search Subject"));
ui.filterLineEdit->addFilter(QIcon(), tr("From"), RsMessageModel::COLUMN_THREAD_AUTHOR, tr("Search From"));
ui.filterLineEdit->addFilter(QIcon(), tr("To"), RsMessageModel::COLUMN_THREAD_TO, tr("Search To"));
ui.filterLineEdit->addFilter(QIcon(), tr("Date"), RsMessageModel::COLUMN_THREAD_DATE, tr("Search Date"));
ui.filterLineEdit->addFilter(QIcon(), tr("Content"), RsMessageModel::COLUMN_THREAD_CONTENT, tr("Search Content"));
ui.filterLineEdit->addFilter(QIcon(), tr("Tags"), RsMessageModel::COLUMN_THREAD_TAGS, tr("Search Tags"));
@ -212,16 +215,18 @@ MessagesDialog::MessagesDialog(QWidget *parent)
msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_SUBJECT, fm.width("You have a message")*3.0);
msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_AUTHOR, fm.width("[Retroshare]")*1.1);
msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_TO, fm.width("[Retroshare]")*1.1);
msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_DATE, fm.width("01/01/1970")*1.1);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_SUBJECT, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_AUTHOR, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_DATE, QHeaderView::Interactive);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_SUBJECT, QHeaderView::Interactive);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_AUTHOR, QHeaderView::Interactive);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_TO, QHeaderView::Interactive);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_DATE, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_STAR, QHeaderView::Fixed);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_ATTACHMENT, QHeaderView::Fixed);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_READ, QHeaderView::Fixed);
QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_SPAM, QHeaderView::Fixed);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_STAR, QHeaderView::Fixed);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_ATTACHMENT, QHeaderView::Fixed);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_READ, QHeaderView::Fixed);
msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_SPAM, QHeaderView::Fixed);
ui.messageTreeWidget->setSortingEnabled(true);
@ -249,9 +254,6 @@ MessagesDialog::MessagesDialog(QWidget *parent)
sortColumn(RsMessageModel::COLUMN_THREAD_DATE,Qt::DescendingOrder);
// load settings
processSettings(true);
//ui.messageTreeWidget->installEventFilter(this);
// remove close button of the the first tab
@ -280,10 +282,10 @@ MessagesDialog::MessagesDialog(QWidget *parent)
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCustomPopupMenu(QPoint)));
connect(ui.listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeBox(int)));
connect(ui.quickViewWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeQuickView(int)));
connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(newmessage()));
connect(ui.quickViewWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(resetQuickView(const QModelIndex&)));
connect(ui.messageTreeWidget, SIGNAL(clicked(const QModelIndex&)) , this, SLOT(clicked(const QModelIndex&)));
connect(ui.messageTreeWidget, SIGNAL(doubleClicked(const QModelIndex&)) , this, SLOT(doubleClicked(const QModelIndex&)));
@ -293,6 +295,11 @@ MessagesDialog::MessagesDialog(QWidget *parent)
connect(ui.messageTreeWidget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)), this, SLOT(currentChanged(const QModelIndex&,const QModelIndex&)));
// load settings
processSettings(true);
ui.listWidget->setCurrentRow(0); // always starts with inbox => allows to setup the proper number of columns
mEventHandlerId=0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS );
@ -375,12 +382,15 @@ void MessagesDialog::postModelUpdate()
sel.select(i.sibling(i.row(),0),i.sibling(i.row(),RsMessageModel::COLUMN_THREAD_NB_COLUMNS-1));
}
ui.messageTreeWidget->selectionModel()->select(sel,QItemSelectionModel::SelectCurrent);
// Restoring selection should not trigger anything, especially the re-display of the msg, which
// in turn will change the read status.
whileBlocking(ui.messageTreeWidget->selectionModel())->select(sel,QItemSelectionModel::SelectCurrent);
if (!mTmpSavedCurrentId.isEmpty()) {
QModelIndex index = mMessageProxyModel->mapFromSource(mMessageModel->getIndexOfMessage(mTmpSavedCurrentId.toStdString()));
if (index.isValid()) {
ui.messageTreeWidget->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
whileBlocking(ui.messageTreeWidget->selectionModel())->setCurrentIndex(index, QItemSelectionModel::Select);
}
}
}
@ -497,7 +507,7 @@ void MessagesDialog::fillQuickView()
ui.quickViewWidget->clear();
// add static items
item = new QListWidgetItem(tr("Starred"), ui.quickViewWidget);
item = new QListWidgetItem(tr("Stared"), ui.quickViewWidget);
item->setIcon(FilesDefs::getIconFromQtResourcePath(IMAGE_STAR_ON));
item->setData(ROLE_QUICKVIEW_TYPE, QUICKVIEW_TYPE_STATIC);
item->setData(ROLE_QUICKVIEW_ID, QUICKVIEW_STATIC_ID_STARRED);
@ -749,12 +759,12 @@ void MessagesDialog::messageTreeWidgetCustomPopupMenu(QPoint /*point*/)
// test if identity is known. If not, no need to call the people tab. Also some mails come from nodes and we wont show that node in the people tab either.
// The problem here is that the field rsgxsid_srcId is always populated with either the GxsId or the node of the source, which is inconsistent.
if(nCount==1 && rsIdentity->getIdDetails(msgInfo.rsgxsid_srcId,details))
if(nCount==1 && msgInfo.from.type() == MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
{
std::cerr << "Src ID = " << msgInfo.rsgxsid_srcId << std::endl;
std::cerr << "Src ID = " << msgInfo.from.toGxsId() << std::endl;
contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR_INFO),tr("Show author in People"),this,SLOT(showAuthorInPeopleTab()));
contextMnu.addSeparator();
contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR_INFO),tr("Show in People"),this,SLOT(showAuthorInPeopleTab()));
contextMnu.addSeparator();
}
contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_MESSAGE), tr("New Message"), this, SLOT(newmessage()));
@ -774,7 +784,7 @@ void MessagesDialog::showAuthorInPeopleTab()
if (!rsMail->getMessage(mid, msgInfo))
return;
if(msgInfo.rsgxsid_srcId.isNull())
if(msgInfo.from.type() != MsgAddress::MSG_ADDRESS_TYPE_RSGXSID)
return ;
/* window will destroy itself! */
@ -784,7 +794,7 @@ void MessagesDialog::showAuthorInPeopleTab()
return ;
MainWindow::showWindow(MainWindow::People);
idDialog->navigate(RsGxsId(msgInfo.rsgxsid_srcId)) ;
idDialog->navigate(RsGxsId(msgInfo.from.toGxsId())) ;
}
void MessagesDialog::folderlistWidgetCustomPopupMenu(QPoint /*point*/)
@ -886,54 +896,76 @@ void MessagesDialog::changeBox(int box_row)
if (item)
{
ui.quickViewWidget->setCurrentItem(NULL);
changeQuickView(-1);
listMode = LIST_BOX;
changeQuickView(-1);
//listMode = LIST_BOX;
QString placeholderText = tr("No message available in your %1.").arg(item->text());
switch(box_row)
{
case ROW_INBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_INBOX );
case ROW_INBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_INBOX );
break;
case ROW_OUTBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_OUTBOX);
break;
case ROW_OUTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_OUTBOX);
case ROW_DRAFTBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_DRAFTS);
break;
case ROW_DRAFTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_DRAFTS);
case ROW_SENTBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_SENT );
break;
case ROW_SENTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_SENT );
break;
case ROW_TRASHBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_TRASH );
case ROW_TRASHBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_TRASH );
break;
default:
mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE);
mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_NONE);
}
insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
ui.messageTreeWidget->setPlaceholderText(placeholderText);
}
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_READ,box_row!=ROW_INBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_STAR,box_row==ROW_OUTBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_SPAM,box_row==ROW_OUTBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_TAGS,box_row==ROW_OUTBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_MSGID,true);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_CONTENT,true);
}
else
{
mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE);
mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_NONE);
}
inChange = false;
updateMessageSummaryList();
}
void MessagesDialog::resetQuickView(const QModelIndex& i)
{
if(!i.isValid())
return;
int n = ui.quickViewWidget->currentRow();
if(mLastCurrentQuickViewRow == n)
{
changeQuickView(-1);
ui.quickViewWidget->setCurrentRow(-1);
}
else
changeQuickView(n);
}
void MessagesDialog::changeQuickView(int newrow)
{
mLastCurrentQuickViewRow = newrow;
RsMessageModel::QuickViewFilter f = RsMessageModel::QUICK_VIEW_ALL ;
QListWidgetItem* item = ui.quickViewWidget->item(newrow);
if(item )
{
ui.listWidget->setCurrentItem(NULL);
changeBox(-1);
listMode = LIST_QUICKVIEW;
//ui.listWidget->setCurrentItem(NULL);
//changeBox(-1);
//listMode = LIST_QUICKVIEW;
QString placeholderText;
switch (item->data(ROLE_QUICKVIEW_TYPE).toInt()) {
switch (item->data(ROLE_QUICKVIEW_TYPE).toInt())
{
case QUICKVIEW_TYPE_TAG:
{
placeholderText = tr("No message using %1 tag available.").arg(item->data(ROLE_QUICKVIEW_TEXT).toString());
@ -958,12 +990,12 @@ void MessagesDialog::changeQuickView(int newrow)
}
}
insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
//insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
ui.messageTreeWidget->setPlaceholderText(placeholderText);
}
mMessageModel->setQuickViewFilter(f);
mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model
mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model
}
// click in messageTreeWidget
@ -989,21 +1021,16 @@ void MessagesDialog::clicked(const QModelIndex& proxy_index)
case RsMessageModel::COLUMN_THREAD_READ:
{
mMessageModel->setMsgReadStatus(real_index, !isMessageRead(proxy_index));
//Already updated by currentChanged
//insertMsgTxtAndFiles(proxy_index);
updateMessageSummaryList();
return;
}
case RsMessageModel::COLUMN_THREAD_STAR:
{
mMessageModel->setMsgStar(real_index, !hasMessageStar(proxy_index));
updateMessageSummaryList();
return;
}
case RsMessageModel::COLUMN_THREAD_SPAM:
{
mMessageModel->setMsgJunk(real_index, !hasMessageSpam(proxy_index));
updateMessageSummaryList();
return;
}
}
@ -1149,12 +1176,17 @@ void MessagesDialog::removemessage()
bool doDelete = false;
int listrow = ui.listWidget->currentRow();
if (listrow == ROW_TRASHBOX) {
if(listrow == ROW_TRASHBOX || (QApplication::keyboardModifiers() & Qt::ShiftModifier))
doDelete = true;
if(listrow == ROW_OUTBOX)
{
if(QMessageBox::question(nullptr,tr("Deletion is not recommended"),tr("Messages in this box are automatically deleted when received. Manually deleting a message does not guaranty that the message will not be delivered. Messages that cannot be delivered will however stay here indefinitly. Do you want to proceed and delete?"))
!= QMessageBox::Yes)
return ;
doDelete = true;
} else {
if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {
doDelete = true;
}
}
foreach (const QString& m, selectedMessages) {
@ -1201,6 +1233,7 @@ void MessagesDialog::filterChanged(const QString& text)
{
case RsMessageModel::COLUMN_THREAD_SUBJECT: f = RsMessageModel::FILTER_TYPE_SUBJECT ; break;
case RsMessageModel::COLUMN_THREAD_AUTHOR: f = RsMessageModel::FILTER_TYPE_FROM ; break;
case RsMessageModel::COLUMN_THREAD_TO: f = RsMessageModel::FILTER_TYPE_TO ; break;
case RsMessageModel::COLUMN_THREAD_DATE: f = RsMessageModel::FILTER_TYPE_DATE ; break;
case RsMessageModel::COLUMN_THREAD_CONTENT: f = RsMessageModel::FILTER_TYPE_CONTENT ; break;
case RsMessageModel::COLUMN_THREAD_TAGS: f = RsMessageModel::FILTER_TYPE_TAGS ; break;
@ -1225,6 +1258,7 @@ void MessagesDialog::filterColumnChanged(int column)
{
case RsMessageModel::COLUMN_THREAD_SUBJECT: f = RsMessageModel::FILTER_TYPE_SUBJECT ; break;
case RsMessageModel::COLUMN_THREAD_AUTHOR: f = RsMessageModel::FILTER_TYPE_FROM ; break;
case RsMessageModel::COLUMN_THREAD_TO: f = RsMessageModel::FILTER_TYPE_TO ; break;
case RsMessageModel::COLUMN_THREAD_DATE: f = RsMessageModel::FILTER_TYPE_DATE ; break;
case RsMessageModel::COLUMN_THREAD_CONTENT: f = RsMessageModel::FILTER_TYPE_CONTENT ; break;
case RsMessageModel::COLUMN_THREAD_TAGS: f = RsMessageModel::FILTER_TYPE_TAGS ; break;
@ -1258,7 +1292,7 @@ void MessagesDialog::updateMessageSummaryList()
/* calculating the new messages */
std::list<MsgInfoSummary> msgList;
rsMail->getMessageSummaries(msgList);
rsMail->getMessageSummaries(Rs::Msgs::BoxName::BOX_ALL,msgList);
QMap<int, int> tagCount;
@ -1274,17 +1308,14 @@ void MessagesDialog::updateMessageSummaryList()
tagCount [*tagId] = nCount;
}
if (it->msgflags & RS_MSG_STAR) {
if (it->msgflags & RS_MSG_STAR)
++starredCount;
}
if (it->msgflags & RS_MSG_SYSTEM) {
if (it->msgflags & RS_MSG_SYSTEM)
++systemCount;
}
if (it->msgflags & RS_MSG_SPAM) {
if (it->msgflags & RS_MSG_SPAM)
++spamCount;
}
/* calculate box */
if (it->msgflags & RS_MSG_TRASH) {
@ -1302,7 +1333,7 @@ void MessagesDialog::updateMessageSummaryList()
case RS_MSG_OUTBOX:
++newOutboxCount;
break;
case RS_MSG_DRAFTBOX:
case RS_MSG_DRAFT: // not RS_MSG_DRAFTBOX because drafts are not considered outgoing
++newDraftCount;
break;
case RS_MSG_SENTBOX:
@ -1339,7 +1370,7 @@ void MessagesDialog::updateMessageSummaryList()
break;
}
std::cerr << "NewInboxCount = " << newInboxCount << " NewDraftCount = " << newDraftCount << std::endl;
QString textItem;
/*updating the labels in leftcolumn*/
@ -1373,7 +1404,7 @@ void MessagesDialog::updateMessageSummaryList()
textItem = tr("Outbox") + " (" + QString::number(newOutboxCount)+")";
item->setText(textItem);
QFont qf = item->font();
qf.setBold(true);
qf.setBold(false);
item->setFont(qf);
}
else
@ -1440,16 +1471,20 @@ void MessagesDialog::updateMessageSummaryList()
QString text = qv_item->data(ROLE_QUICKVIEW_TEXT).toString();
switch (qv_item->data(ROLE_QUICKVIEW_ID).toInt()) {
case QUICKVIEW_STATIC_ID_STARRED:
text += " (" + QString::number(starredCount) + ")";
if(starredCount>0)
text += " (" + QString::number(starredCount) + ")";
break;
case QUICKVIEW_STATIC_ID_SYSTEM:
text += " (" + QString::number(systemCount) + ")";
if(systemCount > 0)
text += " (" + QString::number(systemCount) + ")";
break;
case QUICKVIEW_STATIC_ID_SPAM:
text += " (" + QString::number(spamCount) + ")";
if(spamCount > 0)
text += " (" + QString::number(spamCount) + ")";
break;
case QUICKVIEW_STATIC_ID_ATTACHMENT:
text += " (" + QString::number(attachmentCount) + ")";
if(attachmentCount > 0)
text += " (" + QString::number(attachmentCount) + ")";
break;
}
@ -1463,11 +1498,10 @@ void MessagesDialog::updateMessageSummaryList()
void MessagesDialog::tagAboutToShow()
{
#ifdef TODO
TagsMenu *menu = dynamic_cast<TagsMenu*>(ui.tagButton->menu());
if (menu == NULL) {
if (menu == NULL)
return;
}
// activate actions from the first selected row
MsgTagInfo tagInfo;
@ -1478,8 +1512,7 @@ void MessagesDialog::tagAboutToShow()
if(!msgids.empty())
rsMail->getMessageTag(msgids.front().toStdString(), tagInfo);
menu->activateActions(tagInfo.tagIds);
#endif
menu->activateActions(tagInfo);
}
void MessagesDialog::tagRemoveAll()
@ -1493,9 +1526,8 @@ void MessagesDialog::tagRemoveAll()
void MessagesDialog::tagSet(int tagId, bool set)
{
if (tagId == 0) {
if (tagId == 0)
return;
}
QList<QString> msgids;
getSelectedMessages(msgids);
@ -1507,7 +1539,7 @@ void MessagesDialog::tagSet(int tagId, bool set)
void MessagesDialog::emptyTrash()
{
std::list<Rs::Msgs::MsgInfoSummary> msgs ;
mMessageModel->getMessageSummaries(RsMessageModel::BOX_TRASH,msgs);
rsMsgs->getMessageSummaries(Rs::Msgs::BoxName::BOX_TRASH,msgs);
for(auto it(msgs.begin());it!=msgs.end();++it)
rsMail->MessageDelete(it->msgId);

View File

@ -79,6 +79,7 @@ private slots:
void changeBox(int newrow);
void changeQuickView(int newrow);
void resetQuickView(const QModelIndex& i);
void updateCurrentMessage();
void clicked(const QModelIndex&);
void doubleClicked(const QModelIndex&);
@ -138,9 +139,10 @@ private:
bool inChange;
int lockUpdate; // use with LockUpdate
enum { LIST_NOTHING, LIST_BOX, LIST_QUICKVIEW } listMode;
// enum { LIST_NOTHING, LIST_BOX, LIST_QUICKVIEW } listMode;
std::string mCurrMsgId;
int mLastCurrentQuickViewRow;
// timer and index for showing message
QTimer *timer;

View File

@ -170,7 +170,7 @@ void TagsMenu::fillTags()
addAction(action);
}
void TagsMenu::activateActions(std::list<uint32_t>& tagIds)
void TagsMenu::activateActions(std::set<uint32_t>& tagIds)
{
foreach(QObject *object, children()) {
QAction *action = qobject_cast<QAction*> (object);
@ -186,7 +186,7 @@ void TagsMenu::activateActions(std::list<uint32_t>& tagIds)
continue;
}
std::list<uint32_t>::iterator tagId = std::find(tagIds.begin(), tagIds.end(), values [ACTION_TAGSINDEX_ID]);
auto tagId = std::find(tagIds.begin(), tagIds.end(), values [ACTION_TAGSINDEX_ID]);
action->setChecked(tagId != tagIds.end());
}
}

View File

@ -34,7 +34,7 @@ public:
TagsMenu(const QString &title, QWidget *parent);
virtual ~TagsMenu();
void activateActions(std::list<uint32_t>& tagIds);
void activateActions(std::set<uint32_t> &tagIds);
signals:
void tagSet(int tagId, bool set);