mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
commit
b138263878
@ -111,7 +111,7 @@ public:
|
||||
RsTlvKeySignatureSet signSet;
|
||||
std::string mMsgName;
|
||||
time_t mPublishTs;
|
||||
uint32_t mMsgFlags; // Whats this for?
|
||||
uint32_t mMsgFlags; // used by some services (e.g. by forums to store message moderation flags)
|
||||
|
||||
// BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
|
||||
// normally READ / UNREAD flags. LOCAL Data.
|
||||
|
@ -115,8 +115,7 @@ namespace GXS_SERV {
|
||||
/** START GXS Grp status flags **/
|
||||
|
||||
static const uint32_t GXS_GRP_STATUS_UNPROCESSED = 0x000000100;
|
||||
|
||||
static const uint32_t GXS_GRP_STATUS_UNREAD = 0x00000200;
|
||||
static const uint32_t GXS_GRP_STATUS_UNREAD = 0x000000200;
|
||||
|
||||
/** END GXS Grp status flags **/
|
||||
}
|
||||
|
@ -28,8 +28,15 @@
|
||||
|
||||
#include "retroshare/rstokenservice.h"
|
||||
#include "retroshare/rsgxsifacehelper.h"
|
||||
#include "serialiser/rstlvidset.h"
|
||||
|
||||
// Forum Service message flags, to be used in RsMsgMetaData::mMsgFlags
|
||||
// Gxs imposes to use the first two bytes (lower bytes) of mMsgFlags for private forum flags, the upper bytes being used for internal GXS stuff.
|
||||
|
||||
static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MASK = 0x0000000f ;
|
||||
static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MODERATED = 0x00000001 ;
|
||||
|
||||
#define IS_FORUM_MSG_MODERATION(flags) (flags & RS_GXS_FORUM_MSG_FLAGS_MODERATED)
|
||||
|
||||
/* The Main Interface Class - for information about your Peers */
|
||||
class RsGxsForums;
|
||||
@ -40,6 +47,11 @@ class RsGxsForumGroup
|
||||
public:
|
||||
RsGroupMetaData mMeta;
|
||||
std::string mDescription;
|
||||
|
||||
// What's below is optional, and handled by the serialiser
|
||||
|
||||
RsTlvGxsIdSet mAdminList;
|
||||
RsTlvGxsMsgIdSet mPinnedPosts;
|
||||
};
|
||||
|
||||
class RsGxsForumMsg
|
||||
|
@ -138,7 +138,7 @@ struct RsMsgMetaData : RsSerializable
|
||||
std::string mMsgName;
|
||||
time_t mPublishTs;
|
||||
|
||||
/// the first 16 bits for service, last 16 for GXS
|
||||
/// the lower 16 bits for service, upper 16 bits for GXS
|
||||
uint32_t mMsgFlags;
|
||||
|
||||
// BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
|
||||
|
@ -48,7 +48,16 @@ void RsGxsForumGroupItem::clear()
|
||||
void RsGxsForumGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,mGroup.mDescription,"mGroup.Description");
|
||||
|
||||
// This is for backward compatibility: normally all members are serialized, but in the previous version, these members are missing.
|
||||
|
||||
if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize)
|
||||
return ;
|
||||
|
||||
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mGroup.mAdminList ,"admin_list" ) ;
|
||||
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mGroup.mPinnedPosts,"pinned_posts") ;
|
||||
}
|
||||
|
||||
void RsGxsForumMsgItem::clear()
|
||||
{
|
||||
mMsg.mMsg.clear();
|
||||
|
@ -200,6 +200,7 @@ const uint16_t TLV_TYPE_RECOGNSET = 0x1024;
|
||||
const uint16_t TLV_TYPE_GXSIDSET = 0x1025;
|
||||
const uint16_t TLV_TYPE_GXSCIRCLEIDSET= 0x1026;
|
||||
const uint16_t TLV_TYPE_NODEGROUPIDSET= 0x1027;
|
||||
const uint16_t TLV_TYPE_GXSMSGIDSET = 0x1028;
|
||||
|
||||
const uint16_t TLV_TYPE_SERVICESET = 0x1030;
|
||||
|
||||
|
@ -114,12 +114,13 @@ template<class ID_CLASS,uint32_t TLV_TYPE> class t_RsTlvIdSet: public RsTlvItem
|
||||
std::set<ID_CLASS> ids ;
|
||||
};
|
||||
|
||||
typedef t_RsTlvIdSet<RsPeerId, TLV_TYPE_PEERSET> RsTlvPeerIdSet ;
|
||||
typedef t_RsTlvIdSet<RsPgpId, TLV_TYPE_PGPIDSET> RsTlvPgpIdSet ;
|
||||
typedef t_RsTlvIdSet<Sha1CheckSum, TLV_TYPE_HASHSET> RsTlvHashSet ;
|
||||
typedef t_RsTlvIdSet<RsGxsId, TLV_TYPE_GXSIDSET> RsTlvGxsIdSet ;
|
||||
typedef t_RsTlvIdSet<RsGxsCircleId,TLV_TYPE_GXSCIRCLEIDSET> RsTlvGxsCircleIdSet ;
|
||||
typedef t_RsTlvIdSet<RsNodeGroupId,TLV_TYPE_NODEGROUPIDSET> RsTlvNodeGroupIdSet ;
|
||||
typedef t_RsTlvIdSet<RsPeerId, TLV_TYPE_PEERSET> RsTlvPeerIdSet ;
|
||||
typedef t_RsTlvIdSet<RsPgpId, TLV_TYPE_PGPIDSET> RsTlvPgpIdSet ;
|
||||
typedef t_RsTlvIdSet<Sha1CheckSum, TLV_TYPE_HASHSET> RsTlvHashSet ;
|
||||
typedef t_RsTlvIdSet<RsGxsId, TLV_TYPE_GXSIDSET> RsTlvGxsIdSet ;
|
||||
typedef t_RsTlvIdSet<RsGxsMessageId,TLV_TYPE_GXSMSGIDSET> RsTlvGxsMsgIdSet ;
|
||||
typedef t_RsTlvIdSet<RsGxsCircleId, TLV_TYPE_GXSCIRCLEIDSET> RsTlvGxsCircleIdSet ;
|
||||
typedef t_RsTlvIdSet<RsNodeGroupId, TLV_TYPE_NODEGROUPIDSET> RsTlvNodeGroupIdSet ;
|
||||
|
||||
class RsTlvServiceIdSet: public RsTlvItem
|
||||
{
|
||||
|
@ -26,8 +26,8 @@
|
||||
RsPhoto *rsPhoto = NULL;
|
||||
|
||||
|
||||
const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f;
|
||||
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_POST = 0x0001;
|
||||
const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f;
|
||||
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_POST = 0x0001;
|
||||
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_COMMENT = 0x0002;
|
||||
|
||||
|
||||
|
@ -1539,7 +1539,7 @@ void SharedFilesDialog::FilterItems()
|
||||
if(text.length() < 3)
|
||||
return ;
|
||||
|
||||
FileSearchFlags flags = isRemote()?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL;
|
||||
//FileSearchFlags flags = isRemote()?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL;
|
||||
QStringList lst = text.split(" ",QString::SkipEmptyParts) ;
|
||||
std::list<std::string> keywords ;
|
||||
|
||||
|
@ -32,7 +32,7 @@ const uint32_t PostedCreateEnabledFlags = (
|
||||
GXS_GROUP_FLAGS_DESCRIPTION |
|
||||
GXS_GROUP_FLAGS_DISTRIBUTION |
|
||||
// GXS_GROUP_FLAGS_PUBLISHSIGN |
|
||||
GXS_GROUP_FLAGS_SHAREKEYS |
|
||||
// GXS_GROUP_FLAGS_SHAREKEYS | // disabled because the UI doesn't handle it yet.
|
||||
// GXS_GROUP_FLAGS_PERSONALSIGN |
|
||||
// GXS_GROUP_FLAGS_COMMENTS |
|
||||
0);
|
||||
@ -84,7 +84,7 @@ void PostedGroupDialog::initUi()
|
||||
break;
|
||||
}
|
||||
|
||||
setUiText(UITYPE_KEY_SHARE_CHECKBOX, tr("Add Topic Admins"));
|
||||
setUiText(UITYPE_ADD_ADMINS_CHECKBOX, tr("Add Topic Admins"));
|
||||
setUiText(UITYPE_CONTACTS_DOCK, tr("Select Topic Admins"));
|
||||
}
|
||||
|
||||
|
@ -288,8 +288,14 @@ void FriendSelectionWidget::secured_fillList()
|
||||
}
|
||||
|
||||
std::set<RsGxsId> gxsIdsSelected;
|
||||
|
||||
if (mShowTypes & SHOW_GXS)
|
||||
{
|
||||
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected,true);
|
||||
|
||||
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||
gxsIdsSelected = mPreSelectedGxsIds;
|
||||
}
|
||||
|
||||
std::set<RsGxsId> gxsIdsSelected2;
|
||||
if (mShowTypes & SHOW_CONTACTS)
|
||||
@ -683,6 +689,11 @@ void FriendSelectionWidget::requestGXSIdList()
|
||||
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, IDDIALOG_IDLIST);
|
||||
}
|
||||
|
||||
template<> void FriendSelectionWidget::setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(const std::set<RsGxsId>& ids, bool add)
|
||||
{
|
||||
mPreSelectedGxsIds = ids ;
|
||||
requestGXSIdList();
|
||||
}
|
||||
|
||||
void FriendSelectionWidget::groupsChanged(int /*type*/)
|
||||
{
|
||||
|
@ -174,6 +174,8 @@ private:
|
||||
std::vector<RsGxsGroupId> gxsIds ;
|
||||
TokenQueue *mIdQueue ;
|
||||
QList<QAction*> mContextMenuActions;
|
||||
|
||||
std::set<RsGxsId> mPreSelectedGxsIds; // 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.
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes)
|
||||
|
@ -101,6 +101,7 @@ void GxsGroupDialog::init()
|
||||
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(submitGroup()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(cancelDialog()));
|
||||
connect(ui.pubKeyShare_cb, SIGNAL(clicked()), this, SLOT(setShareList()));
|
||||
connect(ui.addAdmins_cb, SIGNAL(clicked()), this, SLOT(setAdminsList()));
|
||||
|
||||
connect(ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo()));
|
||||
connect(ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo()));
|
||||
@ -115,14 +116,25 @@ void GxsGroupDialog::init()
|
||||
|
||||
if (!ui.pubKeyShare_cb->isChecked())
|
||||
{
|
||||
ui.contactsdockWidget->hide();
|
||||
this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height());
|
||||
ui.shareKeyList->hide();
|
||||
//this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height());
|
||||
}
|
||||
if (!ui.addAdmins_cb->isChecked())
|
||||
{
|
||||
ui.adminsList->hide();
|
||||
//this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height());
|
||||
}
|
||||
|
||||
/* initialize key share list */
|
||||
ui.keyShareList->setHeaderText(tr("Contacts:"));
|
||||
ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK);
|
||||
ui.keyShareList->start();
|
||||
ui.shareKeyList->setHeaderText(tr("Contacts:"));
|
||||
ui.shareKeyList->setModus(FriendSelectionWidget::MODUS_CHECK);
|
||||
ui.shareKeyList->start();
|
||||
|
||||
/* initialize key share list */
|
||||
ui.adminsList->setHeaderText(tr("Moderators:"));
|
||||
ui.adminsList->setModus(FriendSelectionWidget::MODUS_CHECK);
|
||||
ui.adminsList->setShowType(FriendSelectionWidget::SHOW_GXS);
|
||||
ui.adminsList->start();
|
||||
|
||||
/* Setup Reasonable Defaults */
|
||||
|
||||
@ -165,7 +177,8 @@ void GxsGroupDialog::setUiText(UiType uiType, const QString &text)
|
||||
ui.pubKeyShare_cb->setText(text);
|
||||
break;
|
||||
case UITYPE_CONTACTS_DOCK:
|
||||
ui.contactsdockWidget->setWindowTitle(text);
|
||||
case UITYPE_ADD_ADMINS_CHECKBOX:
|
||||
//ui.contactsdockWidget->setWindowTitle(text);
|
||||
break;
|
||||
case UITYPE_BUTTONBOX_OK:
|
||||
ui.buttonBox->button(QDialogButtonBox::Ok)->setText(text);
|
||||
@ -173,6 +186,23 @@ void GxsGroupDialog::setUiText(UiType uiType, const QString &text)
|
||||
}
|
||||
}
|
||||
|
||||
void GxsGroupDialog::setUiToolTip(UiType uiType, const QString &text)
|
||||
{
|
||||
switch (uiType)
|
||||
{
|
||||
case UITYPE_KEY_SHARE_CHECKBOX:
|
||||
ui.pubKeyShare_cb->setToolTip(text);
|
||||
break;
|
||||
case UITYPE_ADD_ADMINS_CHECKBOX:
|
||||
ui.addAdmins_cb->setToolTip(text);
|
||||
break;
|
||||
case UITYPE_BUTTONBOX_OK:
|
||||
ui.buttonBox->button(QDialogButtonBox::Ok)->setToolTip(text);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GxsGroupDialog::initMode()
|
||||
{
|
||||
setAllReadonly();
|
||||
@ -345,6 +375,9 @@ void GxsGroupDialog::setupVisibility()
|
||||
ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN);
|
||||
|
||||
ui.pubKeyShare_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_SHAREKEYS);
|
||||
ui.addAdmins_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS);
|
||||
ui.label_8->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS);
|
||||
ui.moderatorsLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS);
|
||||
|
||||
ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN);
|
||||
|
||||
@ -828,6 +861,31 @@ QString GxsGroupDialog::getDescription()
|
||||
return ui.groupDesc->toPlainText();
|
||||
}
|
||||
|
||||
void GxsGroupDialog::getSelectedModerators(std::set<RsGxsId>& ids)
|
||||
{
|
||||
ui.adminsList->selectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(ids, true);
|
||||
}
|
||||
|
||||
void GxsGroupDialog::setSelectedModerators(const std::set<RsGxsId>& ids)
|
||||
{
|
||||
ui.adminsList->setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(ids, false);
|
||||
|
||||
QString moderatorsListString ;
|
||||
RsIdentityDetails det;
|
||||
|
||||
for(auto it(ids.begin());it!=ids.end();++it)
|
||||
{
|
||||
rsIdentity->getIdDetails(*it,det);
|
||||
|
||||
if(!moderatorsListString.isNull())
|
||||
moderatorsListString += ", " ;
|
||||
|
||||
moderatorsListString += det.mNickname.empty()?("[Unknown]"):QString::fromStdString(det.mNickname) ;
|
||||
}
|
||||
|
||||
ui.moderatorsLabel->setText(moderatorsListString);
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
Share Lists.
|
||||
***********************************************************************************/
|
||||
@ -837,6 +895,20 @@ void GxsGroupDialog::sendShareList(std::string /*groupId*/)
|
||||
close();
|
||||
}
|
||||
|
||||
void GxsGroupDialog::setAdminsList()
|
||||
{
|
||||
if (ui.addAdmins_cb->isChecked())
|
||||
{
|
||||
//this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height());
|
||||
ui.adminsList->show();
|
||||
}
|
||||
else
|
||||
{ // hide share widget
|
||||
ui.adminsList->hide();
|
||||
//this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height());
|
||||
}
|
||||
}
|
||||
|
||||
void GxsGroupDialog::setShareList()
|
||||
{
|
||||
if (ui.pubKeyShare_cb->isChecked()) {
|
||||
|
@ -55,44 +55,45 @@ public:
|
||||
|
||||
/*** Group flags affect what is visually enabled that gets input into the grpMeta ***/
|
||||
|
||||
#define GXS_GROUP_FLAGS_NAME 0x00000001
|
||||
#define GXS_GROUP_FLAGS_ICON 0x00000002
|
||||
#define GXS_GROUP_FLAGS_DESCRIPTION 0x00000004
|
||||
#define GXS_GROUP_FLAGS_DISTRIBUTION 0x00000008
|
||||
#define GXS_GROUP_FLAGS_PUBLISHSIGN 0x00000010
|
||||
#define GXS_GROUP_FLAGS_SHAREKEYS 0x00000020
|
||||
#define GXS_GROUP_FLAGS_PERSONALSIGN 0x00000040
|
||||
#define GXS_GROUP_FLAGS_COMMENTS 0x00000080
|
||||
#define GXS_GROUP_FLAGS_EXTRA 0x00000100
|
||||
#define GXS_GROUP_FLAGS_ANTI_SPAM 0x00000200
|
||||
#define GXS_GROUP_FLAGS_NAME 0x00000001
|
||||
#define GXS_GROUP_FLAGS_ICON 0x00000002
|
||||
#define GXS_GROUP_FLAGS_DESCRIPTION 0x00000004
|
||||
#define GXS_GROUP_FLAGS_DISTRIBUTION 0x00000008
|
||||
#define GXS_GROUP_FLAGS_PUBLISHSIGN 0x00000010
|
||||
#define GXS_GROUP_FLAGS_SHAREKEYS 0x00000020
|
||||
#define GXS_GROUP_FLAGS_PERSONALSIGN 0x00000040
|
||||
#define GXS_GROUP_FLAGS_COMMENTS 0x00000080
|
||||
#define GXS_GROUP_FLAGS_EXTRA 0x00000100
|
||||
#define GXS_GROUP_FLAGS_ANTI_SPAM 0x00000200
|
||||
#define GXS_GROUP_FLAGS_ADDADMINS 0x00000400
|
||||
|
||||
/*** Default flags are used to determine privacy of group, signatures required ***
|
||||
*** whether publish or id and whether comments are allowed or not ***/
|
||||
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_MASK 0x00000f00
|
||||
#define GXS_GROUP_DEFAULTS_COMMENTS_MASK 0x0000f000
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_MASK 0x00000f00
|
||||
#define GXS_GROUP_DEFAULTS_COMMENTS_MASK 0x0000f000
|
||||
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC 0x00000001
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_GROUP 0x00000002
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_LOCAL 0x00000004
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC 0x00000001
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_GROUP 0x00000002
|
||||
#define GXS_GROUP_DEFAULTS_DISTRIB_LOCAL 0x00000004
|
||||
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_THREADS 0x00000020
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED 0x00000040
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED 0x00000080
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_THREADS 0x00000020
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED 0x00000040
|
||||
#define GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED 0x00000080
|
||||
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED 0x00000200
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB 0x00000400
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED 0x00000200
|
||||
#define GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB 0x00000400
|
||||
|
||||
#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000
|
||||
#define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000
|
||||
#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000
|
||||
#define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000
|
||||
|
||||
#define GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP 0x00100000
|
||||
#define GXS_GROUP_DEFAULTS_ANTISPAM_TRACK 0x00200000
|
||||
#define GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP_KNOWN 0x00400000
|
||||
#define GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP 0x00100000
|
||||
#define GXS_GROUP_DEFAULTS_ANTISPAM_TRACK 0x00200000
|
||||
#define GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP_KNOWN 0x00400000
|
||||
|
||||
/*!
|
||||
* The aim of this dialog is to be convenient to encapsulate group
|
||||
@ -121,6 +122,7 @@ public:
|
||||
enum UiType {
|
||||
UITYPE_SERVICE_HEADER,
|
||||
UITYPE_KEY_SHARE_CHECKBOX,
|
||||
UITYPE_ADD_ADMINS_CHECKBOX,
|
||||
UITYPE_CONTACTS_DOCK,
|
||||
UITYPE_BUTTONBOX_OK
|
||||
};
|
||||
@ -172,7 +174,14 @@ protected:
|
||||
virtual QPixmap serviceImage() = 0;
|
||||
virtual QIcon serviceWindowIcon();
|
||||
|
||||
void setUiText(UiType uiType, const QString &text);
|
||||
/*!
|
||||
* \brief setUiToolTip/setUiText
|
||||
* Sets the text and tooltip of some parts of the UI
|
||||
* \param uiType widget to set
|
||||
* \param text text to set
|
||||
*/
|
||||
void setUiToolTip(UiType uiType, const QString &text);
|
||||
void setUiText (UiType uiType, const QString &text);
|
||||
|
||||
/*!
|
||||
* It is up to the service to do the actual group creation
|
||||
@ -219,12 +228,20 @@ protected:
|
||||
*/
|
||||
QString getDescription();
|
||||
|
||||
/*!
|
||||
* \brief getSelectedModerators
|
||||
* Returns the set of ids that hve been selected as moderators.
|
||||
*/
|
||||
void getSelectedModerators(std::set<RsGxsId>& ids);
|
||||
void setSelectedModerators(const std::set<RsGxsId>& ids);
|
||||
|
||||
private slots:
|
||||
/* actions to take.... */
|
||||
void cancelDialog();
|
||||
|
||||
// set private forum key share list
|
||||
void setShareList();
|
||||
void setAdminsList();
|
||||
|
||||
void updateCircleOptions();
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1237</width>
|
||||
<height>1145</height>
|
||||
<height>1189</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -44,7 +44,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="createmode">
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
@ -172,13 +172,23 @@
|
||||
<string>Will be used to send feedback</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Owner:</string>
|
||||
<string>Contact:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GxsIdChooser" name="idChooser"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="addAdmins_cb">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add moderators</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="pubKeyShare_cb">
|
||||
<property name="toolTip">
|
||||
@ -196,102 +206,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDockWidget" name="contactsdockWidget">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>524287</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>220</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>check peers you would like to share private publish key with</string>
|
||||
</property>
|
||||
<property name="floating">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::NoDockWidgetFeatures</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Share Key With</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QGridLayout" name="_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="FriendSelectionWidget" name="keyShareList" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>4</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>220</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="distribGroupBox">
|
||||
<property name="sizePolicy">
|
||||
@ -435,7 +349,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Description</string>
|
||||
@ -447,7 +361,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QGroupBox" name="publishGroupBox">
|
||||
<property name="title">
|
||||
<string>Publish Signatures</string>
|
||||
@ -512,7 +426,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QGroupBox" name="personalGroupBox">
|
||||
<property name="title">
|
||||
<string>Personal Signatures</string>
|
||||
@ -555,7 +469,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QGroupBox" name="commentGroupBox">
|
||||
<property name="title">
|
||||
<string>Comments</string>
|
||||
@ -606,7 +520,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QGroupBox" name="spamProtection_GB">
|
||||
<property name="title">
|
||||
<string>Spam-protection</string>
|
||||
@ -657,7 +571,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QFrame" name="extraFrame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
@ -667,6 +581,12 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="FriendSelectionWidget" name="adminsList" native="true"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="FriendSelectionWidget" name="shareKeyList" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="showmode">
|
||||
@ -676,150 +596,168 @@
|
||||
<property name="title">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="nameline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Popularity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="popline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Posts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="postsline">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Last Post</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lastpostline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Author</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="GxsIdLabel" name="authorLabel">
|
||||
<property name="text">
|
||||
<string>GxsIdLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="IDline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="commentsLabel">
|
||||
<property name="text">
|
||||
<string>Comments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="commentsValueLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" rowspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="distributionValueLabel">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Moderators:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="distributionValueLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GxsCircleChooser" name="distributionCircleComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="postsline">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="popline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Posts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="GxsIdLabel" name="authorLabel">
|
||||
<property name="text">
|
||||
<string>GxsIdLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="lastpostline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Author</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="antiSpamValueLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GxsCircleChooser" name="distributionCircleComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLineEdit" name="IDline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="commentsLabel">
|
||||
<property name="text">
|
||||
<string>Comments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="commentsValueLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="distributionLabel">
|
||||
<property name="text">
|
||||
<string>Distribution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="antiSpamLabel">
|
||||
<property name="text">
|
||||
<string>Anti Spam:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Last Post</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Popularity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="nameline">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="moderatorsLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="distributionLabel">
|
||||
<property name="text">
|
||||
<string>Distribution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="antiSpamLabel">
|
||||
<property name="text">
|
||||
<string>Anti Spam:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="antiSpamValueLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -870,7 +870,7 @@ QString GxsIdDetails::getFailedText(const RsGxsId &id)
|
||||
|
||||
QString GxsIdDetails::getEmptyIdText()
|
||||
{
|
||||
return QApplication::translate("GxsIdDetails", "No Signature");
|
||||
return QApplication::translate("GxsIdDetails", "[None]");
|
||||
}
|
||||
|
||||
QString GxsIdDetails::getNameForType(GxsIdDetailsType type, const RsIdentityDetails &details)
|
||||
|
@ -34,7 +34,7 @@ const uint32_t ChannelCreateEnabledFlags = (
|
||||
GXS_GROUP_FLAGS_DESCRIPTION |
|
||||
GXS_GROUP_FLAGS_DISTRIBUTION |
|
||||
// GXS_GROUP_FLAGS_PUBLISHSIGN |
|
||||
GXS_GROUP_FLAGS_SHAREKEYS |
|
||||
// GXS_GROUP_FLAGS_SHAREKEYS | // disabled because the UI doesn't handle it, so no need to show the disabled button. The user can do it in a second step from the channel menu.
|
||||
// GXS_GROUP_FLAGS_PERSONALSIGN |
|
||||
GXS_GROUP_FLAGS_COMMENTS |
|
||||
0);
|
||||
@ -75,19 +75,19 @@ void GxsChannelGroupDialog::initUi()
|
||||
{
|
||||
case MODE_CREATE:
|
||||
setUiText(UITYPE_SERVICE_HEADER, tr("Create New Channel"));
|
||||
setUiText(UITYPE_BUTTONBOX_OK, tr("Create"));
|
||||
setUiText(UITYPE_BUTTONBOX_OK, tr("Create"));
|
||||
break;
|
||||
case MODE_SHOW:
|
||||
setUiText(UITYPE_SERVICE_HEADER, tr("Channel"));
|
||||
break;
|
||||
case MODE_EDIT:
|
||||
setUiText(UITYPE_SERVICE_HEADER, tr("Edit Channel"));
|
||||
setUiText(UITYPE_BUTTONBOX_OK, tr("Update Channel"));
|
||||
setUiText(UITYPE_BUTTONBOX_OK, tr("Update Channel"));
|
||||
break;
|
||||
}
|
||||
|
||||
setUiText(UITYPE_KEY_SHARE_CHECKBOX, tr("Add Channel Admins"));
|
||||
setUiText(UITYPE_CONTACTS_DOCK, tr("Select Channel Admins"));
|
||||
setUiText(UITYPE_CONTACTS_DOCK, tr("Select Channel Admins"));
|
||||
}
|
||||
|
||||
QPixmap GxsChannelGroupDialog::serviceImage()
|
||||
|
@ -50,8 +50,9 @@
|
||||
//#define ENABLE_GENERATE
|
||||
|
||||
/** Constructor */
|
||||
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), mOrigMsgId(mOId),mPosterId(posterId)
|
||||
CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId& mOId, const RsGxsId& posterId, bool isModerating)
|
||||
: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint),
|
||||
mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId),mIsModerating(isModerating)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
ui.setupUi(this);
|
||||
@ -355,7 +356,9 @@ void CreateGxsForumMsg::createMsg()
|
||||
msg.mMeta.mGroupId = mForumId;
|
||||
msg.mMeta.mParentId = mParentId;
|
||||
msg.mMeta.mOrigMsgId = mOrigMsgId;
|
||||
msg.mMeta.mMsgFlags = mIsModerating?RS_GXS_FORUM_MSG_FLAGS_MODERATED : 0;
|
||||
msg.mMeta.mMsgId.clear() ;
|
||||
|
||||
if (mParentMsgLoaded) {
|
||||
msg.mMeta.mThreadId = mParentMsg.mMeta.mThreadId;
|
||||
}//if (mParentMsgLoaded)
|
||||
|
@ -36,7 +36,7 @@ class CreateGxsForumMsg : public QDialog, public TokenResponse
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId &moId, const RsGxsId &posterId = RsGxsId());
|
||||
CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId &moId, const RsGxsId &posterId = RsGxsId(),bool isModerating=false);
|
||||
~CreateGxsForumMsg();
|
||||
|
||||
void newMsg(); /* cleanup */
|
||||
@ -75,6 +75,7 @@ private:
|
||||
bool mOrigMsgLoaded;
|
||||
bool mForumMetaLoaded;
|
||||
bool mForumCircleLoaded ;
|
||||
bool mIsModerating; // means that the msg has a orig author Id that is not the Id of the author
|
||||
|
||||
RsGxsForumMsg mParentMsg;
|
||||
RsGxsForumMsg mOrigMsg;
|
||||
|
@ -27,12 +27,13 @@
|
||||
// To start with we only have open forums - with distribution controls.
|
||||
|
||||
const uint32_t ForumCreateEnabledFlags = (
|
||||
GXS_GROUP_FLAGS_NAME |
|
||||
// GXS_GROUP_FLAGS_ICON |
|
||||
GXS_GROUP_FLAGS_NAME |
|
||||
// GXS_GROUP_FLAGS_ICON |
|
||||
GXS_GROUP_FLAGS_DESCRIPTION |
|
||||
GXS_GROUP_FLAGS_DISTRIBUTION |
|
||||
// GXS_GROUP_FLAGS_PUBLISHSIGN |
|
||||
GXS_GROUP_FLAGS_SHAREKEYS |
|
||||
// GXS_GROUP_FLAGS_PUBLISHSIGN|
|
||||
// GXS_GROUP_FLAGS_SHAREKEYS |
|
||||
GXS_GROUP_FLAGS_ADDADMINS |
|
||||
GXS_GROUP_FLAGS_ANTI_SPAM |
|
||||
// GXS_GROUP_FLAGS_PERSONALSIGN |
|
||||
// GXS_GROUP_FLAGS_COMMENTS |
|
||||
@ -42,17 +43,17 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC
|
||||
//GXS_GROUP_DEFAULTS_DISTRIB_GROUP |
|
||||
//GXS_GROUP_DEFAULTS_DISTRIB_LOCAL |
|
||||
|
||||
GXS_GROUP_DEFAULTS_PUBLISH_OPEN |
|
||||
GXS_GROUP_DEFAULTS_PUBLISH_OPEN |
|
||||
//GXS_GROUP_DEFAULTS_PUBLISH_THREADS |
|
||||
//GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED |
|
||||
//GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED |
|
||||
|
||||
//GXS_GROUP_DEFAULTS_PERSONAL_PGP |
|
||||
GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED |
|
||||
GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED |
|
||||
//GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB |
|
||||
|
||||
//GXS_GROUP_DEFAULTS_COMMENTS_YES |
|
||||
GXS_GROUP_DEFAULTS_COMMENTS_NO |
|
||||
GXS_GROUP_DEFAULTS_COMMENTS_NO |
|
||||
0);
|
||||
|
||||
const uint32_t ForumEditEnabledFlags = ForumCreateEnabledFlags;
|
||||
@ -61,11 +62,13 @@ const uint32_t ForumEditDefaultsFlags = ForumCreateDefaultsFlags;
|
||||
GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent)
|
||||
: GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent)
|
||||
{
|
||||
ui.pubKeyShare_cb->setEnabled(true) ;
|
||||
}
|
||||
|
||||
GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent)
|
||||
: GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, ForumEditEnabledFlags, ForumEditDefaultsFlags, parent)
|
||||
{
|
||||
ui.pubKeyShare_cb->setEnabled(true) ;
|
||||
}
|
||||
|
||||
void GxsForumGroupDialog::initUi()
|
||||
@ -85,8 +88,10 @@ void GxsForumGroupDialog::initUi()
|
||||
break;
|
||||
}
|
||||
|
||||
setUiText(UITYPE_KEY_SHARE_CHECKBOX, tr("Add Forum Admins"));
|
||||
setUiText(UITYPE_CONTACTS_DOCK, tr("Select Forum Admins"));
|
||||
setUiToolTip(UITYPE_ADD_ADMINS_CHECKBOX,tr("Forum moderators can edit/delete/pinup others posts"));
|
||||
|
||||
//setUiText(UITYPE_KEY_SHARE_CHECKBOX, tr("Add Forum Admins"));
|
||||
//setUiText(UITYPE_CONTACTS_DOCK, tr("Select Forum Admins"));
|
||||
}
|
||||
|
||||
QPixmap GxsForumGroupDialog::serviceImage()
|
||||
@ -100,6 +105,7 @@ bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMeta
|
||||
RsGxsForumGroup grp;
|
||||
grp.mMeta = meta;
|
||||
grp.mDescription = getDescription().toUtf8().constData();
|
||||
getSelectedModerators(grp.mAdminList.ids);
|
||||
|
||||
rsGxsForums->createGroup(token, grp);
|
||||
return true;
|
||||
@ -107,10 +113,15 @@ bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMeta
|
||||
|
||||
bool GxsForumGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta)
|
||||
{
|
||||
RsGxsForumGroup grp;
|
||||
RsGxsForumGroup grp(mGroupData); // start again from cached information. That allows to keep the pinned posts for instance.
|
||||
|
||||
// now replace data by locally edited/changed information
|
||||
|
||||
grp.mMeta = editedMeta;
|
||||
grp.mDescription = getDescription().toUtf8().constData();
|
||||
|
||||
getSelectedModerators(grp.mAdminList.ids);
|
||||
|
||||
std::cerr << "GxsForumGroupDialog::service_EditGroup() submitting changes";
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -124,6 +135,7 @@ bool GxsForumGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGro
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::vector<RsGxsForumGroup> groups;
|
||||
|
||||
if (!rsGxsForums->getGroupData(token, groups))
|
||||
{
|
||||
std::cerr << "GxsForumGroupDialog::service_loadGroup() Error getting GroupData";
|
||||
@ -141,8 +153,16 @@ bool GxsForumGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGro
|
||||
std::cerr << "GxsForumsGroupDialog::service_loadGroup() Unfinished Loading";
|
||||
std::cerr << std::endl;
|
||||
|
||||
// Information handled by GxsGroupDialog. description should rather be handled here in the service part!
|
||||
|
||||
groupMetaData = groups[0].mMeta;
|
||||
description = QString::fromUtf8(groups[0].mDescription.c_str());
|
||||
|
||||
// Local information. Description should be handled here.
|
||||
|
||||
setSelectedModerators(groups[0].mAdminList.ids);
|
||||
|
||||
mGroupData = groups[0]; // keeps the private information
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ protected:
|
||||
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta);
|
||||
virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description);
|
||||
virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta);
|
||||
|
||||
private:
|
||||
RsGxsForumGroup mGroupData;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -88,6 +88,7 @@
|
||||
#define COLUMN_THREAD_CONTENT 6
|
||||
#define COLUMN_THREAD_COUNT 7
|
||||
#define COLUMN_THREAD_MSGID 8
|
||||
#define COLUMN_THREAD_NB_COLUMNS 9
|
||||
|
||||
#define COLUMN_THREAD_DATA 0 // column for storing the userdata like parentid
|
||||
|
||||
@ -99,6 +100,7 @@
|
||||
#define ROLE_THREAD_READCHILDREN Qt::UserRole + 4
|
||||
#define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 5
|
||||
#define ROLE_THREAD_SORT Qt::UserRole + 6
|
||||
#define ROLE_THREAD_PINNED Qt::UserRole + 7
|
||||
|
||||
#define ROLE_THREAD_COUNT 4
|
||||
|
||||
@ -246,8 +248,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
||||
ttheader->resizeSection (COLUMN_THREAD_DISTRIBUTION, 24*f);
|
||||
ttheader->resizeSection (COLUMN_THREAD_AUTHOR, 150*f);
|
||||
|
||||
ui->threadTreeWidget->sortItems(COLUMN_THREAD_DATE, Qt::DescendingOrder);
|
||||
|
||||
/* Set text of column "Read" to empty - without this the column has a number as header text */
|
||||
QTreeWidgetItem *headerItem = ui->threadTreeWidget->headerItem();
|
||||
headerItem->setText(COLUMN_THREAD_READ, "") ;
|
||||
@ -297,6 +297,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
||||
forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p>"));
|
||||
ui->threadTreeWidget->enableColumnCustomize(true);
|
||||
|
||||
ui->threadTreeWidget->sortItems(COLUMN_THREAD_DATE, Qt::DescendingOrder);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::blank()
|
||||
@ -511,10 +512,15 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
}
|
||||
|
||||
QMenu contextMnu(this);
|
||||
QList<QTreeWidgetItem*> selectedItems = ui->threadTreeWidget->selectedItems();
|
||||
|
||||
QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEEDIT), tr("Edit"), &contextMnu);
|
||||
connect(editAct, SIGNAL(triggered()), this, SLOT(editforummessage()));
|
||||
|
||||
bool is_pinned = mForumGroup.mPinnedPosts.ids.find(mThreadId) != mForumGroup.mPinnedPosts.ids.end();
|
||||
QAction *pinUpPostAct = new QAction(QIcon(IMAGE_MESSAGE), (is_pinned?tr("Un-pin this post"):tr("Pin this post up")), &contextMnu);
|
||||
connect(pinUpPostAct , SIGNAL(triggered()), this, SLOT(togglePinUpPost()));
|
||||
|
||||
QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu);
|
||||
connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage()));
|
||||
|
||||
@ -604,16 +610,37 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
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);
|
||||
bool is_pinned = mForumGroup.mPinnedPosts.ids.find( RsGxsMessageId(item->data(COLUMN_THREAD_MSGID,Qt::DisplayRole).toString().toStdString()) ) != mForumGroup.mPinnedPosts.ids.end();
|
||||
|
||||
if(!is_pinned)
|
||||
{
|
||||
RsGxsId author_id;
|
||||
if(gxsIdItem && gxsIdItem->getId(author_id) && rsIdentity->isOwnId(author_id))
|
||||
contextMnu.addAction(editAct);
|
||||
else
|
||||
{
|
||||
// Go through the list of own ids and see if one of them is a moderator
|
||||
// TODO: offer to select which moderator ID to use if multiple IDs fit the conditions of the forum
|
||||
|
||||
std::list<RsGxsId> own_ids ;
|
||||
rsIdentity->getOwnIds(own_ids) ;
|
||||
|
||||
for(auto it(own_ids.begin());it!=own_ids.end();++it)
|
||||
if(mForumGroup.mAdminList.ids.find(*it) != mForumGroup.mAdminList.ids.end())
|
||||
{
|
||||
contextMnu.addAction(editAct);
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(IS_GROUP_ADMIN(mSubscribeFlags) && (*selectedItems.begin())->parent() == NULL)
|
||||
contextMnu.addAction(pinUpPostAct);
|
||||
}
|
||||
|
||||
contextMnu.addAction(replyAct);
|
||||
@ -660,6 +687,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
contextMnu.addAction(showinpeopleAct);
|
||||
contextMnu.addAction(replyauthorAct);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contextMnu.exec(QCursor::pos());
|
||||
@ -783,6 +811,7 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h
|
||||
bool isNew = IS_MSG_NEW(status);
|
||||
bool unread = IS_MSG_UNREAD(status);
|
||||
bool missing = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool();
|
||||
RsGxsMessageId msgId(item->data(COLUMN_THREAD_MSGID,Qt::DisplayRole).toString().toStdString());
|
||||
|
||||
// set icon
|
||||
if (missing) {
|
||||
@ -811,6 +840,8 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h
|
||||
calculateIconsAndFonts(item->child(index), myReadChilddren, myUnreadChilddren);
|
||||
}
|
||||
|
||||
bool is_pinned = mForumGroup.mPinnedPosts.ids.find(msgId) != mForumGroup.mPinnedPosts.ids.end();
|
||||
|
||||
// set font
|
||||
for (int i = 0; i < COLUMN_THREAD_COUNT; ++i) {
|
||||
QFont qf = item->font(i);
|
||||
@ -832,6 +863,15 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h
|
||||
/* Missing message */
|
||||
item->setForeground(i, textColorMissing());
|
||||
}
|
||||
if(is_pinned)
|
||||
{
|
||||
qf.setBold(true);
|
||||
item->setForeground(i, textColorUnread());
|
||||
item->setData(i,Qt::BackgroundRole, QBrush(QColor(255,200,180))) ;
|
||||
}
|
||||
else
|
||||
item->setData(i,Qt::BackgroundRole, QBrush());
|
||||
|
||||
item->setFont(i, qf);
|
||||
}
|
||||
|
||||
@ -968,6 +1008,10 @@ static QString getDurationString(uint32_t days)
|
||||
else if(IS_GROUP_PGP_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous posts forwarded if reputation is positive");
|
||||
|
||||
tw->mForumDescription = QString("<b>%1: \t</b>%2<br/>").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str()));
|
||||
tw->mForumDescription += QString("<b>%1: </b>%2<br/>").arg(tr("Description"),
|
||||
group.mDescription.empty()?
|
||||
tr("[None]<br/>")
|
||||
:(QString::fromUtf8(group.mDescription.c_str())+"<br/>"));
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Subscribers")).arg(group.mMeta.mPop);
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Posts (at neighbor nodes)")).arg(group.mMeta.mVisibleMsgCount);
|
||||
if(group.mMeta.mLastPost==0)
|
||||
@ -1014,21 +1058,31 @@ static QString getDurationString(uint32_t days)
|
||||
}
|
||||
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Distribution"), distrib_string);
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Author"), author);
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Contact"), author);
|
||||
|
||||
if(!anti_spam_features1.isNull())
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Anti-spam")).arg(anti_spam_features1);
|
||||
|
||||
tw->mForumDescription += QString("<b>%1: </b><br/><br/>%2").arg(tr("Description"), QString::fromUtf8(group.mDescription.c_str()));
|
||||
|
||||
tw->ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(tw->mSubscribeFlags));
|
||||
tw->mStateHelper->setWidgetEnabled(tw->ui->newthreadButton, (IS_GROUP_SUBSCRIBED(tw->mSubscribeFlags)));
|
||||
|
||||
if (tw->mThreadId.isNull() && !tw->mStateHelper->isLoading(tw->mTokenTypeMessageData))
|
||||
if(!group.mAdminList.ids.empty())
|
||||
{
|
||||
//ui->threadTitle->setText(tr("Forum Description"));
|
||||
tw->ui->postText->setText(tw->mForumDescription);
|
||||
QString admin_list_str ;
|
||||
|
||||
for(auto it(group.mAdminList.ids.begin());it!=group.mAdminList.ids.end();++it)
|
||||
{
|
||||
RsIdentityDetails det ;
|
||||
|
||||
rsIdentity->getIdDetails(*it,det);
|
||||
admin_list_str += (admin_list_str.isNull()?"":", ") + QString::fromUtf8(det.mNickname.c_str()) ;
|
||||
}
|
||||
|
||||
tw->mForumDescription += QString("<b>%1: </b>%2").arg(tr("Moderators"), admin_list_str);
|
||||
}
|
||||
|
||||
if (tw->mThreadId.isNull() && !tw->mStateHelper->isLoading(tw->mTokenTypeMessageData))
|
||||
tw->ui->postText->setText(tw->mForumDescription);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::fillThreadFinished()
|
||||
@ -1167,11 +1221,49 @@ void GxsForumThreadWidget::fillThreadStatus(QString text)
|
||||
ui->progressText->setText(text);
|
||||
}
|
||||
|
||||
//#define DEBUG_PINNED_POST_SORTING 1
|
||||
|
||||
class ForumThreadItem: public GxsIdRSTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
ForumThreadItem(QHeaderView *header,const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent = NULL)
|
||||
: GxsIdRSTreeWidgetItem(compareRole,icon_mask,parent), m_header(header) {}
|
||||
|
||||
bool operator<(const QTreeWidgetItem& other) const
|
||||
{
|
||||
bool left_is_not_pinned = ! data(COLUMN_THREAD_DATE,ROLE_THREAD_PINNED).toBool();
|
||||
bool right_is_not_pinned = !other.data(COLUMN_THREAD_DATE,ROLE_THREAD_PINNED).toBool();
|
||||
#ifdef DEBUG_PINNED_POST_SORTING
|
||||
std::cerr << "Comparing item date \"" << data(COLUMN_THREAD_DATE,Qt::DisplayRole).toString().toStdString() << "\" ("
|
||||
<< data(COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toUInt() << ", \"" << data(COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toString().toStdString() << "\" --> " << left_is_not_pinned << ") to \""
|
||||
<< other.data(COLUMN_THREAD_DATE,Qt::DisplayRole).toString().toStdString() << "\" ("
|
||||
<< other.data(COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toUInt() << ", \"" << other.data(COLUMN_THREAD_DATE,ROLE_THREAD_SORT).toString().toStdString() << "\" --> " << right_is_not_pinned << ") ";
|
||||
#endif
|
||||
|
||||
if(left_is_not_pinned ^ right_is_not_pinned)
|
||||
{
|
||||
#ifdef DEBUG_PINNED_POST_SORTING
|
||||
std::cerr << "Local: " << ((m_header->sortIndicatorOrder()==Qt::AscendingOrder)?right_is_not_pinned:left_is_not_pinned) << std::endl;
|
||||
#endif
|
||||
return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?right_is_not_pinned:left_is_not_pinned ; // always put pinned posts on top
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PINNED_POST_SORTING
|
||||
std::cerr << "Remote: " << GxsIdRSTreeWidgetItem::operator<(other) << std::endl;
|
||||
#endif
|
||||
return GxsIdRSTreeWidgetItem::operator<(other);
|
||||
}
|
||||
|
||||
private:
|
||||
QHeaderView *m_header ;
|
||||
};
|
||||
|
||||
QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *parent)
|
||||
{
|
||||
// Early check for a message that should be hidden because its author
|
||||
// is flagged with a bad reputation
|
||||
|
||||
bool is_pinned = mForumGroup.mPinnedPosts.ids.find(msg.mMeta.mMsgId) != mForumGroup.mPinnedPosts.ids.end();
|
||||
|
||||
uint32_t idflags =0;
|
||||
RsReputations::ReputationLevel reputation_level = rsReputations->overallReputationLevel(msg.mMeta.mAuthorId,&idflags) ;
|
||||
@ -1179,11 +1271,15 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
|
||||
|
||||
redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
|
||||
|
||||
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR );
|
||||
// We use a specific item model for forums in order to handle the post pinning.
|
||||
|
||||
GxsIdRSTreeWidgetItem *item = new ForumThreadItem(ui->threadTreeWidget->header(),mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR );
|
||||
item->moveToThread(ui->threadTreeWidget->thread());
|
||||
|
||||
if(redacted)
|
||||
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]"));
|
||||
else if(is_pinned)
|
||||
item->setText(COLUMN_THREAD_TITLE, tr("[PINNED] ") + QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
||||
else
|
||||
item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
||||
|
||||
@ -1220,30 +1316,42 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
|
||||
qtime.setTime_t(msg.mMeta.mPublishTs);
|
||||
|
||||
QString itemText = DateTime::formatDateTime(qtime);
|
||||
// This is an attempt to put pinned posts on the top. We should rather use a QSortFilterProxyModel here.
|
||||
QString itemSort = QString::number(msg.mMeta.mPublishTs);//Don't need to format it as for sort.
|
||||
|
||||
//#define SHOW_COMBINED_DATES 1
|
||||
|
||||
if (useChildTS)
|
||||
{
|
||||
for(QTreeWidgetItem *grandParent = parent; grandParent!=NULL; grandParent = grandParent->parent())
|
||||
{
|
||||
//Update Parent Child TimeStamp
|
||||
QString oldTSText = grandParent->text(COLUMN_THREAD_DATE);
|
||||
QString oldTSSort = grandParent->data(COLUMN_THREAD_DATE, ROLE_THREAD_SORT).toString();
|
||||
|
||||
QString oldCTSText = oldTSText.split("|").at(0);
|
||||
QString oldPTSText = oldTSText.contains("|") ? oldTSText.split(" | ").at(1) : oldCTSText;//If first time parent get only its mPublishTs
|
||||
QString oldCTSSort = oldTSSort.split("|").at(0);
|
||||
QString oldPTSSort = oldTSSort.contains("|") ? oldTSSort.split(" | ").at(1) : oldCTSSort;
|
||||
#ifdef SHOW_COMBINED_DATES
|
||||
QString oldTSText = grandParent->text(COLUMN_THREAD_DATE);
|
||||
QString oldCTSText = oldTSText.split("|").at(0);
|
||||
QString oldPTSText = oldTSText.contains("|") ? oldTSText.split(" | ").at(1) : oldCTSText;//If first time parent get only its mPublishTs
|
||||
#endif
|
||||
if (oldCTSSort.toDouble() < itemSort.toDouble())
|
||||
{
|
||||
#ifdef SHOW_COMBINED_DATES
|
||||
grandParent->setText(COLUMN_THREAD_DATE, DateTime::formatDateTime(qtime) + " | " + oldPTSText);
|
||||
#endif
|
||||
grandParent->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, itemSort + " | " + oldPTSSort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item->setText(COLUMN_THREAD_DATE, itemText);
|
||||
item->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, itemSort);
|
||||
item->setData(COLUMN_THREAD_DATE,ROLE_THREAD_SORT, itemSort);
|
||||
|
||||
if(is_pinned)
|
||||
item->setData(COLUMN_THREAD_DATE,ROLE_THREAD_PINNED, QVariant(true)); // this is used by the sorting model to put all posts on top
|
||||
else
|
||||
item->setData(COLUMN_THREAD_DATE,ROLE_THREAD_PINNED, QVariant(false));
|
||||
|
||||
// Set later with GxsIdRSTreeWidgetItem::setId
|
||||
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_AUTHOR, QString::fromStdString(msg.mMeta.mAuthorId.toStdString()));
|
||||
@ -2080,6 +2188,37 @@ void GxsForumThreadWidget::createmessage()
|
||||
/* window will destroy itself! */
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::togglePinUpPost()
|
||||
{
|
||||
if (groupId().isNull() || mThreadId.isNull())
|
||||
return;
|
||||
|
||||
QTreeWidgetItem *item = ui->threadTreeWidget->currentItem();
|
||||
|
||||
// normally this method is only called on top level items. We still check it just in case...
|
||||
|
||||
if(item->parent() != NULL)
|
||||
{
|
||||
std::cerr << "(EE) togglePinUpPost() called on non top level post. This is inconsistent." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
QString thread_title = (item != NULL)?item->text(COLUMN_THREAD_TITLE):QString() ;
|
||||
|
||||
std::cerr << "Toggling Pin-up state of post " << mThreadId.toStdString() << ": \"" << thread_title.toStdString() << "\"" << std::endl;
|
||||
|
||||
if(mForumGroup.mPinnedPosts.ids.find(mThreadId) == mForumGroup.mPinnedPosts.ids.end())
|
||||
mForumGroup.mPinnedPosts.ids.insert(mThreadId) ;
|
||||
else
|
||||
mForumGroup.mPinnedPosts.ids.erase(mThreadId) ;
|
||||
|
||||
uint32_t token;
|
||||
rsGxsForums->updateGroup(token,mForumGroup);
|
||||
|
||||
ui->threadTreeWidget->takeTopLevelItem(ui->threadTreeWidget->indexOfTopLevelItem(item)); // forces the re-creation of all posts widgets. A bit extreme. We should rather only delete item above
|
||||
updateDisplay(true) ;
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::createthread()
|
||||
{
|
||||
if (groupId().isNull ()) {
|
||||
@ -2223,9 +2362,30 @@ void GxsForumThreadWidget::editForumMessageData(const RsGxsForumMsg& msg)
|
||||
return;
|
||||
}
|
||||
|
||||
// Go through the list of own ids and see if one of them is a moderator
|
||||
// TODO: offer to select which moderator ID to use if multiple IDs fit the conditions of the forum
|
||||
|
||||
RsGxsId moderator_id ;
|
||||
|
||||
std::list<RsGxsId> own_ids ;
|
||||
rsIdentity->getOwnIds(own_ids) ;
|
||||
|
||||
for(auto it(own_ids.begin());it!=own_ids.end();++it)
|
||||
if(mForumGroup.mAdminList.ids.find(*it) != mForumGroup.mAdminList.ids.end())
|
||||
{
|
||||
moderator_id = *it;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that author is in own ids, if not use the moderator id that was collected among own ids.
|
||||
bool is_own = false ;
|
||||
for(auto it(own_ids.begin());it!=own_ids.end() && !is_own;++it)
|
||||
if(*it == msg.mMeta.mAuthorId)
|
||||
is_own = true ;
|
||||
|
||||
if (!msg.mMeta.mAuthorId.isNull())
|
||||
{
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), msg.mMeta.mParentId, msg.mMeta.mMsgId, msg.mMeta.mAuthorId);
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), msg.mMeta.mParentId, msg.mMeta.mMsgId, is_own?(msg.mMeta.mAuthorId):moderator_id,!is_own);
|
||||
|
||||
cfm->insertPastedText(QString::fromUtf8(msg.mMsg.c_str())) ;
|
||||
cfm->show();
|
||||
|
@ -108,6 +108,7 @@ private slots:
|
||||
|
||||
void subscribeGroup(bool subscribe);
|
||||
void createthread();
|
||||
void togglePinUpPost();
|
||||
void createmessage();
|
||||
|
||||
void previousMessage();
|
||||
|
@ -182,7 +182,7 @@
|
||||
<widget class="QComboBox" name="viewBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Last Post</string>
|
||||
<string>Lastest post in thread</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@ -577,8 +577,8 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
<include location="../icons.qrc"/>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -94,57 +94,101 @@ static bool decreasing_time_comp(const QPair<time_t,RsGxsMessageId>& e1,const QP
|
||||
void GxsForumsFillThread::run()
|
||||
{
|
||||
RsTokenService *service = rsGxsForums->getTokenService();
|
||||
uint32_t msg_token;
|
||||
uint32_t grp_token;
|
||||
|
||||
emit status(tr("Waiting"));
|
||||
|
||||
/* get all messages of the forum */
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
{
|
||||
/* get all messages of the forum */
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
|
||||
std::list<RsGxsGroupId> grpIds;
|
||||
grpIds.push_back(mForumId);
|
||||
std::list<RsGxsGroupId> grpIds;
|
||||
grpIds.push_back(mForumId);
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "GxsForumsFillThread::run() forum id " << mForumId << std::endl;
|
||||
std::cerr << "GxsForumsFillThread::run() forum id " << mForumId << std::endl;
|
||||
#endif
|
||||
|
||||
uint32_t token;
|
||||
service->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds);
|
||||
service->requestMsgInfo(msg_token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds);
|
||||
|
||||
/* wait for the answer */
|
||||
uint32_t requestStatus = RsTokenService::PENDING;
|
||||
while (!wasStopped()) {
|
||||
requestStatus = service->requestStatus(token);
|
||||
if (requestStatus == RsTokenService::FAILED ||
|
||||
requestStatus == RsTokenService::COMPLETE) {
|
||||
break;
|
||||
/* wait for the answer */
|
||||
uint32_t requestStatus = RsTokenService::PENDING;
|
||||
while (!wasStopped()) {
|
||||
requestStatus = service->requestStatus(msg_token);
|
||||
if (requestStatus == RsTokenService::FAILED ||
|
||||
requestStatus == RsTokenService::COMPLETE) {
|
||||
break;
|
||||
}
|
||||
msleep(200);
|
||||
}
|
||||
msleep(100);
|
||||
|
||||
if (requestStatus == RsTokenService::FAILED)
|
||||
return;
|
||||
}
|
||||
|
||||
if (wasStopped()) {
|
||||
// also get the forum meta data.
|
||||
{
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
|
||||
std::list<RsGxsGroupId> grpIds;
|
||||
grpIds.push_back(mForumId);
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "GxsForumsFillThread::run() forum id " << mForumId << std::endl;
|
||||
#endif
|
||||
|
||||
service->requestGroupInfo(grp_token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds);
|
||||
|
||||
/* wait for the answer */
|
||||
uint32_t requestStatus = RsTokenService::PENDING;
|
||||
while (!wasStopped()) {
|
||||
requestStatus = service->requestStatus(grp_token);
|
||||
if (requestStatus == RsTokenService::FAILED ||
|
||||
requestStatus == RsTokenService::COMPLETE) {
|
||||
break;
|
||||
}
|
||||
msleep(200);
|
||||
}
|
||||
|
||||
if (requestStatus == RsTokenService::FAILED)
|
||||
return;
|
||||
}
|
||||
|
||||
if (wasStopped())
|
||||
{
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "GxsForumsFillThread::run() thread stopped, cancel request" << std::endl;
|
||||
#endif
|
||||
|
||||
/* cancel request */
|
||||
service->cancelRequest(token);
|
||||
service->cancelRequest(msg_token);
|
||||
service->cancelRequest(grp_token);
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestStatus == RsTokenService::FAILED) {
|
||||
//#TODO
|
||||
return;
|
||||
}
|
||||
|
||||
//#TODO
|
||||
// if (failed) {
|
||||
// mService->cancelRequest(token);
|
||||
// return;
|
||||
// }
|
||||
|
||||
emit status(tr("Retrieving"));
|
||||
|
||||
std::vector<RsGxsForumGroup> forum_groups;
|
||||
|
||||
if (!rsGxsForums->getGroupData(grp_token, forum_groups) || forum_groups.size() != 1)
|
||||
return;
|
||||
|
||||
RsGxsForumGroup forum_group = *forum_groups.begin();
|
||||
|
||||
//#ifdef DEBUG_FORUMS
|
||||
std::cerr << "Retrieved group data: " << std::endl;
|
||||
std::cerr << " Group ID: " << forum_group.mMeta.mGroupId << std::endl;
|
||||
std::cerr << " Admin lst: " << forum_group.mAdminList.ids.size() << " elements." << std::endl;
|
||||
for(auto it(forum_group.mAdminList.ids.begin());it!=forum_group.mAdminList.ids.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
std::cerr << " Pinned Post: " << forum_group.mPinnedPosts.ids.size() << " messages." << std::endl;
|
||||
for(auto it(forum_group.mPinnedPosts.ids.begin());it!=forum_group.mPinnedPosts.ids.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
//#endif
|
||||
|
||||
/* get messages */
|
||||
std::map<RsGxsMessageId,RsGxsForumMsg> msgs;
|
||||
|
||||
@ -152,9 +196,8 @@ void GxsForumsFillThread::run()
|
||||
|
||||
std::vector<RsGxsForumMsg> msgs_array;
|
||||
|
||||
if (!rsGxsForums->getMsgData(token, msgs_array)) {
|
||||
if (!rsGxsForums->getMsgData(msg_token, msgs_array))
|
||||
return;
|
||||
}
|
||||
|
||||
// now put everything into a map in order to make search log(n)
|
||||
|
||||
@ -178,11 +221,11 @@ void GxsForumsFillThread::run()
|
||||
// and tries to establish parenthood relationships between them, given that we only know the
|
||||
// immediate parent of a message and now its children. Some messages have a missing parent and for them
|
||||
// a fake top level parent is generated.
|
||||
|
||||
|
||||
// In order to be efficient, we first create a structure that lists the children of every mesage ID in the list.
|
||||
// Then the hierarchy of message is build by attaching the kids to every message until all of them have been processed.
|
||||
// The messages with missing parents will be the last ones remaining in the list.
|
||||
|
||||
|
||||
std::list<std::pair< RsGxsMessageId, QTreeWidgetItem* > > threadStack;
|
||||
std::map<RsGxsMessageId,std::list<RsGxsMessageId> > kids_array ;
|
||||
std::set<RsGxsMessageId> missing_parents;
|
||||
@ -209,11 +252,17 @@ void GxsForumsFillThread::run()
|
||||
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.
|
||||
// Make sure that the author is the same than the original message, or is a moderator. This should always happen when messages are constructed using
|
||||
// the UI but nothing can prevent a nasty user to craft a new version of a message with his own signature.
|
||||
|
||||
if(msgIt2->second.mMeta.mAuthorId != msgIt->second.mMeta.mAuthorId)
|
||||
continue ;
|
||||
{
|
||||
if( !IS_FORUM_MSG_MODERATION(msgIt->second.mMeta.mMsgFlags) ) // if authors are different the moderation flag needs to be set on the editing msg
|
||||
continue ;
|
||||
|
||||
if( forum_group.mAdminList.ids.find(msgIt->second.mMeta.mAuthorId)==forum_group.mAdminList.ids.end()) // if author is not a moderator, continue
|
||||
continue ;
|
||||
}
|
||||
|
||||
// always add the post a self version
|
||||
|
||||
@ -290,7 +339,7 @@ void GxsForumsFillThread::run()
|
||||
|
||||
// The next step is to find the top level thread messages. These are defined as the messages without
|
||||
// any parent message ID.
|
||||
|
||||
|
||||
// this trick is needed because while we remove messages, the parents a given msg may already have been removed
|
||||
// and wrongly understand as a missing parent.
|
||||
|
||||
@ -391,7 +440,7 @@ void GxsForumsFillThread::run()
|
||||
{
|
||||
// We iterate through the top level thread items, and look for which message has the current item as parent.
|
||||
// When found, the item is put in the thread list itself, as a potential new parent.
|
||||
|
||||
|
||||
std::map<RsGxsMessageId,RsGxsForumMsg>::iterator mit = msgs.find(*it2) ;
|
||||
|
||||
if(mit == msgs.end())
|
||||
|
Loading…
Reference in New Issue
Block a user