mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-04-10 09:49:24 -04:00
Merge branch 'master' into merge_alpha_master
This commit is contained in:
commit
4455bfa92d
@ -2,7 +2,7 @@ Source: retroshare06
|
||||
Section: devel
|
||||
Priority: standard
|
||||
Maintainer: Cyril Soler <csoler@users.sourceforge.net>
|
||||
Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev, libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default
|
||||
Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev (>= 3.4.0), libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default
|
||||
Standards-Version: 3.9.6
|
||||
Homepage: http://retroshare.sourceforge.net
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
version="0.6.2"
|
||||
gitpath="https://github.com/RetroShare/RetroShare.git"
|
||||
workdir=retroshare06-${version}
|
||||
branch="v0.6.2-official_release"
|
||||
#bubba3="Y" # comment out to compile for bubba3
|
||||
######################################################
|
||||
|
||||
@ -66,6 +67,7 @@ echo " "Commit count : ${ccount}
|
||||
echo " "Date : ${date}
|
||||
echo " "Time : ${time}
|
||||
echo " "Hash : ${hhsh}
|
||||
echo " "Using branch : ${branch}
|
||||
echo " "Using revision : ${rev}
|
||||
|
||||
echo Done.
|
||||
@ -80,7 +82,7 @@ echo Extracting base archive...
|
||||
mkdir -p ${workdir}/src
|
||||
echo Checking out latest snapshot...
|
||||
cd ${workdir}/src
|
||||
git clone --depth 1 https://github.com/RetroShare/RetroShare.git .
|
||||
git clone --depth 1 https://github.com/RetroShare/RetroShare.git --single-branch --branch $branch .
|
||||
cd -
|
||||
|
||||
if ! test -d ${workdir}/src/libretroshare/; then
|
||||
|
@ -58,7 +58,7 @@
|
||||
/*************************************/
|
||||
|
||||
UdpBitDht::UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string appVersion, std::string bootstrapfile, const std::string& filteredipfile, bdDhtFunctions *fns)
|
||||
:UdpSubReceiver(pub), dhtMtx(true), mFns(fns)
|
||||
:UdpSubReceiver(pub), dhtMtx(true)//, mFns(fns)
|
||||
{
|
||||
std::string usedVersion;
|
||||
|
||||
|
@ -119,7 +119,7 @@ void clearDataTransferred();
|
||||
|
||||
bdMutex dhtMtx; /* for all class data (below) */
|
||||
bdNodeManager *mBitDhtManager;
|
||||
bdDhtFunctions *mFns;
|
||||
//bdDhtFunctions *mFns;
|
||||
|
||||
|
||||
uint32_t mReadBytes;
|
||||
|
@ -103,8 +103,6 @@ int bdnet_inet_aton(const char *name, struct in_addr *addr);
|
||||
int bdnet_checkTTL(int fd);
|
||||
|
||||
void bdsockaddr_clear(struct sockaddr_in *addr);
|
||||
/* thread-safe version of inet_ntoa */
|
||||
std::string bdnet_inet_ntoa(struct in_addr in);
|
||||
|
||||
/* Extra stuff to declare for windows error handling (mimics unix errno)
|
||||
*/
|
||||
@ -175,4 +173,7 @@ int usleep(unsigned int usec);
|
||||
} /* C Interface */
|
||||
#endif
|
||||
|
||||
/* thread-safe version of inet_ntoa */
|
||||
std::string bdnet_inet_ntoa(struct in_addr in);
|
||||
|
||||
#endif /* BITDHT_UNIVERSAL_NETWORK_HEADER */
|
||||
|
@ -17,6 +17,10 @@
|
||||
#include "ChannelsHandler.h"
|
||||
#include "StatsHandler.h"
|
||||
|
||||
#ifdef LIBRESAPI_QT
|
||||
#include "SettingsHandler.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
data types in json http://json.org/
|
||||
string (utf-8 unicode)
|
||||
@ -237,6 +241,9 @@ public:
|
||||
mApiPluginHandler(sts, ifaces),
|
||||
mChannelsHandler(ifaces.mGxsChannels),
|
||||
mStatsHandler()
|
||||
#ifdef LIBRESAPI_QT
|
||||
,mSettingsHandler(sts)
|
||||
#endif
|
||||
{
|
||||
// the dynamic cast is to not confuse the addResourceHandler template like this:
|
||||
// addResourceHandler(derived class, parent class)
|
||||
@ -262,7 +269,11 @@ public:
|
||||
&ChannelsHandler::handleRequest);
|
||||
router.addResourceHandler("stats", dynamic_cast<ResourceRouter*>(&mStatsHandler),
|
||||
&StatsHandler::handleRequest);
|
||||
}
|
||||
#ifdef LIBRESAPI_QT
|
||||
router.addResourceHandler("settings", dynamic_cast<ResourceRouter*>(&mSettingsHandler),
|
||||
&SettingsHandler::handleRequest);
|
||||
#endif
|
||||
}
|
||||
|
||||
PeersHandler mPeersHandler;
|
||||
IdentityHandler mIdentityHandler;
|
||||
@ -274,6 +285,10 @@ public:
|
||||
ApiPluginHandler mApiPluginHandler;
|
||||
ChannelsHandler mChannelsHandler;
|
||||
StatsHandler mStatsHandler;
|
||||
|
||||
#ifdef LIBRESAPI_QT
|
||||
SettingsHandler mSettingsHandler;
|
||||
#endif
|
||||
};
|
||||
|
||||
ApiServer::ApiServer():
|
||||
@ -362,6 +377,9 @@ std::string ApiServer::handleRequest(Request &request)
|
||||
if(data.isRawData())
|
||||
return data.getRawData();
|
||||
|
||||
if(!resp.mCallbackName.empty())
|
||||
outstream << resource_api::makeKeyValueReference("callback_name", resp.mCallbackName);
|
||||
|
||||
outstream << resource_api::makeKeyValue("debug_msg", debugString.str());
|
||||
outstream << resource_api::makeKeyValueReference("returncode", returncode);
|
||||
if(!resp.mStateToken.isNull())
|
||||
|
@ -252,6 +252,9 @@ public:
|
||||
|
||||
StateToken mStateToken;
|
||||
|
||||
//Just for GUI benefit
|
||||
std::string mCallbackName;
|
||||
|
||||
// the result
|
||||
StreamBase& mDataStream;
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsidentity.h>
|
||||
#include <retroshare/rshistory.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
@ -165,6 +166,7 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs,
|
||||
addResourceHandler("lobbies", this, &ChatHandler::handleLobbies);
|
||||
addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby);
|
||||
addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby);
|
||||
addResourceHandler("autosubscribe_lobby", this, &ChatHandler::handleAutoSubsribeLobby);
|
||||
addResourceHandler("clear_lobby", this, &ChatHandler::handleClearLobby);
|
||||
addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants);
|
||||
addResourceHandler("messages", this, &ChatHandler::handleMessages);
|
||||
@ -908,6 +910,15 @@ void ChatHandler::handleUnsubscribeLobby(Request &req, Response &resp)
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void ChatHandler::handleAutoSubsribeLobby(Request& req, Response& resp)
|
||||
{
|
||||
ChatLobbyId chatId = 0;
|
||||
bool autosubsribe;
|
||||
req.mStream << makeKeyValueReference("chatid", chatId) << makeKeyValueReference("autosubsribe", autosubsribe);
|
||||
mRsMsgs->setLobbyAutoSubscribe(chatId, autosubsribe);
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void ChatHandler::handleClearLobby(Request &req, Response &resp)
|
||||
{
|
||||
ChatLobbyId id = 0;
|
||||
@ -949,13 +960,14 @@ void ChatHandler::handleMessages(Request &req, Response &resp)
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||
ChatId id(req.mPath.top());
|
||||
ChatId id(req.mPath.top());
|
||||
|
||||
// make response a list
|
||||
resp.mDataStream.getStreamToMember();
|
||||
if(id.isNotSet())
|
||||
{
|
||||
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
|
||||
return;
|
||||
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
|
||||
return;
|
||||
}
|
||||
std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(id);
|
||||
if(mit == mMsgs.end())
|
||||
@ -992,10 +1004,11 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp)
|
||||
void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp)
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||
ChatId id(req.mPath.top());
|
||||
ChatId id(req.mPath.top());
|
||||
|
||||
if(id.isNotSet())
|
||||
{
|
||||
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
|
||||
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
|
||||
return;
|
||||
}
|
||||
std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(id);
|
||||
|
@ -120,6 +120,7 @@ private:
|
||||
void handleLobbies(Request& req, Response& resp);
|
||||
void handleSubscribeLobby(Request& req, Response& resp);
|
||||
void handleUnsubscribeLobby(Request& req, Response& resp);
|
||||
void handleAutoSubsribeLobby(Request& req, Response& resp);
|
||||
void handleClearLobby(Request& req, Response& resp);
|
||||
ResponseTask* handleLobbyParticipants(Request& req, Response& resp);
|
||||
void handleMessages(Request& req, Response& resp);
|
||||
|
@ -10,8 +10,8 @@
|
||||
namespace resource_api
|
||||
{
|
||||
|
||||
FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles *files):
|
||||
mStateTokenServer(sts), mNotify(notify), mTurtle(turtle), mFiles(files),
|
||||
FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles */*files*/):
|
||||
mStateTokenServer(sts), mNotify(notify), mTurtle(turtle),// mFiles(files),
|
||||
mMtx("FileSearchHandler")
|
||||
{
|
||||
mNotify->registerNotifyClient(this);
|
||||
|
@ -24,7 +24,7 @@ private:
|
||||
StateTokenServer* mStateTokenServer;
|
||||
RsNotify* mNotify;
|
||||
RsTurtle* mTurtle;
|
||||
RsFiles* mFiles;
|
||||
//RsFiles* mFiles;
|
||||
|
||||
class Search{
|
||||
public:
|
||||
|
@ -103,9 +103,13 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden
|
||||
{
|
||||
mNotify->registerNotifyClient(this);
|
||||
|
||||
addResourceHandler("*", this, &IdentityHandler::handleWildcard);
|
||||
addResourceHandler("own", this, &IdentityHandler::handleOwn);
|
||||
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
|
||||
addResourceHandler("*", this, &IdentityHandler::handleWildcard);
|
||||
addResourceHandler("own", this, &IdentityHandler::handleOwn);
|
||||
|
||||
addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest);
|
||||
addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest);
|
||||
|
||||
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
|
||||
}
|
||||
|
||||
IdentityHandler::~IdentityHandler()
|
||||
@ -178,6 +182,112 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp)
|
||||
else resp.setFail();
|
||||
}
|
||||
|
||||
|
||||
void IdentityHandler::handleNotOwnIdsRequest(Request & /*req*/, Response &resp)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
uint32_t token;
|
||||
mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts);
|
||||
|
||||
time_t start = time(NULL);
|
||||
while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||
&&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||
&&((time(NULL) < (start+10)))
|
||||
)
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
Sleep(500);
|
||||
#else
|
||||
usleep(500*1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||
{
|
||||
std::vector<RsGxsIdGroup> grps;
|
||||
ok &= mRsIdentity->getGroupData(token, grps);
|
||||
for(std::vector<RsGxsIdGroup>::iterator vit = grps.begin(); vit != grps.end(); vit++)
|
||||
{
|
||||
RsGxsIdGroup& grp = *vit;
|
||||
//electron: not very happy about this, i think the flags should stay hidden in rsidentities
|
||||
if(!(grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) && grp.mIsAContact)
|
||||
{
|
||||
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ;
|
||||
resp.mDataStream.getStreamToMember()
|
||||
<< makeKeyValueReference("id", grp.mMeta.mGroupId) /// @deprecated using "id" as key can cause problems in some JS based languages like Qml @see gxs_id instead
|
||||
<< makeKeyValueReference("gxs_id", grp.mMeta.mGroupId)
|
||||
<< makeKeyValueReference("pgp_id",grp.mPgpId )
|
||||
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
|
||||
<< makeKeyValueReference("pgp_linked", pgp_linked);
|
||||
}
|
||||
}
|
||||
}
|
||||
else ok = false;
|
||||
|
||||
if(ok) resp.setOk();
|
||||
else resp.setFail();
|
||||
}
|
||||
|
||||
void IdentityHandler::handleOwnIdsRequest(Request & /*req*/, Response &resp)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
uint32_t token;
|
||||
mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts);
|
||||
|
||||
time_t start = time(NULL);
|
||||
while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||
&&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
||||
&&((time(NULL) < (start+10)))
|
||||
)
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
Sleep(500);
|
||||
#else
|
||||
usleep(500*1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||
{
|
||||
std::vector<RsGxsIdGroup> grps;
|
||||
ok &= mRsIdentity->getGroupData(token, grps);
|
||||
for(std::vector<RsGxsIdGroup>::iterator vit = grps.begin(); vit != grps.end(); vit++)
|
||||
{
|
||||
RsGxsIdGroup& grp = *vit;
|
||||
//electron: not very happy about this, i think the flags should stay hidden in rsidentities
|
||||
if(vit->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
|
||||
{
|
||||
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ;
|
||||
resp.mDataStream.getStreamToMember()
|
||||
<< makeKeyValueReference("own_gxs_id", grp.mMeta.mGroupId)
|
||||
<< makeKeyValueReference("pgp_id",grp.mPgpId )
|
||||
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
|
||||
<< makeKeyValueReference("pgp_linked", pgp_linked);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
ok = false;
|
||||
|
||||
if(ok) resp.setOk();
|
||||
else resp.setFail();
|
||||
}
|
||||
|
||||
ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp)
|
||||
{
|
||||
StateToken state;
|
||||
|
@ -23,6 +23,9 @@ public:
|
||||
|
||||
private:
|
||||
void handleWildcard(Request& req, Response& resp);
|
||||
void handleNotOwnIdsRequest(Request& req, Response& resp);
|
||||
void handleOwnIdsRequest(Request& req, Response& resp);
|
||||
|
||||
ResponseTask *handleOwn(Request& req, Response& resp);
|
||||
ResponseTask *handleCreateIdentity(Request& req, Response& resp);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include <util/radix64.h>
|
||||
#include <retroshare/rsstatus.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -12,6 +13,12 @@
|
||||
namespace resource_api
|
||||
{
|
||||
|
||||
#define PEER_STATE_ONLINE 1
|
||||
#define PEER_STATE_BUSY 2
|
||||
#define PEER_STATE_AWAY 3
|
||||
#define PEER_STATE_AVAILABLE 4
|
||||
#define PEER_STATE_INACTIVE 5
|
||||
#define PEER_STATE_OFFLINE 6
|
||||
// todo: groups, add friend, remove friend, permissions
|
||||
|
||||
void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details)
|
||||
@ -21,7 +28,50 @@ void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details)
|
||||
<< makeKeyValueReference("name", details.name)
|
||||
<< makeKeyValueReference("location", details.location)
|
||||
<< makeKeyValueReference("pgp_id", details.gpg_id)
|
||||
;
|
||||
<< makeKeyValueReference("pgp_id", details.gpg_id);
|
||||
|
||||
if(details.state & RS_PEER_STATE_CONNECTED)
|
||||
{
|
||||
std::list<StatusInfo> statusInfo;
|
||||
rsStatus->getStatusList(statusInfo);
|
||||
|
||||
std::string state_string;
|
||||
std::list<StatusInfo>::iterator it;
|
||||
for (it = statusInfo.begin(); it != statusInfo.end(); ++it)
|
||||
{
|
||||
if (it->id == details.id)
|
||||
{
|
||||
switch (it->status)
|
||||
{
|
||||
case RS_STATUS_INACTIVE:
|
||||
state_string = "inactive";
|
||||
break;
|
||||
|
||||
case RS_STATUS_ONLINE:
|
||||
state_string = "online";
|
||||
break;
|
||||
|
||||
case RS_STATUS_AWAY:
|
||||
state_string = "away";
|
||||
break;
|
||||
|
||||
case RS_STATUS_BUSY:
|
||||
state_string = "busy";
|
||||
break;
|
||||
default:
|
||||
state_string = "undefined";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
stream << makeKeyValueReference("state_string", state_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string state_string = "undefined";
|
||||
stream << makeKeyValueReference("state_string", state_string);
|
||||
}
|
||||
}
|
||||
|
||||
bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list<RsGroupInfo>& grpInfo, bool have_avatar)
|
||||
@ -29,7 +79,9 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers
|
||||
bool ok = true;
|
||||
peerDetailsToStream(stream, details);
|
||||
stream << makeKeyValue("is_online", peers->isOnline(details.id))
|
||||
<< makeKeyValue("chat_id", ChatId(details.id).toStdString());
|
||||
<< makeKeyValue("chat_id", ChatId(details.id).toStdString())
|
||||
<< makeKeyValue("custom_state_string", rsMsgs->getCustomStateString(details.id));
|
||||
|
||||
|
||||
std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image";
|
||||
|
||||
@ -63,7 +115,13 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee
|
||||
mNotify->registerNotifyClient(this);
|
||||
mStateTokenServer->registerTickClient(this);
|
||||
addResourceHandler("*", this, &PeersHandler::handleWildcard);
|
||||
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert);
|
||||
addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString);
|
||||
addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString);
|
||||
addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString);
|
||||
addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString);
|
||||
addResourceHandler("get_pgp_options", this, &PeersHandler::handleGetPGPOptions);
|
||||
addResourceHandler("set_pgp_options", this, &PeersHandler::handleSetPGPOptions);
|
||||
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert);
|
||||
}
|
||||
|
||||
PeersHandler::~PeersHandler()
|
||||
@ -100,6 +158,27 @@ void PeersHandler::tick()
|
||||
mStateTokenServer->discardToken(mStateToken);
|
||||
mStateToken = mStateTokenServer->getNewToken();
|
||||
}
|
||||
|
||||
StatusInfo statusInfo;
|
||||
rsStatus->getOwnStatus(statusInfo);
|
||||
if(statusInfo.status != status)
|
||||
{
|
||||
status = statusInfo.status;
|
||||
|
||||
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
||||
mStateTokenServer->discardToken(mStringStateToken);
|
||||
mStringStateToken = mStateTokenServer->getNewToken();
|
||||
}
|
||||
|
||||
std::string custom_state = rsMsgs->getCustomStateString();
|
||||
if(custom_state != custom_state_string)
|
||||
{
|
||||
custom_state_string = custom_state;
|
||||
|
||||
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
||||
mStateTokenServer->discardToken(mCustomStateToken);
|
||||
mCustomStateToken = mStateTokenServer->getNewToken();
|
||||
}
|
||||
}
|
||||
|
||||
void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count)
|
||||
@ -121,6 +200,73 @@ static bool have_avatar(RsMsgs* msgs, const RsPeerId& id)
|
||||
return size != 0;
|
||||
}
|
||||
|
||||
void PeersHandler::handleGetStateString(Request& /*req*/, Response& resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStringStateToken;
|
||||
}
|
||||
|
||||
std::string state_string;
|
||||
StatusInfo statusInfo;
|
||||
if (rsStatus->getOwnStatus(statusInfo))
|
||||
{
|
||||
if(statusInfo.status == RS_STATUS_ONLINE)
|
||||
state_string = "online";
|
||||
else if(statusInfo.status == RS_STATUS_BUSY)
|
||||
state_string = "busy";
|
||||
else if(statusInfo.status == RS_STATUS_AWAY)
|
||||
state_string = "away";
|
||||
else if(statusInfo.status == RS_STATUS_INACTIVE)
|
||||
state_string = "inactive";
|
||||
else
|
||||
state_string = "undefined";
|
||||
}
|
||||
else
|
||||
state_string = "undefined";
|
||||
|
||||
resp.mDataStream << makeKeyValueReference("state_string", state_string);
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void PeersHandler::handleSetStateString(Request& req, Response& resp)
|
||||
{
|
||||
std::string state_string;
|
||||
req.mStream << makeKeyValueReference("state_string", state_string);
|
||||
|
||||
uint32_t status = RS_STATUS_OFFLINE;
|
||||
if(state_string == "online")
|
||||
status = RS_STATUS_ONLINE;
|
||||
else if(state_string == "busy")
|
||||
status = RS_STATUS_BUSY;
|
||||
else if(state_string == "away")
|
||||
status = RS_STATUS_AWAY;
|
||||
|
||||
rsStatus->sendStatus(RsPeerId(), status);
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void PeersHandler::handleGetCustomStateString(Request& /*req*/, Response& resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mCustomStateToken;
|
||||
}
|
||||
|
||||
std::string custom_state_string = rsMsgs->getCustomStateString();
|
||||
resp.mDataStream << makeKeyValueReference("custom_state_string", custom_state_string);
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void PeersHandler::handleSetCustomStateString(Request& req, Response& resp)
|
||||
{
|
||||
std::string custom_state_string;
|
||||
req.mStream << makeKeyValueReference("custom_state_string", custom_state_string);
|
||||
|
||||
rsMsgs->setCustomStateString(custom_state_string);
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void PeersHandler::handleWildcard(Request &req, Response &resp)
|
||||
{
|
||||
bool ok = false;
|
||||
@ -176,6 +322,9 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
|
||||
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
||||
unread_msgs = mUnreadMsgsCounts;
|
||||
}
|
||||
std::list<StatusInfo> statusInfo;
|
||||
rsStatus->getStatusList(statusInfo);
|
||||
|
||||
// list all peers
|
||||
ok = true;
|
||||
std::list<RsPgpId> identities;
|
||||
@ -216,6 +365,11 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
|
||||
StreamBase& locationStream = itemStream.getStreamToMember("locations");
|
||||
// mark as list (in case list is empty)
|
||||
locationStream.getStreamToMember();
|
||||
|
||||
int bestPeerState = 0;
|
||||
unsigned int bestRSState = 0;
|
||||
std::string bestCustomStateString;
|
||||
|
||||
for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit)
|
||||
{
|
||||
if(vit->gpg_id == *lit)
|
||||
@ -226,8 +380,85 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
|
||||
unread = unread_msgs.find(vit->id)->second;
|
||||
stream << makeKeyValueReference("unread_msgs", unread);
|
||||
peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id));
|
||||
}
|
||||
|
||||
|
||||
/* Custom state string */
|
||||
std::string customStateString;
|
||||
if (vit->state & RS_PEER_STATE_CONNECTED)
|
||||
{
|
||||
customStateString = rsMsgs->getCustomStateString(vit->id);
|
||||
}
|
||||
|
||||
int peerState = 0;
|
||||
|
||||
if (vit->state & RS_PEER_STATE_CONNECTED)
|
||||
{
|
||||
// get the status info for this ssl id
|
||||
int rsState = 0;
|
||||
std::list<StatusInfo>::iterator it;
|
||||
for (it = statusInfo.begin(); it != statusInfo.end(); ++it)
|
||||
{
|
||||
if (it->id == vit->id)
|
||||
{
|
||||
rsState = it->status;
|
||||
switch (rsState)
|
||||
{
|
||||
case RS_STATUS_INACTIVE:
|
||||
peerState = PEER_STATE_INACTIVE;
|
||||
break;
|
||||
|
||||
case RS_STATUS_ONLINE:
|
||||
peerState = PEER_STATE_ONLINE;
|
||||
break;
|
||||
|
||||
case RS_STATUS_AWAY:
|
||||
peerState = PEER_STATE_AWAY;
|
||||
break;
|
||||
|
||||
case RS_STATUS_BUSY:
|
||||
peerState = PEER_STATE_BUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* find the best ssl contact for the gpg item */
|
||||
if (bestPeerState == 0 || peerState < bestPeerState)
|
||||
{
|
||||
bestPeerState = peerState;
|
||||
bestRSState = rsState;
|
||||
bestCustomStateString = customStateString;
|
||||
}
|
||||
else if (peerState == bestPeerState)
|
||||
{
|
||||
/* equal state */
|
||||
if (bestCustomStateString.empty() && !customStateString.empty())
|
||||
{
|
||||
bestPeerState = peerState;
|
||||
bestRSState = rsState;
|
||||
bestCustomStateString = customStateString;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
itemStream << makeKeyValue("custom_state_string", bestCustomStateString);
|
||||
|
||||
std::string state_string;
|
||||
|
||||
if(bestRSState == RS_STATUS_ONLINE)
|
||||
state_string = "online";
|
||||
else if(bestRSState == RS_STATUS_BUSY)
|
||||
state_string = "busy";
|
||||
else if(bestRSState == RS_STATUS_AWAY)
|
||||
state_string = "away";
|
||||
else if(bestRSState == RS_STATUS_INACTIVE)
|
||||
state_string = "inactive";
|
||||
else
|
||||
state_string = "undefined";
|
||||
|
||||
itemStream << makeKeyValue("state_string", state_string);
|
||||
}
|
||||
resp.mStateToken = getCurrentStateToken();
|
||||
}
|
||||
@ -300,6 +531,120 @@ void PeersHandler::handleExamineCert(Request &req, Response &resp)
|
||||
}
|
||||
}
|
||||
|
||||
void PeersHandler::handleGetPGPOptions(Request& req, Response& resp)
|
||||
{
|
||||
std::string pgp_id;
|
||||
req.mStream << makeKeyValueReference("pgp_id", pgp_id);
|
||||
|
||||
RsPgpId pgp(pgp_id);
|
||||
RsPeerDetails detail;
|
||||
|
||||
if(!mRsPeers->getGPGDetails(pgp, detail))
|
||||
{
|
||||
resp.setFail();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string pgp_key = mRsPeers->getPGPKey(detail.gpg_id, false);
|
||||
|
||||
resp.mDataStream << makeKeyValue("pgp_fingerprint", detail.fpr.toStdString());
|
||||
resp.mDataStream << makeKeyValueReference("pgp_key", pgp_key);
|
||||
|
||||
resp.mDataStream << makeKeyValue("direct_transfer", detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL);
|
||||
resp.mDataStream << makeKeyValue("allow_push", detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH);
|
||||
resp.mDataStream << makeKeyValue("require_WL", detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL);
|
||||
|
||||
resp.mDataStream << makeKeyValue("own_sign", detail.ownsign);
|
||||
resp.mDataStream << makeKeyValue("trustLvl", detail.trustLvl);
|
||||
|
||||
uint32_t max_upload_speed = 0;
|
||||
uint32_t max_download_speed = 0;
|
||||
|
||||
mRsPeers->getPeerMaximumRates(pgp, max_upload_speed, max_download_speed);
|
||||
|
||||
resp.mDataStream << makeKeyValueReference("maxUploadSpeed", max_upload_speed);
|
||||
resp.mDataStream << makeKeyValueReference("maxDownloadSpeed", max_download_speed);
|
||||
|
||||
StreamBase& signersStream = resp.mDataStream.getStreamToMember("gpg_signers");
|
||||
|
||||
// mark as list (in case list is empty)
|
||||
signersStream.getStreamToMember();
|
||||
|
||||
for(std::list<RsPgpId>::const_iterator it(detail.gpgSigners.begin()); it != detail.gpgSigners.end(); ++it)
|
||||
{
|
||||
RsPeerDetails detail;
|
||||
if(!mRsPeers->getGPGDetails(*it, detail))
|
||||
continue;
|
||||
|
||||
std::string pgp_id = (*it).toStdString();
|
||||
std::string name = detail.name;
|
||||
|
||||
signersStream.getStreamToMember()
|
||||
<< makeKeyValueReference("pgp_id", pgp_id)
|
||||
<< makeKeyValueReference("name", name);
|
||||
}
|
||||
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
void PeersHandler::handleSetPGPOptions(Request& req, Response& resp)
|
||||
{
|
||||
std::string pgp_id;
|
||||
req.mStream << makeKeyValueReference("pgp_id", pgp_id);
|
||||
|
||||
RsPgpId pgp(pgp_id);
|
||||
RsPeerDetails detail;
|
||||
|
||||
if(!mRsPeers->getGPGDetails(pgp, detail))
|
||||
{
|
||||
resp.setFail();
|
||||
return;
|
||||
}
|
||||
|
||||
int trustLvl;
|
||||
req.mStream << makeKeyValueReference("trustLvl", trustLvl);
|
||||
|
||||
if(trustLvl != (int)detail.trustLvl)
|
||||
mRsPeers->trustGPGCertificate(pgp, trustLvl);
|
||||
|
||||
int max_upload_speed;
|
||||
int max_download_speed;
|
||||
|
||||
req.mStream << makeKeyValueReference("max_upload_speed", max_upload_speed);
|
||||
req.mStream << makeKeyValueReference("max_download_speed", max_download_speed);
|
||||
|
||||
mRsPeers->setPeerMaximumRates(pgp, (uint32_t)max_upload_speed, (uint32_t)max_download_speed);
|
||||
|
||||
bool direct_transfer;
|
||||
bool allow_push;
|
||||
bool require_WL;
|
||||
|
||||
req.mStream << makeKeyValueReference("direct_transfer", direct_transfer);
|
||||
req.mStream << makeKeyValueReference("allow_push", allow_push);
|
||||
req.mStream << makeKeyValueReference("require_WL", require_WL);
|
||||
|
||||
ServicePermissionFlags flags(0);
|
||||
|
||||
if(direct_transfer)
|
||||
flags = flags | RS_NODE_PERM_DIRECT_DL;
|
||||
if(allow_push)
|
||||
flags = flags | RS_NODE_PERM_ALLOW_PUSH;
|
||||
if(require_WL)
|
||||
flags = flags | RS_NODE_PERM_REQUIRE_WL;
|
||||
|
||||
mRsPeers->setServicePermissionFlags(pgp, flags);
|
||||
|
||||
bool own_sign;
|
||||
req.mStream << makeKeyValueReference("own_sign", own_sign);
|
||||
|
||||
if(own_sign)
|
||||
mRsPeers->signGPGCertificate(pgp);
|
||||
|
||||
resp.mStateToken = getCurrentStateToken();
|
||||
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
StateToken PeersHandler::getCurrentStateToken()
|
||||
{
|
||||
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
||||
|
@ -35,6 +35,15 @@ private:
|
||||
void handleWildcard(Request& req, Response& resp);
|
||||
void handleExamineCert(Request& req, Response& resp);
|
||||
|
||||
void handleGetStateString(Request& req, Response& resp);
|
||||
void handleSetStateString(Request& req, Response& resp);
|
||||
|
||||
void handleGetCustomStateString(Request& req, Response& resp);
|
||||
void handleSetCustomStateString(Request& req, Response& resp);
|
||||
|
||||
void handleGetPGPOptions(Request& req, Response& resp);
|
||||
void handleSetPGPOptions(Request& req, Response& resp);
|
||||
|
||||
// a helper which ensures proper mutex locking
|
||||
StateToken getCurrentStateToken();
|
||||
|
||||
@ -44,9 +53,14 @@ private:
|
||||
RsMsgs* mRsMsgs; // required for avatar data
|
||||
|
||||
std::list<RsPeerId> mOnlinePeers;
|
||||
uint32_t status;
|
||||
std::string custom_state_string;
|
||||
|
||||
RsMutex mMtx;
|
||||
StateToken mStateToken; // mutex protected
|
||||
StateToken mStringStateToken; // mutex protected
|
||||
StateToken mCustomStateToken; // mutex protected
|
||||
|
||||
std::map<RsPeerId, uint32_t> mUnreadMsgsCounts;
|
||||
};
|
||||
} // namespace resource_api
|
||||
|
@ -37,6 +37,13 @@ ResponseTask* ResourceRouter::handleRequest(Request& req, Response& resp)
|
||||
if(vit->first == req.mPath.top())
|
||||
{
|
||||
req.mPath.pop();
|
||||
|
||||
//Just for GUI benefit
|
||||
std::string callbackName;
|
||||
req.mStream << makeKeyValueReference("callback_name", callbackName);
|
||||
resp.mCallbackName = callbackName;
|
||||
//
|
||||
|
||||
return vit->second->handleRequest(req, resp);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <retroshare/rsinit.h>
|
||||
#include <retroshare/rsiface.h>
|
||||
#include <util/rsdir.h>
|
||||
|
||||
#include "api/ApiServer.h"
|
||||
#include "api/Operators.h"
|
||||
@ -23,7 +24,9 @@ RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, A
|
||||
mDataMtx("RsControlModule::mDataMtx"),
|
||||
mRunState(WAITING_INIT),
|
||||
mAutoLoginNextTime(false),
|
||||
mWantPassword(false)
|
||||
mWantPassword(false),
|
||||
mPassword(""),
|
||||
mPrevIsBad(false)
|
||||
{
|
||||
mStateToken = sts->getNewToken();
|
||||
this->argc = argc;
|
||||
@ -55,13 +58,16 @@ bool RsControlModule::processShouldExit()
|
||||
return mProcessShouldExit;
|
||||
}
|
||||
|
||||
bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool /* prev_is_bad */, std::string &password, bool& cancelled)
|
||||
bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool prev_is_bad, std::string &password, bool& cancelled)
|
||||
{
|
||||
cancelled = false ;
|
||||
{
|
||||
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
|
||||
|
||||
mPrevIsBad = prev_is_bad;
|
||||
|
||||
if(mFixedPassword != "")
|
||||
{
|
||||
{
|
||||
password = mFixedPassword;
|
||||
return true;
|
||||
}
|
||||
@ -69,25 +75,31 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string
|
||||
mWantPassword = true;
|
||||
mTitle = title;
|
||||
mKeyName = key_details;
|
||||
mPassword = "";
|
||||
|
||||
if(mPassword != "")
|
||||
{
|
||||
password = mPassword;
|
||||
mWantPassword = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mStateTokenServer->replaceToken(mStateToken);
|
||||
}
|
||||
|
||||
bool wait = true;
|
||||
while(wait)
|
||||
int i = 0;
|
||||
while(i<100)
|
||||
{
|
||||
usleep(5*1000);
|
||||
|
||||
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
|
||||
wait = mWantPassword;
|
||||
if(!wait && mPassword != "")
|
||||
|
||||
if(mPassword != "")
|
||||
{
|
||||
password = mPassword;
|
||||
mPassword = "";
|
||||
password = mPassword;
|
||||
mWantPassword = false;
|
||||
mStateTokenServer->replaceToken(mStateToken);
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -124,6 +136,11 @@ void RsControlModule::run()
|
||||
bool login_ok = false;
|
||||
while(!login_ok)
|
||||
{
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
mPassword = "";
|
||||
}
|
||||
|
||||
// skip account selection if autologin is available
|
||||
if(initResult != RS_INIT_HAVE_ACCOUNT)
|
||||
setRunState(WAITING_ACCOUNT_SELECT);
|
||||
@ -174,8 +191,19 @@ void RsControlModule::run()
|
||||
std::cerr << "RsControlModule::run() LockAndLoadCertificates failed. Unexpected switch value: " << retVal << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
mLoadPeerId.clear();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
mFixedPassword = mPassword;
|
||||
mPassword = "";
|
||||
}
|
||||
|
||||
setRunState(WAITING_STARTUP);
|
||||
|
||||
std::cerr << "RsControlModule: login ok, starting Retroshare worker threads..." << std::endl;
|
||||
@ -305,7 +333,8 @@ void RsControlModule::handlePassword(Request &req, Response &resp)
|
||||
|
||||
resp.mDataStream
|
||||
<< makeKeyValueReference("want_password", mWantPassword)
|
||||
<< makeKeyValueReference("key_name", mKeyName);
|
||||
<< makeKeyValueReference("key_name", mKeyName)
|
||||
<< makeKeyValueReference("prev_is_bad", mPrevIsBad);
|
||||
resp.mStateToken = mStateToken;
|
||||
resp.setOk();
|
||||
}
|
||||
@ -425,17 +454,17 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
|
||||
RsPeerId ssl_id;
|
||||
std::string err_string;
|
||||
// give the password to the password callback
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
mFixedPassword = pgp_password;
|
||||
}
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
mFixedPassword = pgp_password;
|
||||
}
|
||||
bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string);
|
||||
|
||||
// clear fixed password to restore normal password operation
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
mFixedPassword = "";
|
||||
}
|
||||
// {
|
||||
// RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
// mFixedPassword = "";
|
||||
// }
|
||||
|
||||
if (ssl_ok)
|
||||
{
|
||||
@ -456,6 +485,20 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
|
||||
resp.setFail("could not create a new location. Error: "+err_string);
|
||||
}
|
||||
|
||||
bool RsControlModule::askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason /*=""*/)
|
||||
{
|
||||
if(rsPeers->gpgSignData(data,len,sign,signlen,reason))
|
||||
{
|
||||
signature_result = SELF_SIGNATURE_RESULT_SUCCESS;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
signature_result = SELF_SIGNATURE_RESULT_FAILED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RsControlModule::setRunState(RunState s, std::string errstr)
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
|
@ -31,8 +31,9 @@ public:
|
||||
// returns true if the process should terminate
|
||||
bool processShouldExit();
|
||||
|
||||
// from NotifyClient
|
||||
virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled);
|
||||
// from NotifyClient
|
||||
virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled) override;
|
||||
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override;
|
||||
|
||||
protected:
|
||||
// from RsThread
|
||||
@ -76,6 +77,7 @@ private:
|
||||
// to notify that a password callback is waiting
|
||||
// to answer the request, clear the flag and set the password
|
||||
bool mWantPassword;
|
||||
bool mPrevIsBad;
|
||||
std::string mTitle;
|
||||
std::string mKeyName;
|
||||
std::string mPassword;
|
||||
|
182
libresapi/src/api/SettingsHandler.cpp
Normal file
182
libresapi/src/api/SettingsHandler.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
#include "SettingsHandler.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <retroshare/rsinit.h>
|
||||
|
||||
namespace resource_api
|
||||
{
|
||||
#define SETTINGS_FILE (QString::fromUtf8(RsAccounts::AccountDirectory().c_str()) + "/Sonet.conf")
|
||||
|
||||
SettingsHandler::SettingsHandler(StateTokenServer *sts, const QString settingsGroup) :
|
||||
QSettings(SETTINGS_FILE, QSettings::IniFormat),
|
||||
mStateTokenServer(sts),
|
||||
mMtx("SettingsHandler Mutex"),
|
||||
mStateToken(sts->getNewToken())
|
||||
{
|
||||
RsPeerId sPreferedId;
|
||||
m_bValid = RsAccounts::GetPreferredAccountId(sPreferedId);
|
||||
|
||||
if (!settingsGroup.isEmpty())
|
||||
beginGroup(settingsGroup);
|
||||
|
||||
addResourceHandler("*", this, &SettingsHandler::handleSettingsRequest);
|
||||
addResourceHandler("get_advanced_mode", this, &SettingsHandler::handleGetAdvancedMode);
|
||||
addResourceHandler("set_advanced_mode", this, &SettingsHandler::handleSetAdvancedMode);
|
||||
addResourceHandler("get_flickable_grid_mode", this, &SettingsHandler::handleGetFlickableGridMode);
|
||||
addResourceHandler("set_flickable_grid_mode", this, &SettingsHandler::handleSetFlickableGridMode);
|
||||
addResourceHandler("get_auto_login", this, &SettingsHandler::handleGetAutoLogin);
|
||||
addResourceHandler("set_auto_login", this, &SettingsHandler::handleSetAutoLogin);
|
||||
}
|
||||
|
||||
SettingsHandler::~SettingsHandler()
|
||||
{
|
||||
sync();
|
||||
}
|
||||
|
||||
void SettingsHandler::handleSettingsRequest(Request &/*req*/, Response &resp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SettingsHandler::handleGetAdvancedMode(Request &/*req*/, Response &resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
|
||||
bool advanced_mode = valueFromGroup("General", "Advanced", false).toBool();
|
||||
resp.mDataStream << makeKeyValueReference("advanced_mode", advanced_mode);
|
||||
resp.setOk();
|
||||
sync();
|
||||
}
|
||||
|
||||
void SettingsHandler::handleSetAdvancedMode(Request &req, Response &resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
|
||||
bool advanced_mode;
|
||||
req.mStream << makeKeyValueReference("advanced_mode", advanced_mode);
|
||||
setValueToGroup("General", "Advanced", advanced_mode);
|
||||
resp.setOk();
|
||||
sync();
|
||||
}
|
||||
|
||||
void SettingsHandler::handleGetFlickableGridMode(Request &/*req*/, Response &resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
|
||||
bool flickable_grid_mode = valueFromGroup("General", "FlickableGrid", false).toBool();
|
||||
resp.mDataStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode);
|
||||
resp.setOk();
|
||||
sync();
|
||||
}
|
||||
|
||||
void SettingsHandler::handleSetFlickableGridMode(Request &req, Response &resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
|
||||
bool flickable_grid_mode;
|
||||
req.mStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode);
|
||||
setValueToGroup("General", "FlickableGrid", flickable_grid_mode);
|
||||
|
||||
resp.setOk();
|
||||
sync();
|
||||
}
|
||||
|
||||
void SettingsHandler::handleGetAutoLogin(Request &/*req*/, Response &resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
|
||||
bool autoLogin = RsInit::getAutoLogin();;
|
||||
resp.mDataStream << makeKeyValueReference("auto_login", autoLogin);
|
||||
resp.setOk();
|
||||
sync();
|
||||
}
|
||||
|
||||
void SettingsHandler::handleSetAutoLogin(Request &req, Response &resp)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
|
||||
bool autoLogin;
|
||||
req.mStream << makeKeyValueReference("auto_login", autoLogin);
|
||||
RsInit::setAutoLogin(autoLogin);
|
||||
|
||||
resp.setOk();
|
||||
sync();
|
||||
}
|
||||
|
||||
QVariant SettingsHandler::value(const QString &key, const QVariant &defaultVal) const
|
||||
{
|
||||
if (m_bValid == false)
|
||||
{
|
||||
return defaultVal.isNull() ? defaultValue(key) : defaultVal;
|
||||
}
|
||||
return QSettings::value(key, defaultVal.isNull() ? defaultValue(key) : defaultVal);
|
||||
}
|
||||
|
||||
void SettingsHandler::setValue(const QString &key, const QVariant &val)
|
||||
{
|
||||
if (m_bValid == false)
|
||||
{
|
||||
std::cerr << "RSettings::setValue() Calling on invalid object, key = " << key.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
if (val == defaultValue(key))
|
||||
QSettings::remove(key);
|
||||
else if (val != value(key))
|
||||
QSettings::setValue(key, val);
|
||||
}
|
||||
|
||||
QVariant SettingsHandler::valueFromGroup(const QString &group, const QString &key, const QVariant &defaultVal)
|
||||
{
|
||||
beginGroup(group);
|
||||
QVariant val = value(key, defaultVal);
|
||||
endGroup();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void SettingsHandler::setValueToGroup(const QString &group, const QString &key, const QVariant &val)
|
||||
{
|
||||
beginGroup(group);
|
||||
setValue(key, val);
|
||||
endGroup();
|
||||
}
|
||||
|
||||
void SettingsHandler::setDefault(const QString &key, const QVariant &val)
|
||||
{
|
||||
_defaults.insert(key, val);
|
||||
}
|
||||
|
||||
QVariant SettingsHandler::defaultValue(const QString &key) const
|
||||
{
|
||||
if (_defaults.contains(key))
|
||||
return _defaults.value(key);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void SettingsHandler::reset()
|
||||
{
|
||||
/* Static method, so we have to create a QSettings object. */
|
||||
QSettings settings(SETTINGS_FILE, QSettings::IniFormat);
|
||||
settings.clear();
|
||||
}
|
||||
} // namespace resource_api
|
||||
|
59
libresapi/src/api/SettingsHandler.h
Normal file
59
libresapi/src/api/SettingsHandler.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef SETTINGSHANDLER_H
|
||||
#define SETTINGSHANDLER_H
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <util/rsthreads.h>
|
||||
|
||||
#include "ResourceRouter.h"
|
||||
#include "StateTokenServer.h"
|
||||
|
||||
/* Reimplemented class RSettings*/
|
||||
namespace resource_api
|
||||
{
|
||||
class SettingsHandler : public ResourceRouter, public QSettings
|
||||
{
|
||||
public:
|
||||
SettingsHandler(StateTokenServer* sts, const QString group = QString());
|
||||
~SettingsHandler();
|
||||
|
||||
static void reset();
|
||||
|
||||
QVariant value(const QString &key,
|
||||
const QVariant &defaultVal = QVariant()) const;
|
||||
|
||||
void setValue(const QString &key, const QVariant &val);
|
||||
|
||||
QVariant valueFromGroup(const QString &group, const QString &key,
|
||||
const QVariant &defaultVal = QVariant());
|
||||
void setValueToGroup(const QString &group, const QString &key,
|
||||
const QVariant &val);
|
||||
|
||||
protected:
|
||||
void setDefault(const QString &key, const QVariant &val);
|
||||
QVariant defaultValue(const QString &key) const;
|
||||
|
||||
bool m_bValid;
|
||||
|
||||
private:
|
||||
void handleSettingsRequest(Request& req, Response& resp);
|
||||
|
||||
void handleGetAdvancedMode(Request& req, Response& resp);
|
||||
void handleSetAdvancedMode(Request& req, Response& resp);
|
||||
|
||||
void handleGetFlickableGridMode(Request& req, Response& resp);
|
||||
void handleSetFlickableGridMode(Request& req, Response& resp);
|
||||
|
||||
void handleGetAutoLogin(Request& req, Response& resp);
|
||||
void handleSetAutoLogin(Request& req, Response& resp);
|
||||
|
||||
QHash<QString, QVariant> _defaults;
|
||||
|
||||
StateTokenServer* mStateTokenServer;
|
||||
|
||||
RsMutex mMtx;
|
||||
StateToken mStateToken; // mutex protected
|
||||
};
|
||||
} // namespace resource_api
|
||||
|
||||
#endif // SETTINGSHANDLER_H
|
@ -10,6 +10,40 @@ DESTDIR = lib
|
||||
|
||||
INCLUDEPATH += ../../libretroshare/src
|
||||
|
||||
retroshare_android_service {
|
||||
win32 {
|
||||
OBJECTS_DIR = temp/obj
|
||||
|
||||
LIBS_DIR = $$PWD/../../libs/lib
|
||||
LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a
|
||||
LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a
|
||||
|
||||
for(lib, LIB_DIR):LIBS += -L"$$lib"
|
||||
for(bin, BIN_DIR):LIBS += -L"$$bin"
|
||||
|
||||
|
||||
LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32
|
||||
LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32
|
||||
LIBS += -lwinmm
|
||||
|
||||
DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
|
||||
|
||||
DEPENDPATH += . $$INC_DIR
|
||||
INCLUDEPATH += . $$INC_DIR
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
# Qt 5
|
||||
RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src
|
||||
} else {
|
||||
# Qt 4
|
||||
QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src
|
||||
}
|
||||
}
|
||||
|
||||
DEPENDPATH += . ../../libretroshare/src/
|
||||
INCLUDEPATH += ../../libretroshare/src/
|
||||
}
|
||||
|
||||
libresapihttpserver {
|
||||
CONFIG += libmicrohttpd
|
||||
|
||||
@ -183,3 +217,11 @@ libresapilocalserver {
|
||||
SOURCES *= api/ApiServerLocal.cpp
|
||||
HEADERS *= api/ApiServerLocal.h
|
||||
}
|
||||
|
||||
qt_dependencies {
|
||||
CONFIG *= qt
|
||||
QT *= core
|
||||
|
||||
SOURCES += api/SettingsHandler.cpp
|
||||
HEADERS += api/SettingsHandler.h
|
||||
}
|
||||
|
@ -459,8 +459,12 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
|
||||
msgMeta.signSet.TlvClear();
|
||||
|
||||
RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId;
|
||||
msgMeta.mOrigMsgId.clear();
|
||||
|
||||
if(msgMeta.mOrigMsgId == msgMeta.mMsgId) // message is not versionned, then the signature was made with mOrigMsgId==NULL
|
||||
msgMeta.mOrigMsgId.clear();
|
||||
|
||||
msgMeta.mMsgId.clear();
|
||||
|
||||
int signOk = 0 ;
|
||||
|
||||
{
|
||||
|
@ -1270,6 +1270,58 @@ bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMa
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsGenExchange::getSerializedGroupData(const uint32_t &token, RsGxsGroupId& id,unsigned char *& data,uint32_t& size)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
|
||||
std::list<RsNxsGrp*> nxsGrps;
|
||||
|
||||
if(!mDataAccess->getGroupData(token, nxsGrps))
|
||||
return false ;
|
||||
|
||||
if(nxsGrps.size() != 1)
|
||||
{
|
||||
std::cerr << "(EE) getSerializedGroupData() got multiple groups in single request. This is unexpected." << std::endl;
|
||||
|
||||
for(std::list<RsNxsGrp*>::const_iterator it(nxsGrps.begin());it!=nxsGrps.end();++it)
|
||||
delete *it ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
RsNxsGrp *nxs_grp = *(nxsGrps.begin());
|
||||
|
||||
size = nxs_grp->serial_size() ;
|
||||
id = nxs_grp->metaData->mGroupId ;
|
||||
|
||||
if(size > 1024*1024 || NULL==(data = (unsigned char *)rs_malloc(size)))
|
||||
{
|
||||
std::cerr << "(EE) getSerializedGroupData() cannot allocate mem chunk of size " << size << ". Too big, or no room." << std::endl;
|
||||
delete nxs_grp ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
return nxs_grp->serialise(data,size) ;
|
||||
}
|
||||
|
||||
bool RsGenExchange::deserializeGroupData(unsigned char *data,uint32_t size)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
|
||||
RsItem *item = RsNxsSerialiser(mServType).deserialise(data, &size);
|
||||
|
||||
RsNxsGrp *nxs_grp = dynamic_cast<RsNxsGrp*>(item) ;
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
std::cerr << "(EE) RsGenExchange::deserializeGroupData(): cannot deserialise this data. Something's wrong." << std::endl;
|
||||
delete item ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
mReceivedGrps.push_back( GxsPendingItem<RsNxsGrp*, RsGxsGroupId>(nxs_grp, nxs_grp->grpId,time(NULL)) );
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem *>& grpItem)
|
||||
{
|
||||
@ -2135,7 +2187,9 @@ void RsGenExchange::publishMsgs()
|
||||
if(createOk && validSize)
|
||||
{
|
||||
// empty orig msg id means this is the original
|
||||
// msg
|
||||
// msg.
|
||||
// (csoler) Why are we doing this???
|
||||
|
||||
if(msg->metaData->mOrigMsgId.isNull())
|
||||
{
|
||||
msg->metaData->mOrigMsgId = msg->metaData->mMsgId;
|
||||
|
@ -288,6 +288,20 @@ protected:
|
||||
*/
|
||||
bool getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem*>& grpItem);
|
||||
|
||||
/*!
|
||||
* \brief getSerializedGroupData
|
||||
* Retrieves the complete group data serialized into a chunk of memory. This can be useful to
|
||||
* transfer a full group from one machine to another.
|
||||
*
|
||||
* \param token token previously obtained from cache request
|
||||
* \param data memory chunk allocated (using malloc)
|
||||
* \param size size of the memory chunk.
|
||||
* \return
|
||||
*/
|
||||
|
||||
bool getSerializedGroupData(const uint32_t &token, RsGxsGroupId &id, unsigned char *& data, uint32_t& size);
|
||||
bool deserializeGroupData(unsigned char *data, uint32_t size);
|
||||
|
||||
template<class GrpType>
|
||||
bool getGroupDataT(const uint32_t &token, std::vector<GrpType*>& grpItem)
|
||||
{
|
||||
|
@ -34,8 +34,8 @@
|
||||
#include "serialiser/rstlvkeys.h"
|
||||
#include "serialiser/rsgxsitems.h"
|
||||
|
||||
class RsGroupMetaData;
|
||||
class RsMsgMetaData;
|
||||
struct RsGroupMetaData;
|
||||
struct RsMsgMetaData;
|
||||
|
||||
static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0001 = 0x0000 ; // change this, and keep old values if the content changes
|
||||
static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0002 = 0xaf01 ; // current API
|
||||
@ -56,22 +56,22 @@ public:
|
||||
void clear();
|
||||
void operator =(const RsGroupMetaData& rMeta);
|
||||
|
||||
//Sort data in same order than serialiser and deserializer
|
||||
//Sort data in same order than serialiser and deserializer
|
||||
RsGxsGroupId mGroupId;
|
||||
RsGxsGroupId mOrigGrpId;
|
||||
RsGxsGroupId mParentGrpId;
|
||||
RsGxsGroupId mParentGrpId;
|
||||
std::string mGroupName;
|
||||
uint32_t mGroupFlags; // GXS_SERV::FLAG_PRIVACY_RESTRICTED | GXS_SERV::FLAG_PRIVACY_PRIVATE | GXS_SERV::FLAG_PRIVACY_PUBLIC
|
||||
uint32_t mPublishTs;
|
||||
uint32_t mCircleType;
|
||||
uint32_t mAuthenFlags;
|
||||
uint32_t mCircleType;
|
||||
uint32_t mAuthenFlags;
|
||||
RsGxsId mAuthorId;
|
||||
std::string mServiceString;
|
||||
std::string mServiceString;
|
||||
RsGxsCircleId mCircleId;
|
||||
RsTlvKeySignatureSet signSet;
|
||||
RsTlvSecurityKeySet keys;
|
||||
|
||||
uint32_t mSignFlags;
|
||||
uint32_t mSignFlags;
|
||||
|
||||
// BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
|
||||
|
||||
@ -103,9 +103,9 @@ public:
|
||||
void clear();
|
||||
void operator =(const RsMsgMetaData& rMeta);
|
||||
|
||||
static int refcount;
|
||||
|
||||
//Sort data in same order than serialiser and deserializer
|
||||
static int refcount;
|
||||
|
||||
//Sort data in same order than serialiser and deserializer
|
||||
RsGxsGroupId mGroupId;
|
||||
RsGxsMessageId mMsgId;
|
||||
RsGxsMessageId mThreadId;
|
||||
@ -121,7 +121,7 @@ public:
|
||||
// BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
|
||||
// normally READ / UNREAD flags. LOCAL Data.
|
||||
|
||||
std::string mServiceString;
|
||||
std::string mServiceString;
|
||||
uint32_t mMsgStatus;
|
||||
uint32_t mMsgSize;
|
||||
time_t mChildTs;
|
||||
|
@ -75,6 +75,12 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const
|
||||
gir->mGroupIds = groupIds;
|
||||
req = gir;
|
||||
}
|
||||
else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA)
|
||||
{
|
||||
GroupSerializedDataReq* gir = new GroupSerializedDataReq();
|
||||
gir->mGroupIds = groupIds;
|
||||
req = gir;
|
||||
}
|
||||
|
||||
if(req == NULL)
|
||||
{
|
||||
@ -103,34 +109,25 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const
|
||||
uint32_t reqType = opts.mReqType;
|
||||
|
||||
if(reqType & GXS_REQUEST_TYPE_GROUP_META)
|
||||
{
|
||||
GroupMetaReq* gmr = new GroupMetaReq();
|
||||
req = gmr;
|
||||
}
|
||||
req = new GroupMetaReq();
|
||||
else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA)
|
||||
{
|
||||
GroupDataReq* gdr = new GroupDataReq();
|
||||
req = gdr;
|
||||
}
|
||||
req = new GroupDataReq();
|
||||
else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS)
|
||||
{
|
||||
GroupIdReq* gir = new GroupIdReq();
|
||||
req = gir;
|
||||
}
|
||||
|
||||
if(req == NULL)
|
||||
req = new GroupIdReq();
|
||||
else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA)
|
||||
req = new GroupSerializedDataReq();
|
||||
else
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type "
|
||||
<< reqType << std::endl;
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
generateToken(token);
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
generateToken(token);
|
||||
#ifdef DATA_DEBUG
|
||||
std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl;
|
||||
#endif
|
||||
|
||||
setReq(req, token, ansType, opts);
|
||||
storeRequest(req);
|
||||
|
||||
@ -430,7 +427,16 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list<RsNxsGrp*>&
|
||||
else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE)
|
||||
{
|
||||
GroupDataReq* gmreq = dynamic_cast<GroupDataReq*>(req);
|
||||
if(gmreq)
|
||||
GroupSerializedDataReq* gsreq = dynamic_cast<GroupSerializedDataReq*>(req);
|
||||
|
||||
if(gsreq)
|
||||
{
|
||||
grpData.swap(gsreq->mGroupData);
|
||||
gsreq->mGroupData.clear();
|
||||
|
||||
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
|
||||
}
|
||||
else if(gmreq)
|
||||
{
|
||||
grpData.swap(gmreq->mGroupData);
|
||||
gmreq->mGroupData.clear();
|
||||
@ -804,6 +810,7 @@ void RsGxsDataAccess::processRequests()
|
||||
MsgIdReq* mir;
|
||||
MsgRelatedInfoReq* mri;
|
||||
GroupStatisticRequest* gsr;
|
||||
GroupSerializedDataReq* grr;
|
||||
ServiceStatisticRequest* ssr;
|
||||
|
||||
#ifdef DATA_DEBUG
|
||||
@ -851,6 +858,11 @@ void RsGxsDataAccess::processRequests()
|
||||
{
|
||||
ok = getServiceStatistic(ssr);
|
||||
}
|
||||
else if((grr = dynamic_cast<GroupSerializedDataReq*>(req)) != NULL)
|
||||
{
|
||||
ok = getGroupSerializedData(grr);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
std::cerr << "RsGxsDataAccess::processRequests() Failed to process request, token: "
|
||||
@ -929,7 +941,30 @@ bool RsGxsDataAccess::getServiceStatistic(const uint32_t &token, GxsServiceStati
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::getGroupSerializedData(GroupSerializedDataReq* req)
|
||||
{
|
||||
std::map<RsGxsGroupId, RsNxsGrp*> grpData;
|
||||
std::list<RsGxsGroupId> grpIdsOut;
|
||||
|
||||
getGroupList(req->mGroupIds, req->Options, grpIdsOut);
|
||||
|
||||
if(grpIdsOut.empty())
|
||||
return true;
|
||||
|
||||
|
||||
for(std::list<RsGxsGroupId>::iterator lit = grpIdsOut.begin();lit != grpIdsOut.end();++lit)
|
||||
grpData[*lit] = NULL;
|
||||
|
||||
bool ok = mDataStore->retrieveNxsGrps(grpData, true, true);
|
||||
req->mGroupData.clear();
|
||||
|
||||
std::map<RsGxsGroupId, RsNxsGrp*>::iterator mit = grpData.begin();
|
||||
|
||||
for(; mit != grpData.end(); ++mit)
|
||||
req->mGroupData.push_back(mit->second) ;
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsGxsDataAccess::getGroupData(GroupDataReq* req)
|
||||
{
|
||||
std::map<RsGxsGroupId, RsNxsGrp*> grpData;
|
||||
|
@ -418,6 +418,13 @@ private:
|
||||
*/
|
||||
bool getGroupStatistic(GroupStatisticRequest* req);
|
||||
|
||||
/*!
|
||||
*
|
||||
* Attempts to retrieve group data in serialized format
|
||||
* @param req Request object to satisfy
|
||||
*/
|
||||
bool getGroupSerializedData(GroupSerializedDataReq* req);
|
||||
|
||||
/*!
|
||||
*
|
||||
* Attempts to service statistic
|
||||
|
@ -1972,7 +1972,7 @@ void RsGxsNetService::updateServerSyncTS()
|
||||
#endif
|
||||
|
||||
// I keep the creation, but the data is not used yet.
|
||||
#warning disabled this, but do we need it?
|
||||
#warning csoler 2016-12-12: Disabled this, but do we need it?
|
||||
// RsGxsServerMsgUpdate& msui(mServerMsgUpdateMap[grpId]) ;
|
||||
|
||||
// (cyril) I'm removing this, because the msgUpdateTS is updated when new messages are received by calling locked_stampMsgServerUpdateTS().
|
||||
@ -3000,7 +3000,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
|
||||
}
|
||||
// FIXTESTS global variable rsReputations not available in unittests!
|
||||
|
||||
#warning Update the code below to correctly send/recv dependign on reputation
|
||||
#warning csoler 2016-12-23: Update the code below to correctly send/recv dependign on reputation
|
||||
if(!grpSyncItem->authorId.isNull() && mReputations->overallReputationLevel(grpSyncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
|
@ -45,7 +45,7 @@ bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, c
|
||||
rep.id = authorId ;
|
||||
rep.reputation_level = mRep->overallReputationLevel(authorId);
|
||||
|
||||
#warning can it happen that reputations do not have the info yet?
|
||||
#warning csoler 2017-01-10: Can it happen that reputations do not have the info yet?
|
||||
return true ;
|
||||
#ifdef TO_BE_REMOVED
|
||||
{
|
||||
|
@ -61,6 +61,12 @@ public:
|
||||
std::list<RsGxsGroupId> mGroupIds;
|
||||
std::list<RsGxsGroupId> mGroupIdResult;
|
||||
};
|
||||
class GroupSerializedDataReq : public GxsRequest
|
||||
{
|
||||
public:
|
||||
std::list<RsGxsGroupId> mGroupIds;
|
||||
std::list<RsNxsGrp*> mGroupData;
|
||||
};
|
||||
|
||||
class GroupDataReq : public GxsRequest
|
||||
{
|
||||
|
@ -1194,7 +1194,7 @@ bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *
|
||||
if(gitem->data_bytes == NULL)
|
||||
{
|
||||
delete gitem ;
|
||||
return NULL ;
|
||||
return false ;
|
||||
}
|
||||
// by convention, we use a IV of 0 for unencrypted data.
|
||||
memset(gitem->data_bytes,0,8) ;
|
||||
|
@ -279,7 +279,12 @@ win32 {
|
||||
|
||||
CONFIG += upnp_miniupnpc
|
||||
|
||||
LIBS += -lsqlcipher
|
||||
no_sqlcipher {
|
||||
PKGCONFIG *= sqlite3
|
||||
LIBS += -lsqlite3
|
||||
} else {
|
||||
LIBS += -lsqlcipher
|
||||
}
|
||||
|
||||
DEPENDPATH += . $$INC_DIR
|
||||
INCLUDEPATH += . $$INC_DIR
|
||||
|
@ -51,9 +51,14 @@ RsPluginManager::RsPluginManager(const RsFileHash &hash)
|
||||
_allow_all_plugins = false ;
|
||||
}
|
||||
|
||||
bool RsPluginManager::loadConfiguration(RsFileHash &loadHash)
|
||||
{
|
||||
return p3Config::loadConfiguration(loadHash);
|
||||
}
|
||||
|
||||
void RsPluginManager::loadConfiguration()
|
||||
{
|
||||
RsFileHash dummyHash ;
|
||||
RsFileHash dummyHash;
|
||||
p3Config::loadConfiguration(dummyHash);
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ class RsPluginManager: public RsPluginHandler, public p3Config
|
||||
// -------------------- Own members -------------------------//
|
||||
//
|
||||
virtual void addConfigurations(p3ConfigMgr *cfgMgr) ;
|
||||
virtual bool loadConfiguration(RsFileHash &loadHash) ;
|
||||
virtual void loadConfiguration() ;
|
||||
|
||||
/*!
|
||||
|
@ -92,7 +92,7 @@ dhtPeerEntry::dhtPeerEntry()
|
||||
return;
|
||||
}
|
||||
|
||||
p3DhtMgr::p3DhtMgr(std::string id, pqiConnectCb *cb)
|
||||
p3DhtMgr::p3DhtMgr(RsPeerId id, pqiConnectCb *cb)
|
||||
:pqiNetAssistConnect(id, cb), dhtMtx("p3DhtMgr"), mStunRequired(true)
|
||||
{
|
||||
/* setup own entry */
|
||||
@ -237,13 +237,13 @@ bool p3DhtMgr::setExternalInterface(
|
||||
|
||||
|
||||
/* add / remove peers */
|
||||
bool p3DhtMgr::findPeer(std::string id)
|
||||
bool p3DhtMgr::findPeer(const RsPeerId& id)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
if (it != peers.end())
|
||||
{
|
||||
@ -281,14 +281,14 @@ bool p3DhtMgr::findPeer(std::string id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3DhtMgr::dropPeer(std::string id)
|
||||
bool p3DhtMgr::dropPeer(const RsPeerId& id)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
/* once we are connected ... don't worry about them anymore */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
if (it == peers.end())
|
||||
{
|
||||
@ -302,14 +302,14 @@ bool p3DhtMgr::dropPeer(std::string id)
|
||||
}
|
||||
|
||||
/* post DHT key saying we should connect */
|
||||
bool p3DhtMgr::notifyPeer(std::string id)
|
||||
bool p3DhtMgr::notifyPeer(const RsPeerId& id)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() " << id << std::endl;
|
||||
std::cerr << "p3DhtMgr::notifyPeer() " << id.toStdString() << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
if (it == peers.end())
|
||||
{
|
||||
@ -333,7 +333,7 @@ bool p3DhtMgr::notifyPeer(std::string id)
|
||||
#ifdef DHT_LOGS
|
||||
{
|
||||
/* Log */
|
||||
rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id + " TO SOON - DROPPING");
|
||||
rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id.toStdString() + " TO SOON - DROPPING");
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -352,7 +352,7 @@ bool p3DhtMgr::notifyPeer(std::string id)
|
||||
#ifdef DHT_LOGS
|
||||
{
|
||||
/* Log */
|
||||
rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id + " PEER NOT FOUND - Trigger Search");
|
||||
rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id.toStdString() + " PEER NOT FOUND - Trigger Search");
|
||||
}
|
||||
#endif
|
||||
it->second.lastTS = 0;
|
||||
@ -364,14 +364,14 @@ bool p3DhtMgr::notifyPeer(std::string id)
|
||||
}
|
||||
|
||||
/* extract current peer status */
|
||||
bool p3DhtMgr::getPeerStatus(std::string id,
|
||||
struct sockaddr_in &laddr,
|
||||
struct sockaddr_in &raddr,
|
||||
bool p3DhtMgr::getPeerStatus(const RsPeerId &id,
|
||||
struct sockaddr_in &laddr,
|
||||
struct sockaddr_in &raddr,
|
||||
uint32_t &type, uint32_t &state)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /* LOCK MUTEX */
|
||||
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
|
||||
/* ignore OFF peers */
|
||||
@ -776,7 +776,7 @@ int p3DhtMgr::checkPeerDHTKeys()
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
|
||||
/* iterate through and find min time and suitable candidate */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it,pit;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it,pit;
|
||||
time_t now = time(NULL);
|
||||
uint32_t period = 0;
|
||||
uint32_t repeatPeriod = 6000;
|
||||
@ -802,7 +802,7 @@ int p3DhtMgr::checkPeerDHTKeys()
|
||||
period = DHT_CHECK_PERIOD;
|
||||
}
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkPeerDHTKeys() Peer: " << it->second.id;
|
||||
std::cerr << "p3DhtMgr::checkPeerDHTKeys() Peer: " << it->second.id.toStdString();
|
||||
std::cerr << " Period: " << period;
|
||||
std::cerr << " Delta: " << delta;
|
||||
std::cerr << std::endl;
|
||||
@ -865,7 +865,7 @@ int p3DhtMgr::checkNotifyDHT()
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
/* iterate through and find min time and suitable candidate */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
time_t now = time(NULL);
|
||||
int repeatPeriod = DHT_DEFAULT_PERIOD;
|
||||
|
||||
@ -1015,7 +1015,7 @@ int p3DhtMgr::checkStunState()
|
||||
if (mDhtState == DHT_STATE_CHECK_PEERS)
|
||||
{
|
||||
/* check that they have all be searched for */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
for(it = peers.begin(); it != peers.end(); it++)
|
||||
{
|
||||
if (it->second.state == DHT_PEER_INIT)
|
||||
@ -1287,7 +1287,7 @@ int p3DhtMgr::status(std::ostream &out)
|
||||
out << "OWN DETAILS END----------------------------------------" << std::endl;
|
||||
|
||||
/* now peers states */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
out << "PEER DETAILS ------------------------------------------" << std::endl;
|
||||
for(it = peers.begin(); it != peers.end(); it++)
|
||||
{
|
||||
@ -1622,15 +1622,13 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
||||
std::cerr << "p3DhtMgr::dhtResultNotify() from idhash: ";
|
||||
std::cerr << RsUtil::BinToHex(idhash) << std::endl;
|
||||
#endif
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* if notify - we must match on the second hash */
|
||||
for(it = peers.begin(); (it != peers.end()) && ((it->second).hash2 != idhash); it++) ;
|
||||
|
||||
/* update data */
|
||||
std::string peerid;
|
||||
|
||||
/* ignore OFF peers */
|
||||
if ((it != peers.end()) && (it->second.state != DHT_PEER_OFF))
|
||||
{
|
||||
@ -1677,7 +1675,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
||||
std::cerr << "p3DhtMgr::dhtResultSearch() for idhash: ";
|
||||
std::cerr << RsUtil::BinToHex(idhash) << std::endl;
|
||||
#endif
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
std::map<RsPeerId, dhtPeerEntry>::iterator it;
|
||||
bool doCb = false;
|
||||
bool doStun = false;
|
||||
uint32_t stunFlags = 0;
|
||||
@ -1780,7 +1778,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
||||
void printDhtPeerEntry(dhtPeerEntry *ent, std::ostream &out)
|
||||
{
|
||||
|
||||
out << "DhtEntry: ID: " << ent->id;
|
||||
out << "DhtEntry: ID: " << ent->id.toStdString();
|
||||
out << " State: " << ent->state;
|
||||
out << " lastTS: " << ent->lastTS;
|
||||
out << " notifyPending: " << ent->notifyPending;
|
||||
|
@ -78,7 +78,7 @@ class dhtPeerEntry
|
||||
public:
|
||||
dhtPeerEntry();
|
||||
|
||||
std::string id;
|
||||
RsPeerId id;
|
||||
uint32_t state;
|
||||
time_t lastTS;
|
||||
|
||||
@ -97,7 +97,7 @@ class p3DhtMgr: public pqiNetAssistConnect, public RsThread
|
||||
/*
|
||||
*/
|
||||
public:
|
||||
p3DhtMgr(std::string id, pqiConnectCb *cb);
|
||||
p3DhtMgr(RsPeerId id, pqiConnectCb *cb);
|
||||
|
||||
/********** External DHT Interface ************************
|
||||
* These Functions are the external interface
|
||||
@ -121,15 +121,15 @@ virtual bool setExternalInterface(struct sockaddr_in laddr,
|
||||
struct sockaddr_in raddr, uint32_t type);
|
||||
|
||||
/* add / remove peers */
|
||||
virtual bool findPeer(std::string id);
|
||||
virtual bool dropPeer(std::string id);
|
||||
virtual bool findPeer(const RsPeerId& id);
|
||||
virtual bool dropPeer(const RsPeerId& id);
|
||||
|
||||
/* post DHT key saying we should connect (callback when done) */
|
||||
virtual bool notifyPeer(std::string id);
|
||||
virtual bool notifyPeer(const RsPeerId& id);
|
||||
|
||||
/* extract current peer status */
|
||||
virtual bool getPeerStatus(std::string id,
|
||||
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
|
||||
virtual bool getPeerStatus(const RsPeerId& id,
|
||||
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
|
||||
uint32_t &type, uint32_t &mode);
|
||||
|
||||
/* stun */
|
||||
@ -154,17 +154,17 @@ virtual bool dhtResultBootstrap(std::string idhash);
|
||||
protected:
|
||||
|
||||
/* can block briefly (called only from thread) */
|
||||
virtual bool dhtPublish(std::string id,
|
||||
virtual bool dhtPublish(std::string idhash,
|
||||
struct sockaddr_in &laddr,
|
||||
struct sockaddr_in &raddr,
|
||||
uint32_t type, std::string sign);
|
||||
|
||||
virtual bool dhtNotify(std::string peerid, std::string ownId,
|
||||
virtual bool dhtNotify(std::string idhash, std::string ownIdHash,
|
||||
std::string sign);
|
||||
|
||||
virtual bool dhtSearch(std::string id, uint32_t mode);
|
||||
virtual bool dhtSearch(std::string idhash, uint32_t mode);
|
||||
|
||||
virtual bool dhtBootstrap(std::string storehash, std::string ownIdHash,
|
||||
virtual bool dhtBootstrap(std::string idhash, std::string ownIdHash,
|
||||
std::string sign); /* to publish bootstrap */
|
||||
|
||||
|
||||
@ -232,7 +232,7 @@ std::string randomBootstrapId();
|
||||
|
||||
dhtPeerEntry ownEntry;
|
||||
time_t ownNotifyTS;
|
||||
std::map<std::string, dhtPeerEntry> peers;
|
||||
std::map<RsPeerId, dhtPeerEntry> peers;
|
||||
|
||||
std::list<std::string> stunIds;
|
||||
bool mStunRequired;
|
||||
|
@ -397,7 +397,7 @@ private:
|
||||
std::map<RsPeerId,sockaddr_storage> mReportedOwnAddresses ;
|
||||
|
||||
std::map<RsNodeGroupId,RsGroupInfo> groupList;
|
||||
uint32_t lastGroupId;
|
||||
//uint32_t lastGroupId;
|
||||
|
||||
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
|
||||
|
||||
|
@ -61,14 +61,20 @@ void pqiConnectCbDummy::peerStatus(const RsPeerId& id, const pqiIpAddrSet &ad
|
||||
std::cerr << out << std::endl;
|
||||
}
|
||||
|
||||
void pqiConnectCbDummy::peerConnectRequest(const RsPeerId& id,
|
||||
const struct sockaddr_storage &raddr, uint32_t source)
|
||||
void pqiConnectCbDummy::peerConnectRequest(const RsPeerId &id, const sockaddr_storage &raddr
|
||||
, const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr
|
||||
, uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth)
|
||||
{
|
||||
std::cerr << "pqiConnectCbDummy::peerConnectRequest()";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << " raddr: " << sockaddr_storage_tostring(raddr);
|
||||
std::cerr << " proxyaddr: " << sockaddr_storage_tostring(proxyaddr);
|
||||
std::cerr << " srcaddr: " << sockaddr_storage_tostring(srcaddr);
|
||||
std::cerr << " source: " << source;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << " flags: " << flags;
|
||||
std::cerr << " delay: " << delay;
|
||||
std::cerr << " bandwidth: " << bandwidth;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
void pqiMonitor::disconnectPeer(const RsPeerId &/*peer*/)
|
||||
|
@ -179,8 +179,9 @@ virtual ~pqiConnectCbDummy();
|
||||
virtual void peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs,
|
||||
uint32_t type, uint32_t mode, uint32_t source);
|
||||
|
||||
virtual void peerConnectRequest(const RsPeerId& id,
|
||||
const struct sockaddr_storage &raddr, uint32_t source);
|
||||
virtual void peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr,
|
||||
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
|
||||
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth);
|
||||
|
||||
//virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags);
|
||||
};
|
||||
|
@ -40,7 +40,7 @@ static struct RsLog::logInfo pqipersonzoneInfo = {RsLog::Default, "pqiperson"};
|
||||
|
||||
pqiperson::pqiperson(const RsPeerId& id, pqipersongrp *pg) :
|
||||
PQInterface(id), mNotifyMtx("pqiperson-notify"), mPersonMtx("pqiperson"),
|
||||
active(false), activepqi(NULL), inConnectAttempt(false), waittimes(0),
|
||||
active(false), activepqi(NULL), inConnectAttempt(false),// waittimes(0),
|
||||
pqipg(pg) {} // TODO: must check id!
|
||||
|
||||
pqiperson::~pqiperson()
|
||||
|
@ -29,6 +29,7 @@
|
||||
#define MRK_PQI_PERSON_HEADER
|
||||
|
||||
|
||||
#include <string>
|
||||
#include "pqi/pqi.h"
|
||||
#include "util/rsnet.h"
|
||||
|
||||
@ -66,7 +67,7 @@ public:
|
||||
virtual int reset() { pqistreamer::reset(); return ni->reset(); }
|
||||
virtual int disconnect() { return reset() ; }
|
||||
virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni->connect_parameter(type, value);}
|
||||
virtual bool connect_parameter(uint32_t type, std::string value) { return ni->connect_parameter(type, value);}
|
||||
virtual bool connect_parameter(uint32_t type, const std::string &value) { return ni->connect_parameter(type, value);}
|
||||
virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) { return ni->connect_additional_address(type, addr); }
|
||||
virtual int getConnectAddress(struct sockaddr_storage &raddr){ return ni->getConnectAddress(raddr); }
|
||||
|
||||
@ -171,7 +172,7 @@ private:
|
||||
bool active;
|
||||
pqiconnect *activepqi;
|
||||
bool inConnectAttempt;
|
||||
int waittimes;
|
||||
//int waittimes;
|
||||
time_t lastHeartbeatReceived; // use to track connection failure
|
||||
pqipersongrp *pqipg; /* parent for callback */
|
||||
};
|
||||
|
@ -1009,7 +1009,7 @@ int pqissl::Basic_Connection_Complete()
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if ((err == ECONNREFUSED))
|
||||
else if (err == ECONNREFUSED)
|
||||
{
|
||||
rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() ECONNREFUSED: cert: " + PeerId().toStdString());
|
||||
|
||||
|
@ -53,7 +53,7 @@ static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */
|
||||
/********** PQI SSL UDP STUFF **************************************/
|
||||
|
||||
pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm) :
|
||||
pqissl(NULL, parent, lm), tou_bio(NULL), listen_checktime(0),
|
||||
pqissl(NULL, parent, lm), tou_bio(NULL),// listen_checktime(0),
|
||||
mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD), mConnectFlags(0),
|
||||
mConnectBandwidth(0)
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ private:
|
||||
|
||||
BIO *tou_bio; // specific to ssludp.
|
||||
|
||||
long listen_checktime;
|
||||
//long listen_checktime;
|
||||
|
||||
uint32_t mConnectPeriod;
|
||||
uint32_t mConnectFlags;
|
||||
|
@ -627,7 +627,7 @@ bool getX509id(X509 *x509, RsPeerId& xid)
|
||||
* more randomness
|
||||
*/
|
||||
|
||||
#warning this is cryptographically horrible. We should do a hash of the public key here!!!
|
||||
#warning csoler 2017-02-19: This is cryptographically horrible. We should do a hash of the public key here!!!
|
||||
|
||||
xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ;
|
||||
|
||||
|
@ -25,7 +25,7 @@ typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
|
||||
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsGxsMessageId> > MsgRelatedIdResult;
|
||||
typedef std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > GxsMsgReq;
|
||||
|
||||
class RsMsgMetaData;
|
||||
struct RsMsgMetaData;
|
||||
|
||||
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > MsgMetaResult;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "retroshare/rsgxsifacetypes.h"
|
||||
#include "retroshare/rstokenservice.h"
|
||||
|
||||
class RsMsgMetaData ;
|
||||
struct RsMsgMetaData ;
|
||||
|
||||
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
|
||||
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
|
||||
|
@ -305,6 +305,9 @@ public:
|
||||
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ;
|
||||
virtual bool isARegularContact(const RsGxsId& id) = 0 ;
|
||||
|
||||
virtual bool serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string)=0;
|
||||
virtual bool deserialiseIdentityFromMemory(const std::string& radix_string)=0;
|
||||
|
||||
/*!
|
||||
* \brief overallReputationLevel
|
||||
* Returns the overall reputation level of the supplied identity. See rsreputations.h
|
||||
@ -319,6 +322,7 @@ public:
|
||||
*/
|
||||
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup> &groups) = 0;
|
||||
virtual bool getGroupSerializedData(const uint32_t &token, std::map<RsGxsId,std::string>& serialized_groups)=0;
|
||||
//virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opinions) = 0;
|
||||
|
||||
};
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#define GXS_REQUEST_TYPE_GROUP_STATS 0x01600000
|
||||
#define GXS_REQUEST_TYPE_SERVICE_STATS 0x03200000
|
||||
#define GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA 0x04000000
|
||||
|
||||
|
||||
// TODO CLEANUP: RS_TOKREQOPT_MSG_* should be an inner enum of RsTokReqOptions
|
||||
|
@ -1037,6 +1037,9 @@ bool p3Peers::setProxyServer(const uint32_t type, const std::string &addr_str, c
|
||||
std::cerr << "(EE) attempt to set proxy server address to something not allowed: " << addr_str << ":" << port << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
std::cerr << "Settign proxy server address to " << addr_str << ":" << port << std::endl;
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr;
|
||||
addrv4p->sin_family = AF_INET;
|
||||
|
@ -66,8 +66,8 @@
|
||||
*/
|
||||
RsBanList *rsBanList = NULL ;
|
||||
|
||||
p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr *nm)
|
||||
:p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc), mNetMgr(nm)
|
||||
p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr */*nm*/)
|
||||
:p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc)//, mNetMgr(nm)
|
||||
{
|
||||
addSerialType(new RsBanListSerialiser());
|
||||
|
||||
|
@ -148,7 +148,7 @@ private:
|
||||
std::map<struct sockaddr_storage, BanListPeer> mWhiteListedRanges;
|
||||
|
||||
p3ServiceControl *mServiceCtrl;
|
||||
p3NetMgr *mNetMgr;
|
||||
//p3NetMgr *mNetMgr;
|
||||
time_t mLastDhtInfoRequest ;
|
||||
|
||||
bool mIPFilteringEnabled ;
|
||||
|
@ -1035,7 +1035,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
|
||||
|
||||
if (rit == mReputations.end())
|
||||
{
|
||||
#warning we should set the owner node id here.
|
||||
#warning csoler 2017-01-05: We should set the owner node id here.
|
||||
mReputations[gxsid] = Reputation(gxsid);
|
||||
rit = mReputations.find(gxsid);
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ private:
|
||||
time_t mLastIdentityFlagsUpdate ;
|
||||
bool mReputationsUpdated;
|
||||
|
||||
float mAutoBanIdentitiesLimit ;
|
||||
//float mAutoBanIdentitiesLimit ;
|
||||
bool mAutoSetPositiveOptionToContacts;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
|
@ -70,6 +70,8 @@ static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed ident
|
||||
|
||||
static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins
|
||||
|
||||
static const uint32_t MAX_SERIALISED_IDENTITY_AGE = 600 ; // after 10 mins, a serialised identity record must be renewed.
|
||||
|
||||
RsIdentity *rsIdentity = NULL;
|
||||
|
||||
/******
|
||||
@ -97,13 +99,12 @@ RsIdentity *rsIdentity = NULL;
|
||||
#define BG_REPUTATION 3
|
||||
|
||||
|
||||
#define GXSIDREQ_CACHELOAD 0x0001
|
||||
#define GXSIDREQ_CACHEOWNIDS 0x0002
|
||||
|
||||
#define GXSIDREQ_PGPHASH 0x0010
|
||||
#define GXSIDREQ_RECOGN 0x0020
|
||||
|
||||
#define GXSIDREQ_OPINION 0x0030
|
||||
#define GXSIDREQ_CACHELOAD 0x0001
|
||||
#define GXSIDREQ_CACHEOWNIDS 0x0002
|
||||
#define GXSIDREQ_PGPHASH 0x0010
|
||||
#define GXSIDREQ_RECOGN 0x0020
|
||||
#define GXSIDREQ_OPINION 0x0030
|
||||
#define GXSIDREQ_SERIALIZE_TO_MEMORY 0x0040
|
||||
|
||||
#define GXSIDREQ_CACHETEST 0x1000
|
||||
|
||||
@ -697,6 +698,84 @@ bool p3IdService::getOwnIds(std::list<RsGxsId> &ownIds)
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3IdService::serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string)
|
||||
{
|
||||
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
// look into cache. If available, return the data. If not, request it.
|
||||
|
||||
std::map<RsGxsId,SerialisedIdentityStruct>::const_iterator it = mSerialisedIdentities.find(id);
|
||||
|
||||
if(it != mSerialisedIdentities.end())
|
||||
{
|
||||
Radix64::encode(it->second.mMem,it->second.mSize,radix_string) ;
|
||||
|
||||
if(it->second.mLastUsageTS + MAX_SERIALISED_IDENTITY_AGE > time(NULL))
|
||||
return true ;
|
||||
|
||||
std::cerr << "Identity " << id << " will be re-serialised, because the last record is too old." << std::endl;
|
||||
}
|
||||
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
uint32_t token = 0;
|
||||
std::list<RsGxsGroupId> groupIds;
|
||||
|
||||
groupIds.push_back(RsGxsGroupId(id)) ;
|
||||
|
||||
RsGenExchange::getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds);
|
||||
GxsTokenQueue::queueRequest(token, GXSIDREQ_SERIALIZE_TO_MEMORY);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void p3IdService::handle_get_serialized_grp(uint32_t token)
|
||||
{
|
||||
// store the serialized data in cache.
|
||||
|
||||
unsigned char *mem = NULL;
|
||||
uint32_t size;
|
||||
RsGxsGroupId id ;
|
||||
|
||||
if(!RsGenExchange::getSerializedGroupData(token,id, mem,size))
|
||||
{
|
||||
std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
std::cerr << "Received serialised group from RsGenExchange." << std::endl;
|
||||
|
||||
std::map<RsGxsId,SerialisedIdentityStruct>::const_iterator it = mSerialisedIdentities.find(RsGxsId(id));
|
||||
|
||||
if(it != mSerialisedIdentities.end())
|
||||
free(it->second.mMem) ;
|
||||
|
||||
SerialisedIdentityStruct s ;
|
||||
s.mMem = mem ;
|
||||
s.mSize = size ;
|
||||
s.mLastUsageTS = time(NULL) ;
|
||||
|
||||
mSerialisedIdentities[RsGxsId(id)] = s ;
|
||||
}
|
||||
|
||||
bool p3IdService::deserialiseIdentityFromMemory(const std::string& radix_string)
|
||||
{
|
||||
std::vector<uint8_t> mem = Radix64::decode(radix_string) ;
|
||||
|
||||
if(mem.empty())
|
||||
{
|
||||
std::cerr << "Cannot decode radix string \"" << radix_string << "\"" << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::deserializeGroupData(mem.data(),mem.size()))
|
||||
{
|
||||
std::cerr << "Cannot load identity from radix string \"" << radix_string << "\"" << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms)
|
||||
{
|
||||
@ -709,7 +788,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms)
|
||||
|
||||
if (params.isPgpLinked)
|
||||
{
|
||||
#warning Backward compatibility issue to fix here in v0.7.0
|
||||
#warning csoler 2017-02-07: Backward compatibility issue to fix here in v0.7.0
|
||||
|
||||
// This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE.
|
||||
// In order to keep backward compatibility, we'll also add the new value
|
||||
@ -1587,6 +1666,28 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup>
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool p3IdService::getGroupSerializedData(const uint32_t &token, std::map<RsGxsId,std::string>& serialized_groups)
|
||||
{
|
||||
unsigned char *mem = NULL;
|
||||
uint32_t size;
|
||||
RsGxsGroupId id ;
|
||||
|
||||
serialized_groups.clear() ;
|
||||
|
||||
if(!RsGenExchange::getSerializedGroupData(token,id, mem,size))
|
||||
{
|
||||
std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string radix ;
|
||||
|
||||
Radix64::encode(mem,size,radix) ;
|
||||
|
||||
serialized_groups[RsGxsId(id)] = radix ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************************/
|
||||
/********************************************************************************/
|
||||
@ -4309,6 +4410,9 @@ void p3IdService::handleResponse(uint32_t token, uint32_t req_type)
|
||||
case GXSIDREQ_OPINION:
|
||||
opinion_handlerequest(token);
|
||||
break;
|
||||
case GXSIDREQ_SERIALIZE_TO_MEMORY:
|
||||
handle_get_serialized_grp(token) ;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
std::cerr << "p3IdService::handleResponse() Unknown Request Type: " << req_type;
|
||||
|
@ -212,6 +212,13 @@ private:
|
||||
void init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pub_key, const RsTlvPrivateRSAKey& in_priv_key,const std::list<RsRecognTag> &tagList);
|
||||
};
|
||||
|
||||
struct SerialisedIdentityStruct
|
||||
{
|
||||
unsigned char *mMem ;
|
||||
uint32_t mSize ;
|
||||
time_t mLastUsageTS;
|
||||
};
|
||||
|
||||
// Not sure exactly what should be inherited here?
|
||||
// Chris - please correct as necessary.
|
||||
|
||||
@ -238,6 +245,8 @@ public:
|
||||
|
||||
// These are exposed via RsIdentity.
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup> &groups);
|
||||
virtual bool getGroupSerializedData(const uint32_t &token, std::map<RsGxsId,std::string>& serialized_groups);
|
||||
|
||||
//virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opinions);
|
||||
|
||||
// These are local - and not exposed via RsIdentity.
|
||||
@ -341,6 +350,8 @@ public:
|
||||
const RsIdentityUsage &use_info );
|
||||
virtual bool requestPrivateKey(const RsGxsId &id);
|
||||
|
||||
virtual bool serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string);
|
||||
virtual bool deserialiseIdentityFromMemory(const std::string& radix_string);
|
||||
|
||||
/**************** RsGixsReputation Implementation ****************/
|
||||
|
||||
@ -433,6 +444,12 @@ private:
|
||||
bool mBgSchedule_Active;
|
||||
uint32_t mBgSchedule_Mode;
|
||||
|
||||
/***********************************8
|
||||
* Fonction to receive and handle group serialisation to memory
|
||||
*/
|
||||
|
||||
virtual void handle_get_serialized_grp(uint32_t token);
|
||||
|
||||
/************************************************************************
|
||||
* pgphash processing.
|
||||
*
|
||||
@ -563,6 +580,8 @@ private:
|
||||
std::map<RsGxsId, std::list<RsPeerId> > mIdsNotPresent;
|
||||
std::map<RsGxsId,keyTSInfo> mKeysTS ;
|
||||
|
||||
std::map<RsGxsId,SerialisedIdentityStruct> mSerialisedIdentities ;
|
||||
|
||||
// keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only.
|
||||
std::set<RsGxsId> mContacts;
|
||||
RsNetworkExchangeService* mNes;
|
||||
|
@ -93,9 +93,9 @@ again:
|
||||
idx = (idx + 1) % 4;
|
||||
}
|
||||
|
||||
idx = idx;
|
||||
//idx = idx;
|
||||
|
||||
return buf;
|
||||
return buf ;
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -147,7 +147,7 @@ again:
|
||||
|
||||
private:
|
||||
static inline char *bintoasc() { static char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; return bta ; }
|
||||
static inline char *asctobin() { static char s[256]; return s ; } /* runtime radix64_initd */
|
||||
static inline uint8_t *asctobin() { static uint8_t s[256]; return s ; } /* runtime radix64_initd */
|
||||
static int& is_radix64_initd() { static int is_inited = false ; return is_inited ; }
|
||||
|
||||
/* hey, guess what: this is a read-only table.
|
||||
|
@ -2394,7 +2394,7 @@ static int parse_secret_key(ops_region_t *region,ops_parse_info_t *pinfo)
|
||||
else if(C.secret_key.s2k_usage != OPS_S2KU_NONE)
|
||||
{
|
||||
// this is V3 style, looks just like a V4 simple hash
|
||||
C.secret_key.algorithm=C.secret_key.s2k_usage;
|
||||
C.secret_key.algorithm=(ops_symmetric_algorithm_t)C.secret_key.s2k_usage;
|
||||
C.secret_key.s2k_usage=OPS_S2KU_ENCRYPTED;
|
||||
C.secret_key.s2k_specifier=OPS_S2KS_SIMPLE;
|
||||
C.secret_key.hash_algorithm=OPS_HASH_MD5;
|
||||
|
@ -651,7 +651,7 @@ static time_t parseRFC822Date(const std::string &pubDate)
|
||||
offset = abs(offset);
|
||||
offset = ((offset / 100)*60 + (offset % 100))*sgn;
|
||||
} else {
|
||||
for (int i=0; known_zones[i].tzName != 0; i++) {
|
||||
for (int i=0; known_zones[i].tzName[0] != 0; i++) {
|
||||
if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
|
||||
offset = known_zones[i].tzOffset;
|
||||
break;
|
||||
|
@ -66,7 +66,9 @@ private:
|
||||
AVPacket decoding_buffer;
|
||||
uint64_t encoding_frame_count ;
|
||||
|
||||
#ifdef DEBUG_MPEG_VIDEO
|
||||
FILE *encoding_debug_file ;
|
||||
#endif
|
||||
};
|
||||
|
||||
// This class decodes video from a stream. It keeps a queue of
|
||||
|
@ -6,13 +6,11 @@ QT += core network
|
||||
QT -= gui
|
||||
|
||||
CONFIG += c++11
|
||||
CONFIG += dll
|
||||
android-g++:CONFIG += dll
|
||||
|
||||
android-g++:TEMPLATE = lib
|
||||
!android-g++:TEMPLATE = app
|
||||
|
||||
SOURCES += service.cpp
|
||||
|
||||
DEPENDPATH *= ../../libresapi/src
|
||||
INCLUDEPATH *= ../../libresapi/src
|
||||
PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a
|
||||
@ -22,3 +20,34 @@ DEPENDPATH *= ../../libretroshare/src
|
||||
INCLUDEPATH *= ../../libretroshare/src
|
||||
PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
LIBS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
|
||||
win32 {
|
||||
OBJECTS_DIR = temp/obj
|
||||
|
||||
LIBS_DIR = $$PWD/../../libs/lib
|
||||
LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a
|
||||
LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a
|
||||
|
||||
for(lib, LIB_DIR):LIBS += -L"$$lib"
|
||||
for(bin, BIN_DIR):LIBS += -L"$$bin"
|
||||
|
||||
|
||||
LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32
|
||||
LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32
|
||||
LIBS += -lwinmm
|
||||
|
||||
DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
|
||||
|
||||
DEPENDPATH += . $$INC_DIR
|
||||
INCLUDEPATH += . $$INC_DIR
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
# Qt 5
|
||||
RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src
|
||||
} else {
|
||||
# Qt 4
|
||||
QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src
|
||||
}
|
||||
}
|
||||
|
||||
SOURCES += service.cpp
|
||||
|
@ -24,12 +24,10 @@
|
||||
# include "util/androiddebug.h"
|
||||
#endif
|
||||
|
||||
#include "retroshare/rsinit.h"
|
||||
#include "api/ApiServer.h"
|
||||
#include "api/ApiServerLocal.h"
|
||||
#include "api/RsControlModule.h"
|
||||
|
||||
|
||||
using namespace resource_api;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -46,7 +44,12 @@ int main(int argc, char *argv[])
|
||||
dynamic_cast<resource_api::ResourceRouter*>(&ctrl_mod),
|
||||
&resource_api::RsControlModule::handleRequest);
|
||||
|
||||
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
|
||||
#ifdef QT_DEBUG
|
||||
QString sockPath = "RS/";
|
||||
#else
|
||||
QString sockPath = QCoreApplication::applicationDirPath();
|
||||
#endif
|
||||
|
||||
sockPath.append("/libresapi.sock");
|
||||
qDebug() << "Listening on:" << sockPath;
|
||||
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;
|
||||
|
@ -378,8 +378,12 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
||||
+QObject::tr("Id:")+" "+QString::number(id,16) ;
|
||||
|
||||
if(lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
|
||||
{
|
||||
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
|
||||
|
||||
QColor foreground = QColor(0, 128, 0); // green
|
||||
for (int column = 0; column < COLUMN_COUNT; ++column)
|
||||
item->setTextColor(column, foreground);
|
||||
}
|
||||
item->setToolTip(0,tooltipstr) ;
|
||||
}
|
||||
|
||||
@ -653,7 +657,9 @@ void ChatLobbyWidget::updateDisplay()
|
||||
updateItem(ui.lobbyTreeWidget, item, lobby.lobby_id, lobby.lobby_name,lobby.lobby_topic, lobby.gxs_ids.size(), true, autoSubscribe,lobby_flags);
|
||||
}
|
||||
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
|
||||
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));
|
||||
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
|
||||
publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")"));
|
||||
}
|
||||
|
||||
void ChatLobbyWidget::createChatLobby()
|
||||
|
@ -407,6 +407,13 @@ void SearchDialog::download()
|
||||
for(std::list<RsPeerId>::const_iterator it(srcIds.begin()); it!=srcIds.end(); ++it) {
|
||||
std::cout << *it << "-" << std::endl;
|
||||
}//for(std::list<RsPeerId>::const_iterator
|
||||
//QColor foreground = QColor(0, 128, 0); // green
|
||||
QColor foreground = textColorDownloading();
|
||||
QBrush brush(foreground);
|
||||
for (int i = 0; i < item->columnCount(); ++i)
|
||||
{
|
||||
item->setForeground(i, brush);
|
||||
}
|
||||
}//if(!rsFiles -> FileRequest(
|
||||
}//if (item->text(SR_HASH_COL).isEmpty())
|
||||
}//for (int i = 0
|
||||
@ -1189,6 +1196,11 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
||||
found = true ;
|
||||
|
||||
if (!item->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool()) {
|
||||
|
||||
FileInfo fi;
|
||||
if (rsFiles->FileDetails(file.hash, RS_FILE_HINTS_DOWNLOAD, fi))
|
||||
break;
|
||||
|
||||
QColor foreground;
|
||||
|
||||
int sources = friendSource + anonymousSource ;
|
||||
@ -1281,6 +1293,12 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
||||
setForeground = true;
|
||||
}
|
||||
}
|
||||
if (rsFiles->FileDetails(file.hash, RS_FILE_HINTS_DOWNLOAD, fi))
|
||||
{
|
||||
//foreground = QColor(0, 128, 0); // green
|
||||
foreground = textColorDownloading();
|
||||
setForeground = true;
|
||||
}
|
||||
|
||||
if (setForeground) {
|
||||
QBrush brush(foreground);
|
||||
|
@ -38,6 +38,7 @@ class SearchDialog : public MainPage
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor textColorLocal READ textColorLocal WRITE setTextColorLocal)
|
||||
Q_PROPERTY(QColor textColorDownloading READ textColorDownloading WRITE setTextColorDownloading)
|
||||
Q_PROPERTY(QColor textColorNoSources READ textColorNoSources WRITE setTextColorNoSources)
|
||||
Q_PROPERTY(QColor textColorLowSources READ textColorLowSources WRITE setTextColorLowSources)
|
||||
Q_PROPERTY(QColor textColorHighSources READ textColorHighSources WRITE setTextColorHighSources)
|
||||
@ -51,11 +52,13 @@ public:
|
||||
void searchKeywords(const QString& keywords);
|
||||
|
||||
QColor textColorLocal() const { return mTextColorLocal; }
|
||||
QColor textColorDownloading() const { return mTextColorDownloading; }
|
||||
QColor textColorNoSources() const { return mTextColorNoSources; }
|
||||
QColor textColorLowSources() const { return mTextColorLowSources; }
|
||||
QColor textColorHighSources() const { return mTextColorHighSources; }
|
||||
|
||||
void setTextColorLocal(QColor color) { mTextColorLocal = color; }
|
||||
void setTextColorDownloading(QColor color) { mTextColorDownloading = color; }
|
||||
void setTextColorNoSources(QColor color) { mTextColorNoSources = color; }
|
||||
void setTextColorLowSources(QColor color) { mTextColorLowSources = color; }
|
||||
void setTextColorHighSources(QColor color) { mTextColorHighSources = color; }
|
||||
@ -154,6 +157,7 @@ private:
|
||||
|
||||
/* Color definitions (for standard see qss.default) */
|
||||
QColor mTextColorLocal;
|
||||
QColor mTextColorDownloading;
|
||||
QColor mTextColorNoSources;
|
||||
QColor mTextColorLowSources;
|
||||
QColor mTextColorHighSources;
|
||||
|
@ -55,10 +55,11 @@
|
||||
*****/
|
||||
|
||||
// Data Requests.
|
||||
#define IDDIALOG_IDLIST 1
|
||||
#define IDDIALOG_IDDETAILS 2
|
||||
#define IDDIALOG_REPLIST 3
|
||||
#define IDDIALOG_REFRESH 4
|
||||
#define IDDIALOG_IDLIST 1
|
||||
#define IDDIALOG_IDDETAILS 2
|
||||
#define IDDIALOG_REPLIST 3
|
||||
#define IDDIALOG_REFRESH 4
|
||||
#define IDDIALOG_SERIALIZED_GROUP 5
|
||||
|
||||
#define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0
|
||||
#define CIRCLEGROUP_CIRCLE_COL_GROUPID 1
|
||||
@ -814,7 +815,7 @@ void IdDialog::loadCircleGroupData(const uint32_t& token)
|
||||
#ifdef ID_DEBUG
|
||||
std::cerr << "Loading circle info" << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
std::vector<RsGxsCircleGroup> circle_grp_v ;
|
||||
rsGxsCircles->getGroupData(token, circle_grp_v);
|
||||
|
||||
@ -1207,6 +1208,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
||||
contextMnu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
#ifdef SUSPENDED
|
||||
static void set_item_background(QTreeWidgetItem *item, uint32_t type)
|
||||
{
|
||||
QBrush brush;
|
||||
@ -1247,7 +1249,6 @@ static void update_children_background(QTreeWidgetItem *item, uint32_t type)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SUSPENDED
|
||||
static void set_tree_background(QTreeWidget *tree, uint32_t type)
|
||||
{
|
||||
std::cerr << "CirclesDialog set_tree_background()";
|
||||
@ -1385,6 +1386,8 @@ void IdDialog::updateSelection()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void IdDialog::requestIdList()
|
||||
{
|
||||
//Disable by default, will be enable by insertIdDetails()
|
||||
@ -1990,7 +1993,7 @@ QString IdDialog::createUsageString(const RsIdentityUsage& u) const
|
||||
return tr("Membership verification in circle %1.").arg(QString::fromStdString(u.mGrpId.toStdString()));
|
||||
}
|
||||
|
||||
#warning TODO! Add the different strings and translations here.
|
||||
#warning TODO! csoler 2017-01-03: Add the different strings and translations here.
|
||||
default:
|
||||
return QString("Undone yet");
|
||||
}
|
||||
@ -2174,6 +2177,45 @@ void IdDialog::insertRepList(uint32_t token)
|
||||
mStateHelper->setActive(IDDIALOG_REPLIST, true);
|
||||
}
|
||||
|
||||
void IdDialog::handleSerializedGroupData(uint32_t token)
|
||||
{
|
||||
std::map<RsGxsId,std::string> serialized_group_map ;
|
||||
|
||||
rsIdentity->getGroupSerializedData(token, serialized_group_map);
|
||||
|
||||
if(serialized_group_map.size() < 1)
|
||||
{
|
||||
std::cerr << "(EE) Cannot get radix data " << std::endl;
|
||||
return;
|
||||
}
|
||||
if(serialized_group_map.size() > 1)
|
||||
{
|
||||
std::cerr << "(EE) Too many results for serialized data" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsGxsId gxs_id = serialized_group_map.begin()->first ;
|
||||
std::string radix = serialized_group_map.begin()->second ;
|
||||
|
||||
RsIdentityDetails details ;
|
||||
|
||||
if(!rsIdentity->getIdDetails(gxs_id,details))
|
||||
{
|
||||
std::cerr << "(EE) Cannot get id details for key " << gxs_id << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
QList<RetroShareLink> urls ;
|
||||
|
||||
RetroShareLink link ;
|
||||
link.createIdentity(gxs_id,QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ;
|
||||
urls.push_back(link);
|
||||
|
||||
RSLinkClipboard::copyLinks(urls) ;
|
||||
|
||||
QMessageBox::information(NULL,tr("information"),tr("This identity link was copied to your clipboard. Paste it in a mail, or a message to transmit the identity to someone.")) ;
|
||||
}
|
||||
|
||||
void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
|
||||
{
|
||||
#ifdef ID_DEBUG
|
||||
@ -2197,6 +2239,10 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
|
||||
insertRepList(req.mToken);
|
||||
break;
|
||||
|
||||
case IDDIALOG_SERIALIZED_GROUP:
|
||||
handleSerializedGroupData(req.mToken);
|
||||
break;
|
||||
|
||||
case IDDIALOG_REFRESH:
|
||||
// replaced by RsGxsUpdateBroadcastPage
|
||||
// updateDisplay(true);
|
||||
@ -2240,165 +2286,211 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
|
||||
|
||||
void IdDialog::IdListCustomPopupMenu( QPoint )
|
||||
{
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
|
||||
|
||||
std::list<RsGxsId> own_identities ;
|
||||
rsIdentity->getOwnIds(own_identities) ;
|
||||
std::list<RsGxsId> own_identities ;
|
||||
rsIdentity->getOwnIds(own_identities) ;
|
||||
|
||||
// make some stats about what's selected. If the same value is used for all selected items, it can be switched.
|
||||
// make some stats about what's selected. If the same value is used for all selected items, it can be switched.
|
||||
|
||||
QList<QTreeWidgetItem *> selected_items = ui->idTreeWidget->selectedItems();
|
||||
QList<QTreeWidgetItem *> selected_items = ui->idTreeWidget->selectedItems();
|
||||
|
||||
bool root_node_present = false ;
|
||||
bool one_item_owned_by_you = false ;
|
||||
uint32_t n_positive_reputations = 0 ;
|
||||
uint32_t n_negative_reputations = 0 ;
|
||||
uint32_t n_neutral_reputations = 0 ;
|
||||
uint32_t n_is_a_contact = 0 ;
|
||||
uint32_t n_is_not_a_contact = 0 ;
|
||||
uint32_t n_selected_items =0 ;
|
||||
bool root_node_present = false ;
|
||||
bool one_item_owned_by_you = false ;
|
||||
uint32_t n_positive_reputations = 0 ;
|
||||
uint32_t n_negative_reputations = 0 ;
|
||||
uint32_t n_neutral_reputations = 0 ;
|
||||
uint32_t n_is_a_contact = 0 ;
|
||||
uint32_t n_is_not_a_contact = 0 ;
|
||||
uint32_t n_selected_items =0 ;
|
||||
|
||||
for(QList<QTreeWidgetItem*>::const_iterator it(selected_items.begin());it!=selected_items.end();++it)
|
||||
{
|
||||
if(*it == allItem || *it == contactsItem || *it == ownItem)
|
||||
{
|
||||
root_node_present = true ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
uint32_t item_flags = (*it)->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ;
|
||||
|
||||
if(item_flags & RSID_FILTER_OWNED_BY_YOU)
|
||||
one_item_owned_by_you = true ;
|
||||
|
||||
#ifdef ID_DEBUG
|
||||
std::cerr << " item flags = " << item_flags << std::endl;
|
||||
#endif
|
||||
RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString());
|
||||
|
||||
RsIdentityDetails det ;
|
||||
rsIdentity->getIdDetails(keyId,det) ;
|
||||
|
||||
switch(det.mReputation.mOwnOpinion)
|
||||
{
|
||||
case RsReputations::OPINION_NEGATIVE: ++n_negative_reputations ;
|
||||
break ;
|
||||
|
||||
case RsReputations::OPINION_POSITIVE: ++n_positive_reputations ;
|
||||
break ;
|
||||
|
||||
case RsReputations::OPINION_NEUTRAL: ++n_neutral_reputations ;
|
||||
break ;
|
||||
}
|
||||
|
||||
++n_selected_items ;
|
||||
|
||||
if(rsIdentity->isARegularContact(keyId))
|
||||
++n_is_a_contact ;
|
||||
else
|
||||
++n_is_not_a_contact ;
|
||||
}
|
||||
|
||||
if(!root_node_present) // don't show menu if some of the root nodes are present
|
||||
for(QList<QTreeWidgetItem*>::const_iterator it(selected_items.begin());it!=selected_items.end();++it)
|
||||
{
|
||||
if(*it == allItem || *it == contactsItem || *it == ownItem)
|
||||
{
|
||||
|
||||
if(!one_item_owned_by_you)
|
||||
{
|
||||
QWidget *widget = new QWidget(contextMenu);
|
||||
widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}");
|
||||
|
||||
// create menu header
|
||||
QHBoxLayout *hbox = new QHBoxLayout(widget);
|
||||
hbox->setMargin(0);
|
||||
hbox->setSpacing(6);
|
||||
|
||||
QLabel *iconLabel = new QLabel(widget);
|
||||
QPixmap pix = QPixmap(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5);
|
||||
iconLabel->setPixmap(pix);
|
||||
iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width());
|
||||
hbox->addWidget(iconLabel);
|
||||
|
||||
QLabel *textLabel = new QLabel("<strong>" + ui->titleBarLabel->text() + "</strong>", widget);
|
||||
hbox->addWidget(textLabel);
|
||||
|
||||
QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
hbox->addItem(spacerItem);
|
||||
|
||||
widget->setLayout(hbox);
|
||||
|
||||
QWidgetAction *widgetAction = new QWidgetAction(this);
|
||||
widgetAction->setDefaultWidget(widget);
|
||||
contextMenu->addAction(widgetAction);
|
||||
|
||||
if(n_selected_items == 1) // if only one item is selected, allow to chat with this item
|
||||
{
|
||||
if(own_identities.size() <= 1)
|
||||
{
|
||||
QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity()));
|
||||
|
||||
if(own_identities.empty())
|
||||
action->setEnabled(false) ;
|
||||
else
|
||||
action->setData(QString::fromStdString((own_identities.front()).toStdString())) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
QMenu *mnu = contextMenu->addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ;
|
||||
|
||||
for(std::list<RsGxsId>::const_iterator it=own_identities.begin();it!=own_identities.end();++it)
|
||||
{
|
||||
RsIdentityDetails idd ;
|
||||
rsIdentity->getIdDetails(*it,idd) ;
|
||||
|
||||
QPixmap pixmap ;
|
||||
|
||||
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
|
||||
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ;
|
||||
|
||||
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity()));
|
||||
action->setData(QString::fromStdString((*it).toStdString())) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// always allow to send messages
|
||||
contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg()));
|
||||
|
||||
contextMenu->addSeparator();
|
||||
|
||||
if(n_is_a_contact == 0)
|
||||
contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts()));
|
||||
|
||||
if(n_is_not_a_contact == 0)
|
||||
contextMenu->addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts()));
|
||||
|
||||
contextMenu->addSeparator();
|
||||
|
||||
if(n_positive_reputations == 0) // only unban when all items are banned
|
||||
contextMenu->addAction(QIcon(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson()));
|
||||
|
||||
if(n_neutral_reputations == 0) // only unban when all items are banned
|
||||
contextMenu->addAction(QIcon(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
|
||||
|
||||
if(n_negative_reputations == 0)
|
||||
contextMenu->addAction(QIcon(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
|
||||
}
|
||||
|
||||
if(one_item_owned_by_you && n_selected_items==1)
|
||||
{
|
||||
contextMenu->addSeparator();
|
||||
|
||||
contextMenu->addAction(ui->editIdentity);
|
||||
contextMenu->addAction(ui->removeIdentity);
|
||||
}
|
||||
|
||||
root_node_present = true ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
contextMenu = ui->idTreeWidget->createStandardContextMenu(contextMenu);
|
||||
uint32_t item_flags = (*it)->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ;
|
||||
|
||||
contextMenu->exec(QCursor::pos());
|
||||
delete contextMenu;
|
||||
if(item_flags & RSID_FILTER_OWNED_BY_YOU)
|
||||
one_item_owned_by_you = true ;
|
||||
|
||||
#ifdef ID_DEBUG
|
||||
std::cerr << " item flags = " << item_flags << std::endl;
|
||||
#endif
|
||||
RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString());
|
||||
|
||||
RsIdentityDetails det ;
|
||||
rsIdentity->getIdDetails(keyId,det) ;
|
||||
|
||||
switch(det.mReputation.mOwnOpinion)
|
||||
{
|
||||
case RsReputations::OPINION_NEGATIVE: ++n_negative_reputations ;
|
||||
break ;
|
||||
|
||||
case RsReputations::OPINION_POSITIVE: ++n_positive_reputations ;
|
||||
break ;
|
||||
|
||||
case RsReputations::OPINION_NEUTRAL: ++n_neutral_reputations ;
|
||||
break ;
|
||||
}
|
||||
|
||||
++n_selected_items ;
|
||||
|
||||
if(rsIdentity->isARegularContact(keyId))
|
||||
++n_is_a_contact ;
|
||||
else
|
||||
++n_is_not_a_contact ;
|
||||
}
|
||||
|
||||
if(!root_node_present) // don't show menu if some of the root nodes are present
|
||||
{
|
||||
|
||||
if(!one_item_owned_by_you)
|
||||
{
|
||||
QWidget *widget = new QWidget(contextMenu);
|
||||
widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}");
|
||||
|
||||
// create menu header
|
||||
QHBoxLayout *hbox = new QHBoxLayout(widget);
|
||||
hbox->setMargin(0);
|
||||
hbox->setSpacing(6);
|
||||
|
||||
QLabel *iconLabel = new QLabel(widget);
|
||||
QPixmap pix = QPixmap(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5);
|
||||
iconLabel->setPixmap(pix);
|
||||
iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width());
|
||||
hbox->addWidget(iconLabel);
|
||||
|
||||
QLabel *textLabel = new QLabel("<strong>" + ui->titleBarLabel->text() + "</strong>", widget);
|
||||
hbox->addWidget(textLabel);
|
||||
|
||||
QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
hbox->addItem(spacerItem);
|
||||
|
||||
widget->setLayout(hbox);
|
||||
|
||||
QWidgetAction *widgetAction = new QWidgetAction(this);
|
||||
widgetAction->setDefaultWidget(widget);
|
||||
contextMenu->addAction(widgetAction);
|
||||
|
||||
if(n_selected_items == 1) // if only one item is selected, allow to chat with this item
|
||||
{
|
||||
if(own_identities.size() <= 1)
|
||||
{
|
||||
QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity()));
|
||||
|
||||
if(own_identities.empty())
|
||||
action->setEnabled(false) ;
|
||||
else
|
||||
action->setData(QString::fromStdString((own_identities.front()).toStdString())) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
QMenu *mnu = contextMenu->addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ;
|
||||
|
||||
for(std::list<RsGxsId>::const_iterator it=own_identities.begin();it!=own_identities.end();++it)
|
||||
{
|
||||
RsIdentityDetails idd ;
|
||||
rsIdentity->getIdDetails(*it,idd) ;
|
||||
|
||||
QPixmap pixmap ;
|
||||
|
||||
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
|
||||
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ;
|
||||
|
||||
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity()));
|
||||
action->setData(QString::fromStdString((*it).toStdString())) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(n_selected_items==1)
|
||||
QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ;
|
||||
|
||||
// always allow to send messages
|
||||
contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg()));
|
||||
|
||||
contextMenu->addSeparator();
|
||||
|
||||
if(n_is_a_contact == 0)
|
||||
contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts()));
|
||||
|
||||
if(n_is_not_a_contact == 0)
|
||||
contextMenu->addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts()));
|
||||
|
||||
contextMenu->addSeparator();
|
||||
|
||||
if(n_positive_reputations == 0) // only unban when all items are banned
|
||||
contextMenu->addAction(QIcon(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson()));
|
||||
|
||||
if(n_neutral_reputations == 0) // only unban when all items are banned
|
||||
contextMenu->addAction(QIcon(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
|
||||
|
||||
if(n_negative_reputations == 0)
|
||||
contextMenu->addAction(QIcon(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
|
||||
}
|
||||
|
||||
if(one_item_owned_by_you && n_selected_items==1)
|
||||
{
|
||||
contextMenu->addSeparator();
|
||||
|
||||
contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ;
|
||||
contextMenu->addAction(ui->editIdentity);
|
||||
contextMenu->addAction(ui->removeIdentity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contextMenu = ui->idTreeWidget->createStandardContextMenu(contextMenu);
|
||||
|
||||
contextMenu->exec(QCursor::pos());
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
void IdDialog::copyRetroshareLink()
|
||||
{
|
||||
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
|
||||
|
||||
if (!item)
|
||||
{
|
||||
std::cerr << "IdDialog::editIdentity() Invalid item";
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsGxsId gxs_id(item->text(RSID_COL_KEYID).toStdString());
|
||||
|
||||
if(gxs_id.isNull())
|
||||
{
|
||||
std::cerr << "Null GXS id. Something went wrong." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
RsIdentityDetails details ;
|
||||
|
||||
if(! rsIdentity->getIdDetails(gxs_id,details))
|
||||
return ;
|
||||
|
||||
if (!mIdQueue)
|
||||
return;
|
||||
|
||||
mStateHelper->setLoading(IDDIALOG_SERIALIZED_GROUP, true);
|
||||
|
||||
mIdQueue->cancelActiveRequestTokens(IDDIALOG_SERIALIZED_GROUP);
|
||||
|
||||
std::list<RsGxsGroupId> ids ;
|
||||
ids.push_back(RsGxsGroupId(gxs_id)) ;
|
||||
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA;
|
||||
|
||||
uint32_t token;
|
||||
|
||||
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, IDDIALOG_SERIALIZED_GROUP);
|
||||
}
|
||||
|
||||
void IdDialog::chatIdentity()
|
||||
|
@ -93,6 +93,7 @@ private slots:
|
||||
void editIdentity();
|
||||
void chatIdentity();
|
||||
void sendMsg();
|
||||
void copyRetroshareLink();
|
||||
void on_closeInfoFrameButton_clicked();
|
||||
|
||||
void updateSelection();
|
||||
@ -132,6 +133,7 @@ private:
|
||||
|
||||
void requestRepList();
|
||||
void insertRepList(uint32_t token);
|
||||
void handleSerializedGroupData(uint32_t token);
|
||||
|
||||
void requestIdEdit(std::string &id);
|
||||
void showIdEdit(uint32_t token);
|
||||
|
@ -287,7 +287,7 @@
|
||||
<height>692</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="headerFramePerson">
|
||||
<property name="frameShape">
|
||||
@ -296,12 +296,12 @@
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<layout class="QGridLayout" name="headerFramePersonGLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="headerFramePersonVLayout">
|
||||
<item>
|
||||
<widget class="StyledElidedLabel" name="headerTextLabel_Person">
|
||||
<property name="text">
|
||||
@ -397,7 +397,7 @@
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="distantFrameHLayout">
|
||||
<layout class="QHBoxLayout" name="inviteFrameHLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
@ -514,7 +514,7 @@ border-image: url(:/images/closepressed.png)
|
||||
<property name="title">
|
||||
<string>Identity info</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<layout class="QGridLayout" name="detailsGroupBoxGLayout">
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
|
||||
<property name="toolTip">
|
||||
@ -526,7 +526,7 @@ border-image: url(:/images/closepressed.png)
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="label_YourOpinion">
|
||||
<property name="text">
|
||||
<string>Your opinion:</string>
|
||||
</property>
|
||||
@ -540,7 +540,7 @@ border-image: url(:/images/closepressed.png)
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<widget class="Line" name="line_IdInfo">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -728,7 +728,7 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QLineEdit" name="lineEdit_LastUsed"/>
|
||||
</item>
|
||||
<item row="1" column="2" rowspan="11">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<layout class="QGridLayout" name="avatarGLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="avatarLabel">
|
||||
<property name="sizePolicy">
|
||||
@ -774,12 +774,12 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<layout class="QHBoxLayout" name="avatarOpinionHLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<widget class="QLabel" name="label_PosIcon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>34</width>
|
||||
@ -813,14 +813,14 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_3">
|
||||
<widget class="Line" name="line_Opinion">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<widget class="QLabel" name="label_NegIcon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>34</width>
|
||||
@ -856,7 +856,7 @@ p, li { white-space: pre-wrap; }
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="avatarVSpacer_2">
|
||||
<spacer name="avatarVSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@ -874,11 +874,11 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<widget class="QGroupBox" name="usageStatisticsGBox">
|
||||
<property name="title">
|
||||
<string>Usage statistics</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="usageStatisticsGBoxHLayout">
|
||||
<item>
|
||||
<widget class="RSTextBrowser" name="usageStatistics_TB"/>
|
||||
</item>
|
||||
@ -886,7 +886,7 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<spacer name="scrollAreaWidgetContentsVSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@ -900,10 +900,8 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>detailsGroupBox</zorder>
|
||||
<zorder>detailsGroupBox</zorder>
|
||||
<zorder>groupBox</zorder>
|
||||
<zorder>usageStatisticsGBox</zorder>
|
||||
<zorder>headerFramePerson</zorder>
|
||||
<zorder>verticalSpacer_2</zorder>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -1207,7 +1207,7 @@ void MainWindow::showHelpDialog(const QString &topic)
|
||||
void
|
||||
MainWindow::retranslateUi()
|
||||
{
|
||||
retranslateUi();
|
||||
//retranslateUi();
|
||||
foreach (MainPage *page, ui->stackPages->pages()) {
|
||||
page->retranslateUi();
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info
|
||||
}
|
||||
}
|
||||
|
||||
QSize CircleWidget::sizeHint()
|
||||
QSize CircleWidget::sizeHint() const
|
||||
{
|
||||
QSize size;
|
||||
size.setHeight(ui->graphicsView->size().height() + ui->label->size().height());
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
, const RsGxsCircleDetails& details);
|
||||
|
||||
//Start QWidget Properties
|
||||
QSize sizeHint();
|
||||
QSize sizeHint() const;
|
||||
//Start FlowLayoutItem Properties
|
||||
virtual const QPixmap getImage();
|
||||
virtual const QPixmap getDragImage();
|
||||
|
@ -148,7 +148,7 @@ void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info, const RsPeer
|
||||
updateData(pgp_details);
|
||||
}
|
||||
|
||||
QSize IdentityWidget::sizeHint()
|
||||
QSize IdentityWidget::sizeHint() const
|
||||
{
|
||||
QSize size;
|
||||
size.setHeight(ui->graphicsView->size().height() + ui->labelName->size().height());
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
, const RsPeerDetails& pgp_details);
|
||||
|
||||
//Start QWidget Properties
|
||||
QSize sizeHint();
|
||||
QSize sizeHint() const;
|
||||
//Start FlowLayoutItem Properties
|
||||
virtual const QPixmap getImage();
|
||||
virtual const QPixmap getDragImage();
|
||||
|
@ -901,7 +901,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event)
|
||||
|
||||
QWidget *wid =
|
||||
qobject_cast<QWidget *>(event->source());//QT5 return QObject
|
||||
FlowLayout *layout;
|
||||
FlowLayout *layout = NULL;
|
||||
if (wid) layout =
|
||||
qobject_cast<FlowLayout *>(wid->layout());
|
||||
if (layout) {
|
||||
@ -991,7 +991,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event)
|
||||
|
||||
QWidget *wid =
|
||||
qobject_cast<QWidget *>(event->source());//QT5 return QObject
|
||||
FlowLayout *layout;
|
||||
FlowLayout *layout = NULL;
|
||||
if (wid) layout =
|
||||
qobject_cast<FlowLayout *>(wid->layout());
|
||||
if (layout) {
|
||||
|
@ -67,7 +67,8 @@
|
||||
#define HOST_SEARCH "search"
|
||||
#define HOST_CERTIFICATE "certificate"
|
||||
#define HOST_PUBLIC_MSG "public_msg"
|
||||
#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg"
|
||||
#define HOST_IDENTITY "identity"
|
||||
#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg|identity"
|
||||
|
||||
#define FILE_NAME "name"
|
||||
#define FILE_SIZE "size"
|
||||
@ -89,6 +90,9 @@
|
||||
#define POSTED_ID "id"
|
||||
#define POSTED_MSGID "msgid"
|
||||
|
||||
#define IDENTITY_NAME "name"
|
||||
#define IDENTITY_ID "gxsid"
|
||||
#define IDENTITY_GROUP "groupdata"
|
||||
|
||||
#define MESSAGE_ID "id"
|
||||
#define MESSAGE_SUBJECT "subject"
|
||||
@ -303,6 +307,21 @@ void RetroShareLink::fromUrl(const QUrl& url)
|
||||
return;
|
||||
}
|
||||
|
||||
if(url.host() == HOST_IDENTITY) {
|
||||
_type = TYPE_IDENTITY ;
|
||||
QString name = decodedQueryItemValue(urlQuery, IDENTITY_NAME) ;
|
||||
QString radix= decodedQueryItemValue(urlQuery, IDENTITY_GROUP) ;
|
||||
QString gxsid= urlQuery.queryItemValue(IDENTITY_ID) ;
|
||||
|
||||
RsGxsId id(gxsid.toStdString()) ;
|
||||
|
||||
if(!id.isNull())
|
||||
createIdentity(id,name,radix) ;
|
||||
else
|
||||
std::cerr << "(EE) identity link is not valid." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
if (url.host() == HOST_MESSAGE) {
|
||||
_type = TYPE_MESSAGE;
|
||||
std::string id = urlQuery.queryItemValue(MESSAGE_ID).toStdString();
|
||||
@ -312,7 +331,7 @@ void RetroShareLink::fromUrl(const QUrl& url)
|
||||
|
||||
if (url.host() == HOST_CERTIFICATE) {
|
||||
_type = TYPE_CERTIFICATE;
|
||||
_radix = urlQuery.queryItemValue(CERTIFICATE_RADIX);
|
||||
_radix = decodedQueryItemValue(urlQuery, CERTIFICATE_RADIX);
|
||||
|
||||
#ifdef DEBUG_RSLINK
|
||||
std::cerr << "Got a certificate link!!" << std::endl;
|
||||
@ -333,6 +352,21 @@ RetroShareLink::RetroShareLink()
|
||||
clear();
|
||||
}
|
||||
|
||||
bool RetroShareLink::createIdentity(const RsGxsId& id, const QString& name, const QString& radix_data)
|
||||
{
|
||||
clear();
|
||||
|
||||
_name = name;
|
||||
_hash = QString::fromStdString(id.toStdString());
|
||||
_radix_group_data = radix_data ;
|
||||
|
||||
_type = TYPE_IDENTITY;
|
||||
|
||||
check();
|
||||
|
||||
return valid();
|
||||
}
|
||||
|
||||
bool RetroShareLink::createExtraFile(const QString& name, uint64_t size, const QString& hash,const QString& ssl_id)
|
||||
{
|
||||
clear();
|
||||
@ -534,6 +568,7 @@ void RetroShareLink::clear()
|
||||
_GPGid = "" ;
|
||||
_time_stamp = 0 ;
|
||||
_encrypted_chat_info = "" ;
|
||||
_radix_group_data = "" ;
|
||||
}
|
||||
|
||||
void RetroShareLink::check()
|
||||
@ -565,6 +600,17 @@ void RetroShareLink::check()
|
||||
if(!checkPGPId(_GPGid)) _valid = false ;
|
||||
break ;
|
||||
|
||||
case TYPE_IDENTITY:
|
||||
if(_name.isNull())
|
||||
_valid = false ;
|
||||
|
||||
if(_radix_group_data.isNull())
|
||||
_valid = false ;
|
||||
|
||||
if(_hash.isNull())
|
||||
_valid = false ;
|
||||
break ;
|
||||
|
||||
case TYPE_PERSON:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
@ -651,6 +697,9 @@ QString RetroShareLink::title() const
|
||||
return QObject::tr("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size()));
|
||||
case TYPE_FILE:
|
||||
return QString("%1 (%2)").arg(hash()).arg(misc::friendlyUnit(size()));
|
||||
case TYPE_IDENTITY:
|
||||
return _name ;
|
||||
|
||||
case TYPE_PERSON:
|
||||
return PeerDefs::rsidFromId(RsPgpId(hash().toStdString()));
|
||||
case TYPE_FORUM:
|
||||
@ -711,6 +760,14 @@ QString RetroShareLink::toString() const
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_IDENTITY:
|
||||
url.setScheme(RSLINK_SCHEME) ;
|
||||
url.setHost(HOST_IDENTITY) ;
|
||||
urlQuery.addQueryItem(IDENTITY_ID,_hash) ;
|
||||
urlQuery.addQueryItem(IDENTITY_NAME,encodeItem(_name)) ;
|
||||
urlQuery.addQueryItem(IDENTITY_GROUP,encodeItem(_radix_group_data)) ;
|
||||
break ;
|
||||
|
||||
case TYPE_EXTRAFILE:
|
||||
url.setScheme(RSLINK_SCHEME);
|
||||
url.setHost(HOST_EXTRAFILE);
|
||||
@ -782,9 +839,9 @@ QString RetroShareLink::toString() const
|
||||
case TYPE_CERTIFICATE:
|
||||
url.setScheme(RSLINK_SCHEME);
|
||||
url.setHost(HOST_CERTIFICATE) ;
|
||||
urlQuery.addQueryItem(CERTIFICATE_RADIX, _radix);
|
||||
urlQuery.addQueryItem(CERTIFICATE_NAME, _name);
|
||||
urlQuery.addQueryItem(CERTIFICATE_LOCATION, _location);
|
||||
urlQuery.addQueryItem(CERTIFICATE_RADIX, encodeItem(_radix));
|
||||
urlQuery.addQueryItem(CERTIFICATE_NAME, encodeItem(_name));
|
||||
urlQuery.addQueryItem(CERTIFICATE_LOCATION, encodeItem(_location));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -798,9 +855,11 @@ QString RetroShareLink::toString() const
|
||||
|
||||
QString RetroShareLink::niceName() const
|
||||
{
|
||||
if (type() == TYPE_PERSON) {
|
||||
if (type() == TYPE_PERSON)
|
||||
return PeerDefs::rsid(name().toUtf8().constData(), RsPgpId(hash().toStdString()));
|
||||
}
|
||||
|
||||
if(type() == TYPE_IDENTITY)
|
||||
return QObject::tr("Identity link (name=%1, ID=%2)").arg(_name).arg(_hash) ;
|
||||
|
||||
if(type() == TYPE_PUBLIC_MSG) {
|
||||
RsPeerDetails detail;
|
||||
@ -1011,6 +1070,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
||||
case TYPE_POSTED:
|
||||
case TYPE_SEARCH:
|
||||
case TYPE_MESSAGE:
|
||||
case TYPE_IDENTITY:
|
||||
case TYPE_CERTIFICATE:
|
||||
case TYPE_PUBLIC_MSG:
|
||||
case TYPE_PRIVATE_CHAT:
|
||||
@ -1156,6 +1216,15 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
||||
}
|
||||
break ;
|
||||
|
||||
case TYPE_IDENTITY:
|
||||
{
|
||||
if(rsIdentity->deserialiseIdentityFromMemory(link.radixGroupData().toStdString()))
|
||||
QMessageBox::information(NULL,QObject::tr("Identity added to People"),QObject::tr("The identity was added to people. You can now chat with it, send messages to it, etc.")) ;
|
||||
else
|
||||
QMessageBox::warning(NULL,QObject::tr("Identity cannot be added to People"),QObject::tr("The identity was not added to people. Some error occured. The link is probably corrupted.")) ;
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_FILE:
|
||||
case TYPE_EXTRAFILE:
|
||||
{
|
||||
|
@ -68,7 +68,8 @@ class RetroShareLink
|
||||
TYPE_EXTRAFILE = 0x08,
|
||||
TYPE_PRIVATE_CHAT = 0x09,
|
||||
TYPE_PUBLIC_MSG = 0x0a,
|
||||
TYPE_POSTED = 0x0b
|
||||
TYPE_POSTED = 0x0b,
|
||||
TYPE_IDENTITY = 0x0c
|
||||
};
|
||||
|
||||
public:
|
||||
@ -76,7 +77,7 @@ class RetroShareLink
|
||||
RetroShareLink(const QUrl& url);
|
||||
RetroShareLink(const QString& url);
|
||||
|
||||
#warning these methods should be static and return a created link
|
||||
#warning csoler 2017-01-04: These methods should be static and return a created link
|
||||
bool createFile(const QString& name, uint64_t size, const QString& hash);
|
||||
bool createExtraFile(const QString& name, uint64_t size, const QString& hash, const QString& ssl_id);
|
||||
bool createPerson(const RsPgpId &id);
|
||||
@ -85,6 +86,7 @@ class RetroShareLink
|
||||
bool createSearch(const QString& keywords);
|
||||
bool createMessage(const RsPeerId &peerId, const QString& subject);
|
||||
bool createMessage(const RsGxsId &peerId, const QString& subject);
|
||||
bool createIdentity(const RsGxsId& gxs_id,const QString& name,const QString& radix_data) ;
|
||||
bool createCertificate(const RsPeerId &ssl_id) ;
|
||||
bool createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ;
|
||||
bool createUnknwonSslCertificate(const RsPeerId &sslId, const RsPgpId &gpgId = RsPgpId()) ;
|
||||
@ -101,12 +103,13 @@ class RetroShareLink
|
||||
const QString& SSLId() const { return _SSLid ; }
|
||||
const QString& GPGId() const { return _GPGid ; }
|
||||
const QString& localIPAndPort() const { return _loc_ip_port ; }
|
||||
const QString& externalIPAndPort() const { return _ext_ip_port ; }
|
||||
const QString& dyndns() const { return _dyndns_name ; }
|
||||
const QString& location() const { return _location ; }
|
||||
const QString& radix() const { return _radix ; }
|
||||
time_t timeStamp() const { return _time_stamp ; }
|
||||
QString title() const;
|
||||
const QString& externalIPAndPort() const { return _ext_ip_port ; }
|
||||
const QString& dyndns() const { return _dyndns_name ; }
|
||||
const QString& location() const { return _location ; }
|
||||
const QString& radix() const { return _radix ; }
|
||||
time_t timeStamp() const { return _time_stamp ; }
|
||||
QString title() const;
|
||||
QString radixGroupData() const { return _radix_group_data ;}
|
||||
|
||||
unsigned int subType() const { return _subType; }
|
||||
void setSubType(unsigned int subType) { _subType = subType; }
|
||||
@ -158,12 +161,13 @@ class RetroShareLink
|
||||
QString _GPGBase64String ; // GPG Cert
|
||||
QString _GPGBase64CheckSum ; // GPG Cert
|
||||
QString _location ; // location
|
||||
QString _ext_ip_port ;
|
||||
QString _loc_ip_port ;
|
||||
QString _dyndns_name ;
|
||||
QString _ext_ip_port ;
|
||||
QString _loc_ip_port ;
|
||||
QString _dyndns_name ;
|
||||
QString _radix ;
|
||||
QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite
|
||||
time_t _time_stamp ; // time stamp at which the link will expire.
|
||||
QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite
|
||||
time_t _time_stamp ; // time stamp at which the link will expire.
|
||||
QString _radix_group_data;
|
||||
|
||||
unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...)
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ void ChatDialog::closeEvent(QCloseEvent *event)
|
||||
emit dialogClose(this);
|
||||
}
|
||||
|
||||
void ChatDialog::init(ChatId id, const QString &title)
|
||||
void ChatDialog::init(const ChatId &id, const QString &title)
|
||||
{
|
||||
mChatId = id;
|
||||
ChatWidget *cw = getChatWidget();
|
||||
@ -102,14 +102,14 @@ void ChatDialog::init(ChatId id, const QString &title)
|
||||
if (chatflags & RS_CHAT_OPEN) {
|
||||
if (id.isLobbyId()) {
|
||||
ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId());
|
||||
cld->init();
|
||||
cld->init(ChatId(), "");
|
||||
cd = cld;
|
||||
}
|
||||
else if(id.isDistantChatId())
|
||||
{
|
||||
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
|
||||
|
||||
pdcd->init(id.toDistantChatId());
|
||||
pdcd->init(id, "");
|
||||
cd = pdcd;
|
||||
}
|
||||
else
|
||||
|
@ -84,7 +84,7 @@ protected:
|
||||
virtual QString getPeerName(const ChatId &sslid) const ; // can be overloaded for chat dialogs that have specific peers
|
||||
virtual QString getOwnName() const;
|
||||
|
||||
virtual void init(ChatId id, const QString &title);
|
||||
virtual void init(const ChatId &id, const QString &title);
|
||||
virtual void addChatMsg(const ChatMessage& msg) = 0;
|
||||
|
||||
ChatId mChatId;
|
||||
|
@ -304,7 +304,7 @@ void ChatLobbyDialog::showInPeopleTab()
|
||||
idDialog->navigate(nickname);
|
||||
}
|
||||
|
||||
void ChatLobbyDialog::init()
|
||||
void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/)
|
||||
{
|
||||
ChatLobbyInfo linfo ;
|
||||
|
||||
|
@ -71,7 +71,7 @@ protected:
|
||||
virtual ~ChatLobbyDialog();
|
||||
|
||||
void processSettings(bool load);
|
||||
virtual void init();
|
||||
virtual void init(const ChatId &id, const QString &title);
|
||||
virtual bool canClose();
|
||||
virtual void addChatMsg(const ChatMessage &msg);
|
||||
|
||||
|
@ -76,7 +76,7 @@ ChatWidget::ChatWidget(QWidget *parent) :
|
||||
|
||||
int iconHeight = FMM*QFontMetricsF(font()).height() ;
|
||||
QSize iconSize = QSize(iconHeight,iconHeight);
|
||||
QSize buttonSize = QSize(iconSize + QSize(FMM,FMM));
|
||||
QSize buttonSize = QSize(iconSize + QSize((int)FMM,(int)FMM));
|
||||
|
||||
newMessages = false;
|
||||
typing = false;
|
||||
@ -258,7 +258,7 @@ void ChatWidget::addChatBarWidget(QWidget *w)
|
||||
{
|
||||
int iconHeight = FMM*QFontMetricsF(font()).height() ;
|
||||
QSize iconSize = QSize(iconHeight,iconHeight);
|
||||
QSize buttonSize = QSize(iconSize + QSize(FMM,FMM));
|
||||
QSize buttonSize = QSize(iconSize + QSize((int)FMM,(int)FMM));
|
||||
w->setFixedSize(buttonSize);
|
||||
ui->pluginButtonFrame->layout()->addWidget(w) ;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ protected:
|
||||
/** Default destructor */
|
||||
virtual ~PopupChatDialog();
|
||||
|
||||
virtual void init(const ChatId &chat_id, const QString &title);
|
||||
virtual void init(const ChatId &chat_id, const QString &title);
|
||||
virtual void showDialog(uint chatflags);
|
||||
virtual ChatWidget *getChatWidget();
|
||||
virtual bool hasPeerStatus() { return true; }
|
||||
|
@ -63,9 +63,12 @@ PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_i
|
||||
updateDisplay() ;
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
|
||||
void PopupDistantChatDialog::init(const ChatId &chat_id, const QString &/*title*/)
|
||||
{
|
||||
_tunnel_id = peer_id;
|
||||
if (!chat_id.isDistantChatId())
|
||||
return;
|
||||
|
||||
_tunnel_id = chat_id.toDistantChatId();
|
||||
DistantChatPeerInfo tinfo;
|
||||
|
||||
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
|
||||
@ -74,15 +77,15 @@ void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
|
||||
RsIdentityDetails iddetails ;
|
||||
|
||||
if(rsIdentity->getIdDetails(tinfo.to_id,iddetails))
|
||||
PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ;
|
||||
PopupChatDialog::init(chat_id, QString::fromUtf8(iddetails.mNickname.c_str())) ;
|
||||
else
|
||||
PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ;
|
||||
PopupChatDialog::init(chat_id, QString::fromStdString(tinfo.to_id.toStdString())) ;
|
||||
|
||||
// Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
|
||||
// it will not be transmitted.
|
||||
|
||||
ui.ownAvatarWidget->setOwnId() ; // sets the flag
|
||||
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
|
||||
ui.ownAvatarWidget->setId(chat_id) ; // sets the actual Id
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::updateDisplay()
|
||||
|
@ -38,7 +38,7 @@ class PopupDistantChatDialog: public PopupChatDialog
|
||||
/** Default destructor */
|
||||
virtual ~PopupDistantChatDialog();
|
||||
|
||||
virtual void init(const DistantChatPeerId& peer_id);
|
||||
virtual void init(const ChatId& chat_id, const QString &title);
|
||||
virtual void closeEvent(QCloseEvent *e) ;
|
||||
|
||||
virtual QString getPeerName(const ChatId &id) const ;
|
||||
|
@ -76,11 +76,20 @@ RWindow::restoreWindowState()
|
||||
m_bSaveStateOnClose = true; // now we save the window state on close
|
||||
|
||||
#if QT_VERSION >= 0x040200
|
||||
QByteArray geometry = getSetting("Geometry", QByteArray()).toByteArray();
|
||||
if (geometry.isEmpty())
|
||||
QByteArray geo = getSetting("Geometry", QByteArray()).toByteArray();
|
||||
if (geo.isEmpty())
|
||||
{
|
||||
adjustSize();
|
||||
QRect rect = geometry();
|
||||
int h = fontMetrics().height()*40;
|
||||
if (rect.height()<h)
|
||||
{
|
||||
rect.setHeight(h);
|
||||
setGeometry(rect);
|
||||
}
|
||||
}
|
||||
else
|
||||
restoreGeometry(geometry);
|
||||
restoreGeometry(geo);
|
||||
#else
|
||||
QRect screen = QDesktopWidget().availableGeometry();
|
||||
|
||||
|
@ -239,9 +239,9 @@ void ConfCertDialog::load()
|
||||
ui.version->show();
|
||||
ui.label_version->show();
|
||||
|
||||
ui.groupBox->show();
|
||||
//ui.groupBox->show();
|
||||
ui.groupBox_4->show();
|
||||
ui.tabWidget->show();
|
||||
//ui.tabWidget->show();
|
||||
//ui.rsid->hide();
|
||||
//ui.label_rsid->hide();
|
||||
ui.pgpfingerprint->show();
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>722</width>
|
||||
<height>651</height>
|
||||
<width>1104</width>
|
||||
<height>1086</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -69,7 +69,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="stabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="icon">
|
||||
@ -85,7 +85,7 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Friend info</string>
|
||||
<string>Node info:</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="3" column="1">
|
||||
@ -249,6 +249,114 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Current address:</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="localPort">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>7812</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="dynDNS"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QSpinBox" name="extPort">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>7812</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="l_dynDNS">
|
||||
<property name="text">
|
||||
<string>Dynamic DNS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="localAddress"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="l_extAddress">
|
||||
<property name="text">
|
||||
<string>External Address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="extAddress"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="l_portExternal">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="l_portLocal">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="l_localAddress">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Local Address</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>List of known addresses:</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QListWidget" name="ipAddressList">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::DefaultContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@ -264,170 +372,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/kcmsystem24.png</normaloff>:/images/kcmsystem24.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Connectivity</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_15">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_5">
|
||||
<attribute name="title">
|
||||
<string>Peer Addresses</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Peer Address</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>47</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>47</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="l_localAddress">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Local Address</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="localAddress"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="l_extAddress">
|
||||
<property name="text">
|
||||
<string>External Address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="extAddress"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="l_dynDNS">
|
||||
<property name="text">
|
||||
<string>Dynamic DNS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="dynDNS"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="l_portLocal">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="l_portExternal">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QSpinBox" name="localPort">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>7812</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="extPort">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>7812</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_6">
|
||||
<attribute name="title">
|
||||
<string>Addresses list</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Addresses list</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QListWidget" name="ipAddressList">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::DefaultContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Retroshare Certificate</string>
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static const double Pi = 3.14159265358979323846264338327950288419717;
|
||||
//static const double Pi = 3.14159265358979323846264338327950288419717;
|
||||
|
||||
Edge::Edge(Node *sourceNode, Node *destNode)
|
||||
: arrowSize(10)
|
||||
|
@ -362,7 +362,7 @@ void GraphWidget::timerEvent(QTimerEvent *event)
|
||||
|
||||
bool itemsMoved = false;
|
||||
foreach (Node *node, _nodes)
|
||||
if(node->advance())
|
||||
if(node->progress())
|
||||
itemsMoved = true;
|
||||
|
||||
if (!itemsMoved) {
|
||||
|
@ -215,7 +215,7 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl
|
||||
newPos.setY(qMin(qMax(newPos.y(), sceneRect.top()) , sceneRect.bottom()));
|
||||
}
|
||||
|
||||
bool Node::advance()
|
||||
bool Node::progress()
|
||||
{
|
||||
if(_type == GraphWidget::ELASTIC_NODE_TYPE_OWN)
|
||||
return false;
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
std::string descString() const { return _desc_string ; }
|
||||
|
||||
void calculateForces(const double *data,int width,int height,int W,int H,float x,float y,float speedf);
|
||||
bool advance();
|
||||
bool progress();
|
||||
|
||||
QRectF boundingRect() const;
|
||||
QPainterPath shape() const;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <QDateTime>
|
||||
#include <QMenu>
|
||||
|
||||
#include "gui/common/RSElidedItemDelegate.h"
|
||||
#include "gui/gxs/GxsCommentTreeWidget.h"
|
||||
#include "gui/gxs/GxsCreateCommentDialog.h"
|
||||
#include "gui/gxs/GxsIdTreeWidgetItem.h"
|
||||
@ -57,6 +58,10 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
||||
// QTreeWidget* widget = this;
|
||||
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this);
|
||||
itemDelegate->setSpacing(QSize(0, 2));
|
||||
setItemDelegate(itemDelegate);
|
||||
setWordWrap(true);
|
||||
// QFont font = QFont("ARIAL", 10);
|
||||
// font.setBold(true);
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "GxsCreateCommentDialog.h"
|
||||
#include "ui_GxsCreateCommentDialog.h"
|
||||
|
||||
#include "util/HandleRichText.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <iostream>
|
||||
|
||||
@ -45,7 +47,11 @@ void GxsCreateCommentDialog::createComment()
|
||||
{
|
||||
RsGxsComment comment;
|
||||
|
||||
comment.mComment = std::string(ui->commentTextEdit->document()->toPlainText().toUtf8());
|
||||
QString text = ui->commentTextEdit->toHtml();
|
||||
RsHtml::optimizeHtml(text);
|
||||
std::string msg = text.toUtf8().constData();
|
||||
|
||||
comment.mComment = msg;
|
||||
comment.mMeta.mParentId = mParentId.second;
|
||||
comment.mMeta.mGroupId = mParentId.first;
|
||||
comment.mMeta.mThreadId = mThreadId;
|
||||
|
@ -841,8 +841,11 @@ void GxsGroupFrameDialog::insertGroupsData(const std::list<RsGroupMetaData> &gro
|
||||
/* now we can add them in as a tree! */
|
||||
ui->groupTreeWidget->fillGroupItems(mYourGroups, adminList);
|
||||
ui->groupTreeWidget->fillGroupItems(mSubscribedGroups, subList);
|
||||
mSubscribedGroups->setText(2, QString::number(mSubscribedGroups->childCount())); // 1 COLUMN_UNREAD 2 COLUMN_POPULARITY
|
||||
ui->groupTreeWidget->fillGroupItems(mPopularGroups, popList);
|
||||
mPopularGroups->setText(2, QString::number(mPopularGroups->childCount()));
|
||||
ui->groupTreeWidget->fillGroupItems(mOtherGroups, otherList);
|
||||
mOtherGroups->setText(2, QString::number(mOtherGroups->childCount()));
|
||||
|
||||
mInFill = false;
|
||||
|
||||
|
@ -45,12 +45,13 @@
|
||||
#define CREATEGXSFORUMMSG_FORUMINFO 1
|
||||
#define CREATEGXSFORUMMSG_PARENTMSG 2
|
||||
#define CREATEGXSFORUMMSG_CIRCLENFO 3
|
||||
#define CREATEGXSFORUMMSG_ORIGMSG 4
|
||||
|
||||
//#define ENABLE_GENERATE
|
||||
|
||||
/** Constructor */
|
||||
CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId)
|
||||
: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mForumId(fId), mParentId(pId)
|
||||
CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId,const RsGxsMessageId& mOId,const RsGxsId& posterId)
|
||||
: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
ui.setupUi(this);
|
||||
@ -75,7 +76,14 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName);
|
||||
|
||||
QString text = pId.isNull() ? tr("Start New Thread") : tr("Post Forum Message");
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.buttonBox->button(QDialogButtonBox::Ok));
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName);
|
||||
|
||||
|
||||
QString text = mOId.isNull()?(pId.isNull() ? tr("Start New Thread") : tr("Post Forum Message")):tr("Edit Message");
|
||||
setWindowTitle(text);
|
||||
|
||||
ui.headerFrame->setHeaderImage(QPixmap(":/images/konversation64.png"));
|
||||
@ -103,7 +111,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
|
||||
|
||||
mParentMsgLoaded = false;
|
||||
mForumMetaLoaded = false;
|
||||
mForumCircleLoaded = false;
|
||||
mForumCircleLoaded = false;
|
||||
|
||||
newMsg();
|
||||
|
||||
@ -129,13 +137,24 @@ void CreateGxsForumMsg::newMsg()
|
||||
|
||||
//std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
|
||||
|
||||
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
||||
if(!mPosterId.isNull())
|
||||
{
|
||||
std::set<RsGxsId> id_set ;
|
||||
id_set.insert(mPosterId) ;
|
||||
|
||||
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE, mPosterId);
|
||||
ui.idChooser->setIdConstraintSet(id_set);
|
||||
}
|
||||
else
|
||||
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, mPosterId);
|
||||
|
||||
if (mForumId.isNull()) {
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false);
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||
mStateHelper->clear(CREATEGXSFORUMMSG_FORUMINFO);
|
||||
mStateHelper->clear(CREATEGXSFORUMMSG_PARENTMSG);
|
||||
mStateHelper->clear(CREATEGXSFORUMMSG_ORIGMSG);
|
||||
ui.forumName->setText(tr("No Forum"));
|
||||
return;
|
||||
}//if ( mForumId.isNull())
|
||||
@ -174,11 +193,53 @@ void CreateGxsForumMsg::newMsg()
|
||||
uint32_t token;
|
||||
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG);
|
||||
}//if (mParentId.isNull())
|
||||
|
||||
if (mOrigMsgId.isNull()) {
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||
mOrigMsgLoaded = true;
|
||||
} else {
|
||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
|
||||
GxsMsgReq msgIds;
|
||||
std::vector<RsGxsMessageId> &vect = msgIds[mForumId];
|
||||
vect.push_back(mOrigMsgId);
|
||||
|
||||
//std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")";
|
||||
//std::cerr << std::endl;
|
||||
|
||||
uint32_t token;
|
||||
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_ORIGMSG);
|
||||
}//if (mParentId.isNull())
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::loadFormInformation()
|
||||
{
|
||||
if (!mParentId.isNull()) {
|
||||
if (!mOrigMsgId.isNull())
|
||||
{
|
||||
if (mOrigMsgLoaded) {
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||
} else {
|
||||
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet";
|
||||
//std::cerr << std::endl;
|
||||
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true);
|
||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||
}
|
||||
|
||||
|
||||
if (!mParentId.isNull())
|
||||
{
|
||||
if (mParentMsgLoaded) {
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
|
||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
|
||||
@ -190,7 +251,9 @@ void CreateGxsForumMsg::loadFormInformation()
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
|
||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
|
||||
}
|
||||
@ -212,14 +275,24 @@ void CreateGxsForumMsg::loadFormInformation()
|
||||
|
||||
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
|
||||
|
||||
if( (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) || (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN))
|
||||
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ;
|
||||
else
|
||||
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED) ;
|
||||
|
||||
uint32_t fl = IDCHOOSER_ID_REQUIRED ;
|
||||
|
||||
if( (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) || (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN))
|
||||
fl |= IDCHOOSER_NON_ANONYMOUS ;
|
||||
|
||||
if(!mPosterId.isNull())
|
||||
fl |= IDCHOOSER_NO_CREATE;
|
||||
|
||||
ui.idChooser->setFlags(fl) ;
|
||||
|
||||
QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str());
|
||||
QString subj;
|
||||
if (!mParentId.isNull())
|
||||
|
||||
if(!mOrigMsgId.isNull())
|
||||
{
|
||||
subj = QString::fromUtf8(mOrigMsg.mMeta.mMsgName.c_str());
|
||||
}
|
||||
else if (!mParentId.isNull())
|
||||
{
|
||||
QString title = QString::fromUtf8(mParentMsg.mMeta.mMsgName.c_str());
|
||||
name += " " + tr("In Reply to") + ": ";
|
||||
@ -228,17 +301,14 @@ void CreateGxsForumMsg::loadFormInformation()
|
||||
QString text = title;
|
||||
|
||||
if (text.startsWith("Re:", Qt::CaseInsensitive))
|
||||
{
|
||||
subj = title;
|
||||
}
|
||||
else
|
||||
{
|
||||
subj = "Re: " + title;
|
||||
}
|
||||
}
|
||||
|
||||
ui.forumName->setText(misc::removeNewLine(name));
|
||||
ui.forumSubject->setText(misc::removeNewLine(subj));
|
||||
//ui.forumSubject->setReadOnly(!mOrigMsgId.isNull());
|
||||
|
||||
if (ui.forumSubject->text().isEmpty())
|
||||
{
|
||||
@ -286,6 +356,7 @@ void CreateGxsForumMsg::createMsg()
|
||||
RsGxsForumMsg msg;
|
||||
msg.mMeta.mGroupId = mForumId;
|
||||
msg.mMeta.mParentId = mParentId;
|
||||
msg.mMeta.mOrigMsgId = mOrigMsgId;
|
||||
msg.mMeta.mMsgId.clear() ;
|
||||
if (mParentMsgLoaded) {
|
||||
msg.mMeta.mThreadId = mParentMsg.mMeta.mThreadId;
|
||||
@ -377,9 +448,9 @@ void CreateGxsForumMsg::reject()
|
||||
{
|
||||
if (ui.forumMessage->document()->isModified()) {
|
||||
QMessageBox::StandardButton ret;
|
||||
ret = QMessageBox::warning(this, tr("Forum Message"),
|
||||
tr("Forum Message has not been Sent.\n"
|
||||
"Do you want to reject this message?"),
|
||||
ret = QMessageBox::warning(this, tr("Cancel Forum Message"),
|
||||
tr("Forum Message has not been sent yet!\n"
|
||||
"Do you want to discard this message?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
switch (ret) {
|
||||
case QMessageBox::Yes:
|
||||
@ -521,6 +592,35 @@ void CreateGxsForumMsg::loadForumCircleInfo(const uint32_t& token)
|
||||
}
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::loadOrigMsg(const uint32_t &token)
|
||||
{
|
||||
//std::cerr << "CreateGxsForumMsg::loadParentMsg()";
|
||||
//std::cerr << std::endl;
|
||||
|
||||
// Only grab one.... ignore more (shouldn't be any).
|
||||
std::vector<RsGxsForumMsg> msgs;
|
||||
if (rsGxsForums->getMsgData(token, msgs))
|
||||
{
|
||||
if (msgs.size() != 1)
|
||||
{
|
||||
/* error */
|
||||
std::cerr << "CreateGxsForumMsg::loadOrigMsg() ERROR wrong number of msgs";
|
||||
std::cerr << std::endl;
|
||||
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||
mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mOrigMsg = msgs[0];
|
||||
mOrigMsgLoaded = true;
|
||||
|
||||
loadFormInformation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
|
||||
{
|
||||
//std::cerr << "CreateGxsForumMsg::loadParentMsg()";
|
||||
@ -562,6 +662,9 @@ void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest
|
||||
case CREATEGXSFORUMMSG_FORUMINFO:
|
||||
loadForumInfo(req.mToken);
|
||||
break;
|
||||
case CREATEGXSFORUMMSG_ORIGMSG:
|
||||
loadOrigMsg(req.mToken);
|
||||
break;
|
||||
case CREATEGXSFORUMMSG_PARENTMSG:
|
||||
loadParentMsg(req.mToken);
|
||||
break;
|
||||
|
@ -36,7 +36,7 @@ class CreateGxsForumMsg : public QDialog, public TokenResponse
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId);
|
||||
CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId &moId, const RsGxsId &posterId = RsGxsId());
|
||||
~CreateGxsForumMsg();
|
||||
|
||||
void newMsg(); /* cleanup */
|
||||
@ -61,18 +61,24 @@ private:
|
||||
|
||||
void loadForumInfo(const uint32_t &token);
|
||||
void loadParentMsg(const uint32_t &token);
|
||||
void loadOrigMsg(const uint32_t &token);
|
||||
void loadForumCircleInfo(const uint32_t &token);
|
||||
|
||||
RsGxsGroupId mForumId;
|
||||
RsGxsCircleId mCircleId ;
|
||||
RsGxsMessageId mParentId;
|
||||
RsGxsCircleId mCircleId ;
|
||||
RsGxsMessageId mParentId;
|
||||
RsGxsMessageId mOrigMsgId;
|
||||
RsGxsId mPosterId;
|
||||
|
||||
bool mParentMsgLoaded;
|
||||
bool mOrigMsgLoaded;
|
||||
bool mForumMetaLoaded;
|
||||
bool mForumCircleLoaded ;
|
||||
bool mForumCircleLoaded ;
|
||||
|
||||
RsGxsForumMsg mParentMsg;
|
||||
RsGxsForumMsg mOrigMsg;
|
||||
RsGroupMetaData mForumMeta;
|
||||
RsGxsCircleGroup mForumCircleData ;
|
||||
RsGxsCircleGroup mForumCircleData ;
|
||||
|
||||
TokenQueue *mForumQueue;
|
||||
TokenQueue *mCirclesQueue;
|
||||
|
@ -160,6 +160,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
||||
mTokenTypeNegativeAuthor = nextTokenType();
|
||||
mTokenTypeNeutralAuthor = nextTokenType();
|
||||
mTokenTypePositiveAuthor = nextTokenType();
|
||||
mTokenTypeEditForumMessage = nextTokenType();
|
||||
|
||||
setUpdateWhenInvisible(true);
|
||||
|
||||
@ -199,6 +200,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
||||
|
||||
ui->threadTreeWidget->setItemDelegateForColumn(COLUMN_THREAD_DISTRIBUTION,new DistributionItemDelegate()) ;
|
||||
|
||||
connect(ui->versions_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(changedVersion()));
|
||||
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
||||
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
||||
|
||||
@ -483,11 +485,14 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
|
||||
QMenu contextMnu(this);
|
||||
|
||||
QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Edit"), &contextMnu);
|
||||
connect(editAct, SIGNAL(triggered()), this, SLOT(editforummessage()));
|
||||
|
||||
QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu);
|
||||
connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage()));
|
||||
|
||||
QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply to author with private message"), &contextMnu);
|
||||
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage()));
|
||||
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(reply_with_private_message()));
|
||||
|
||||
QAction *flagaspositiveAct = new QAction(QIcon(IMAGE_POSITIVE_OPINION), tr("Give positive opinion"), &contextMnu);
|
||||
flagaspositiveAct->setToolTip(tr("This will block/hide messages from this person, and notify friend nodes.")) ;
|
||||
@ -572,6 +577,18 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
replyauthorAct->setDisabled (true);
|
||||
}
|
||||
|
||||
QList<QTreeWidgetItem*> selectedItems = ui->threadTreeWidget->selectedItems();
|
||||
|
||||
if(selectedItems.size() == 1)
|
||||
{
|
||||
QTreeWidgetItem *item = *selectedItems.begin();
|
||||
GxsIdRSTreeWidgetItem *gxsIdItem = dynamic_cast<GxsIdRSTreeWidgetItem*>(item);
|
||||
|
||||
RsGxsId author_id;
|
||||
if(gxsIdItem && gxsIdItem->getId(author_id) && rsIdentity->isOwnId(author_id))
|
||||
contextMnu.addAction(editAct);
|
||||
}
|
||||
|
||||
contextMnu.addAction(replyAct);
|
||||
contextMnu.addAction(newthreadAct);
|
||||
QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()));
|
||||
@ -585,8 +602,6 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
contextMnu.addAction(expandAll);
|
||||
contextMnu.addAction(collapseAll);
|
||||
|
||||
QList<QTreeWidgetItem*> selectedItems = ui->threadTreeWidget->selectedItems();
|
||||
|
||||
if(selectedItems.size() == 1)
|
||||
{
|
||||
QTreeWidgetItem *item = *selectedItems.begin();
|
||||
@ -680,6 +695,17 @@ void GxsForumThreadWidget::togglethreadview_internal()
|
||||
}
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::changedVersion()
|
||||
{
|
||||
mThreadId = RsGxsMessageId(ui->versions_CB->itemData(ui->versions_CB->currentIndex()).toString().toStdString()) ;
|
||||
|
||||
if (mFillThread) {
|
||||
return;
|
||||
}
|
||||
ui->postText->resetImagesStatus(Settings->getForumLoadEmbeddedImages()) ;
|
||||
insertMessage();
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::changedThread()
|
||||
{
|
||||
/* just grab the ids of the current item */
|
||||
@ -687,8 +713,10 @@ void GxsForumThreadWidget::changedThread()
|
||||
|
||||
if (!item || !item->isSelected()) {
|
||||
mThreadId.clear();
|
||||
mOrigThreadId.clear();
|
||||
} else {
|
||||
mThreadId = RsGxsMessageId(item->data(COLUMN_THREAD_MSGID, Qt::DisplayRole).toString().toStdString());
|
||||
|
||||
mThreadId = mOrigThreadId = RsGxsMessageId(item->data(COLUMN_THREAD_MSGID, Qt::DisplayRole).toString().toStdString());
|
||||
}
|
||||
|
||||
if (mFillThread) {
|
||||
@ -1014,10 +1042,12 @@ void GxsForumThreadWidget::fillThreadFinished()
|
||||
mLastViewType = thread->mViewType;
|
||||
mLastForumID = groupId();
|
||||
ui->threadTreeWidget->insertTopLevelItems(0, thread->mItems);
|
||||
mPostVersions = thread->mPostVersions;
|
||||
|
||||
// clear list
|
||||
thread->mItems.clear();
|
||||
} else {
|
||||
mPostVersions = thread->mPostVersions;
|
||||
fillThreads(thread->mItems, thread->mExpandNewMessages, thread->mItemToExpand);
|
||||
|
||||
// cleanup list
|
||||
@ -1507,6 +1537,9 @@ void GxsForumThreadWidget::insertMessage()
|
||||
mStateHelper->setActive(mTokenTypeMessageData, false);
|
||||
mStateHelper->clear(mTokenTypeMessageData);
|
||||
|
||||
ui->versions_CB->hide();
|
||||
ui->time_label->show();
|
||||
|
||||
ui->postText->clear();
|
||||
//ui->threadTitle->clear();
|
||||
return;
|
||||
@ -1517,6 +1550,9 @@ void GxsForumThreadWidget::insertMessage()
|
||||
mStateHelper->setActive(mTokenTypeMessageData, false);
|
||||
mStateHelper->clear(mTokenTypeMessageData);
|
||||
|
||||
ui->versions_CB->hide();
|
||||
ui->time_label->show();
|
||||
|
||||
//ui->threadTitle->setText(tr("Forum Description"));
|
||||
ui->postText->setText(mForumDescription);
|
||||
return;
|
||||
@ -1535,6 +1571,8 @@ void GxsForumThreadWidget::insertMessage()
|
||||
// there is something wrong
|
||||
mStateHelper->setWidgetEnabled(ui->previousButton, false);
|
||||
mStateHelper->setWidgetEnabled(ui->nextButton, false);
|
||||
ui->versions_CB->hide();
|
||||
ui->time_label->show();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1549,6 +1587,47 @@ void GxsForumThreadWidget::insertMessage()
|
||||
ui->by_text_label->hide();
|
||||
ui->by_label->hide();
|
||||
|
||||
// add/show combobox for versions, if applicable, and enable it. If no older versions of the post available, hide the combobox.
|
||||
|
||||
std::cerr << "Looking into existing versions for post " << mThreadId << ", thread history: " << mPostVersions.size() << std::endl;
|
||||
|
||||
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::const_iterator it = mPostVersions.find(mOrigThreadId) ;
|
||||
|
||||
ui->versions_CB->blockSignals(true) ;
|
||||
|
||||
while(ui->versions_CB->count() > 0)
|
||||
ui->versions_CB->removeItem(0);
|
||||
|
||||
if(it != mPostVersions.end())
|
||||
{
|
||||
std::cerr << (*it).size() << " versions found " << std::endl;
|
||||
|
||||
ui->versions_CB->setVisible(true) ;
|
||||
ui->time_label->hide();
|
||||
|
||||
int current_index = 0 ;
|
||||
|
||||
for(int i=0;i<(*it).size();++i)
|
||||
{
|
||||
ui->versions_CB->insertItem(i, ((i==0)?tr("(Latest) "):tr("(Old) "))+" "+DateTime::formatLongDateTime( (*it)[i].first));
|
||||
ui->versions_CB->setItemData(i,QString::fromStdString((*it)[i].second.toStdString()));
|
||||
|
||||
std::cerr << " added new post version " << (*it)[i].first << " " << (*it)[i].second << std::endl;
|
||||
|
||||
if(mThreadId == (*it)[i].second)
|
||||
current_index = i ;
|
||||
}
|
||||
|
||||
ui->versions_CB->setCurrentIndex(current_index) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->versions_CB->hide();
|
||||
ui->time_label->show();
|
||||
}
|
||||
|
||||
ui->versions_CB->blockSignals(false) ;
|
||||
|
||||
/* request Post */
|
||||
RsGxsGrpMsgIdPair msgId = std::make_pair(groupId(), mThreadId);
|
||||
requestMessageData(msgId);
|
||||
@ -1951,7 +2030,7 @@ void GxsForumThreadWidget::createmessage()
|
||||
return;
|
||||
}
|
||||
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId);
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId,RsGxsMessageId());
|
||||
cfm->show();
|
||||
|
||||
/* window will destroy itself! */
|
||||
@ -1964,7 +2043,7 @@ void GxsForumThreadWidget::createthread()
|
||||
return;
|
||||
}
|
||||
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), RsGxsMessageId());
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), RsGxsMessageId(),RsGxsMessageId());
|
||||
cfm->show();
|
||||
|
||||
/* window will destroy itself! */
|
||||
@ -2018,7 +2097,7 @@ void GxsForumThreadWidget::flagperson()
|
||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, token_type);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::replytomessage()
|
||||
void GxsForumThreadWidget::reply_with_private_message()
|
||||
{
|
||||
if (groupId().isNull() || mThreadId.isNull()) {
|
||||
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
||||
@ -2027,9 +2106,19 @@ void GxsForumThreadWidget::replytomessage()
|
||||
|
||||
// Get Message ... then complete replyMessageData().
|
||||
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||
requestMsgData_ReplyMessage(postId);
|
||||
requestMsgData_ReplyWithPrivateMessage(postId);
|
||||
}
|
||||
void GxsForumThreadWidget::editforummessage()
|
||||
{
|
||||
if (groupId().isNull() || mThreadId.isNull()) {
|
||||
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Message ... then complete replyMessageData().
|
||||
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||
requestMsgData_EditForumMessage(postId);
|
||||
}
|
||||
void GxsForumThreadWidget::replytoforummessage()
|
||||
{
|
||||
if (groupId().isNull() || mThreadId.isNull()) {
|
||||
@ -2082,6 +2171,29 @@ void GxsForumThreadWidget::showAuthorInPeople(const RsGxsForumMsg& msg)
|
||||
requestMsgData_ShowAuthorInPeople(postId);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::editForumMessageData(const RsGxsForumMsg& msg)
|
||||
{
|
||||
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
||||
{
|
||||
std::cerr << "GxsForumThreadWidget::replyMessageData() ERROR Message Ids have changed!";
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!msg.mMeta.mAuthorId.isNull())
|
||||
{
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), msg.mMeta.mParentId, msg.mMeta.mMsgId, msg.mMeta.mAuthorId);
|
||||
|
||||
cfm->insertPastedText(QString::fromUtf8(msg.mMsg.c_str())) ;
|
||||
cfm->show();
|
||||
|
||||
/* window will destroy itself! */
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author"));
|
||||
}
|
||||
}
|
||||
void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
||||
{
|
||||
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
||||
@ -2093,10 +2205,12 @@ void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
||||
|
||||
if (!msg.mMeta.mAuthorId.isNull())
|
||||
{
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId);
|
||||
QTextDocument doc ;
|
||||
CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId,RsGxsMessageId());
|
||||
|
||||
// QTextDocument doc ;
|
||||
// doc.setHtml(QString::fromUtf8(msg.mMsg.c_str()) );
|
||||
// std::string cited_text(doc.toPlainText().toStdString()) ;
|
||||
|
||||
RsHtml::makeQuotedText(ui->postText);
|
||||
|
||||
cfm->insertPastedText(RsHtml::makeQuotedText(ui->postText)) ;
|
||||
@ -2317,7 +2431,8 @@ void GxsForumThreadWidget::loadMessageData(const uint32_t &token)
|
||||
/*********************** **** **** **** ***********************/
|
||||
/*********************** **** **** **** ***********************/
|
||||
|
||||
void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||
|
||||
void GxsForumThreadWidget::requestMsgData_ReplyWithPrivateMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||
{
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
@ -2352,7 +2467,23 @@ void GxsForumThreadWidget::requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgId
|
||||
uint32_t token;
|
||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeShowAuthorInPeople);
|
||||
}
|
||||
void GxsForumThreadWidget::requestMsgData_EditForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||
{
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "GxsForumThreadWidget::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
GxsMsgReq msgIds;
|
||||
std::vector<RsGxsMessageId> &vect = msgIds[msgId.first];
|
||||
vect.push_back(msgId.second);
|
||||
|
||||
uint32_t token;
|
||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeEditForumMessage);
|
||||
}
|
||||
void GxsForumThreadWidget::requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||
{
|
||||
RsTokReqOptions opts;
|
||||
@ -2396,6 +2527,31 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token)
|
||||
}
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::loadMsgData_EditForumMessage(const uint32_t &token)
|
||||
{
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "GxsForumThreadWidget::loadMsgData_EditMessage()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<RsGxsForumMsg> msgs;
|
||||
if (rsGxsForums->getMsgData(token, msgs))
|
||||
{
|
||||
if (msgs.size() != 1)
|
||||
{
|
||||
std::cerr << "GxsForumThreadWidget::loadMsgData_EditMessage() ERROR Wrong number of answers";
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
editForumMessageData(msgs[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Missing Message Data...";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
void GxsForumThreadWidget::loadMsgData_ReplyForumMessage(const uint32_t &token)
|
||||
{
|
||||
#ifdef DEBUG_FORUMS
|
||||
@ -2523,6 +2679,10 @@ void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenReque
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.mUserType == mTokenTypeEditForumMessage) {
|
||||
loadMsgData_EditForumMessage(req.mToken);
|
||||
return;
|
||||
}
|
||||
if (req.mUserType == mTokenTypeShowAuthorInPeople) {
|
||||
loadMsgData_ShowAuthorInPeople(req.mToken);
|
||||
return;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef GXSFORUMTHREADWIDGET_H
|
||||
#define GXSFORUMTHREADWIDGET_H
|
||||
|
||||
#include <QMap>
|
||||
|
||||
#include "gui/gxs/GxsMessageFrameWidget.h"
|
||||
#include <retroshare/rsgxsforums.h>
|
||||
#include "gui/gxs/GxsIdDetails.h"
|
||||
@ -73,12 +75,15 @@ private slots:
|
||||
void contextMenuTextBrowser(QPoint point);
|
||||
|
||||
void changedThread();
|
||||
void changedVersion();
|
||||
void clickedThread (QTreeWidgetItem *item, int column);
|
||||
|
||||
void replytomessage();
|
||||
void reply_with_private_message();
|
||||
void replytoforummessage();
|
||||
void editforummessage();
|
||||
|
||||
void replyMessageData(const RsGxsForumMsg &msg);
|
||||
void editForumMessageData(const RsGxsForumMsg &msg);
|
||||
void replyForumMessageData(const RsGxsForumMsg &msg);
|
||||
void showAuthorInPeople(const RsGxsForumMsg& msg);
|
||||
|
||||
@ -147,19 +152,22 @@ private:
|
||||
static void loadAuthorIdCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/);
|
||||
|
||||
void requestMessageData(const RsGxsGrpMsgIdPair &msgId);
|
||||
void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||
void requestMsgData_ReplyWithPrivateMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||
void requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgIdPair &msgId);
|
||||
void requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||
void requestMsgData_EditForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||
|
||||
void loadMessageData(const uint32_t &token);
|
||||
void loadMsgData_ReplyMessage(const uint32_t &token);
|
||||
void loadMsgData_ReplyForumMessage(const uint32_t &token);
|
||||
void loadMsgData_EditForumMessage(const uint32_t &token);
|
||||
void loadMsgData_ShowAuthorInPeople(const uint32_t &token);
|
||||
void loadMsgData_SetAuthorOpinion(const uint32_t &token, RsReputations::Opinion opinion);
|
||||
|
||||
private:
|
||||
RsGxsGroupId mLastForumID;
|
||||
RsGxsMessageId mThreadId;
|
||||
RsGxsMessageId mOrigThreadId;
|
||||
RsGxsForumGroup mForumGroup;
|
||||
QString mForumDescription;
|
||||
int mSubscribeFlags;
|
||||
@ -177,6 +185,7 @@ private:
|
||||
uint32_t mTokenTypeMessageData;
|
||||
uint32_t mTokenTypeReplyMessage;
|
||||
uint32_t mTokenTypeReplyForumMessage;
|
||||
uint32_t mTokenTypeEditForumMessage;
|
||||
uint32_t mTokenTypeShowAuthorInPeople;
|
||||
uint32_t mTokenTypeNegativeAuthor;
|
||||
uint32_t mTokenTypePositiveAuthor;
|
||||
@ -192,6 +201,8 @@ private:
|
||||
RsGxsMessageId mNavigatePendingMsgId;
|
||||
QList<RsGxsMessageId> mIgnoredMsgId;
|
||||
|
||||
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mPostVersions ; // holds older versions of posts
|
||||
|
||||
Ui::GxsForumThreadWidget *ui;
|
||||
};
|
||||
|
||||
|
@ -289,14 +289,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="time_label">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="12">
|
||||
<item row="0" column="13">
|
||||
<widget class="QPushButton" name="nextUnreadButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
@ -332,7 +325,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="14">
|
||||
<item row="0" column="15">
|
||||
<widget class="QPushButton" name="expandButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -372,7 +365,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="11">
|
||||
<item row="0" column="12">
|
||||
<spacer name="postHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -464,20 +457,30 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="10">
|
||||
<item row="0" column="11">
|
||||
<widget class="GxsIdLabel" name="by_label">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<item row="0" column="10">
|
||||
<widget class="QLabel" name="by_text_label">
|
||||
<property name="text">
|
||||
<string>By </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<widget class="QComboBox" name="versions_CB"/>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="time_label">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@ -562,8 +565,8 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
<include location="../icons.qrc"/>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -89,6 +89,8 @@ void GxsForumsFillThread::calculateExpand(const RsGxsForumMsg &msg, QTreeWidgetI
|
||||
}
|
||||
}
|
||||
|
||||
static bool decreasing_time_comp(const QPair<time_t,RsGxsMessageId>& e1,const QPair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }
|
||||
|
||||
void GxsForumsFillThread::run()
|
||||
{
|
||||
RsTokenService *service = rsGxsForums->getTokenService();
|
||||
@ -171,7 +173,7 @@ void GxsForumsFillThread::run()
|
||||
int pos = 0;
|
||||
int steps = count / PROGRESSBAR_MAX;
|
||||
int step = 0;
|
||||
|
||||
|
||||
// ThreadList contains the list of parent threads. The algorithm below iterates through all messages
|
||||
// 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
|
||||
@ -185,6 +187,99 @@ void GxsForumsFillThread::run()
|
||||
std::map<RsGxsMessageId,std::list<RsGxsMessageId> > kids_array ;
|
||||
std::set<RsGxsMessageId> missing_parents;
|
||||
|
||||
// First of all, remove all older versions of posts. This is done by first adding all posts into a hierarchy structure
|
||||
// and then removing all posts which have a new versions available. The older versions are kept appart.
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "GxsForumsFillThread::run() Collecting post versions" << std::endl;
|
||||
#endif
|
||||
mPostVersions.clear();
|
||||
std::list<RsGxsMessageId> msg_stack ;
|
||||
|
||||
for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
|
||||
if(!msgIt->second.mMeta.mOrigMsgId.isNull() && msgIt->second.mMeta.mOrigMsgId != msgIt->second.mMeta.mMsgId)
|
||||
{
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << " Post " << msgIt->second.mMeta.mMsgId << " is a new version of " << msgIt->second.mMeta.mOrigMsgId << std::endl;
|
||||
#endif
|
||||
std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt2 = msgs.find(msgIt->second.mMeta.mOrigMsgId);
|
||||
|
||||
// Ensuring that the post exists allows to only collect the existing data.
|
||||
|
||||
if(msgIt2 == msgs.end())
|
||||
continue ;
|
||||
|
||||
// Make sure that the author is the same than the original message. This should always happen, but nothing can prevent someone to
|
||||
// craft a new version of a message with his own signature.
|
||||
|
||||
if(msgIt2->second.mMeta.mAuthorId != msgIt->second.mMeta.mAuthorId)
|
||||
continue ;
|
||||
|
||||
// always add the post a self version
|
||||
|
||||
if(mPostVersions[msgIt->second.mMeta.mOrigMsgId].empty())
|
||||
mPostVersions[msgIt->second.mMeta.mOrigMsgId].push_back(QPair<time_t,RsGxsMessageId>(msgIt2->second.mMeta.mPublishTs,msgIt2->second.mMeta.mMsgId)) ;
|
||||
|
||||
mPostVersions[msgIt->second.mMeta.mOrigMsgId].push_back(QPair<time_t,RsGxsMessageId>(msgIt->second.mMeta.mPublishTs,msgIt->second.mMeta.mMsgId)) ;
|
||||
}
|
||||
|
||||
// The following code assembles all new versions of a given post into the same array, indexed by the oldest version of the post.
|
||||
|
||||
for(QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::iterator it(mPostVersions.begin());it!=mPostVersions.end();++it)
|
||||
{
|
||||
QVector<QPair<time_t,RsGxsMessageId> >& v(*it) ;
|
||||
|
||||
for(int32_t i=0;i<v.size();++i)
|
||||
if(v[i].second != it.key())
|
||||
{
|
||||
RsGxsMessageId sub_msg_id = v[i].second ;
|
||||
|
||||
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::iterator it2 = mPostVersions.find(sub_msg_id);
|
||||
|
||||
if(it2 != mPostVersions.end())
|
||||
{
|
||||
for(int32_t j=0;j<(*it2).size();++j)
|
||||
if((*it2)[j].second != sub_msg_id) // dont copy it, since it is already present at slot i
|
||||
v.append((*it2)[j]) ;
|
||||
|
||||
mPostVersions.erase(it2) ; // it2 is never equal to it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now remove from msg ids, all posts except the most recent one. And make the mPostVersion be indexed by the most recent version of the post,
|
||||
// which corresponds to the item in the tree widget.
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "Final post versions: " << std::endl;
|
||||
#endif
|
||||
QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > > mTmp;
|
||||
|
||||
for(QMap<RsGxsMessageId,QVector<QPair<time_t,RsGxsMessageId> > >::iterator it(mPostVersions.begin());it!=mPostVersions.end();++it)
|
||||
{
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "Original post: " << it.key() << std::endl;
|
||||
#endif
|
||||
// Finally, sort the posts from newer to older
|
||||
|
||||
qSort((*it).begin(),(*it).end(),decreasing_time_comp) ;
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << " most recent version " << (*it)[0].first << " " << (*it)[0].second << std::endl;
|
||||
#endif
|
||||
for(int32_t i=1;i<(*it).size();++i)
|
||||
{
|
||||
msgs.erase((*it)[i].second) ;
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << " older version " << (*it)[i].first << " " << (*it)[i].second << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
mTmp[(*it)[0].second] = *it ; // index the versions map by the ID of the most recent post.
|
||||
}
|
||||
mPostVersions = mTmp ;
|
||||
|
||||
// The first step is to find the top level thread messages. These are defined as the messages without
|
||||
// any parent message ID.
|
||||
|
||||
@ -194,6 +289,8 @@ void GxsForumsFillThread::run()
|
||||
std::map<RsGxsMessageId,RsGxsForumMsg> kept_msgs;
|
||||
|
||||
for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
|
||||
{
|
||||
|
||||
if(mFlatView || msgIt->second.mMeta.mParentId.isNull())
|
||||
{
|
||||
|
||||
@ -234,9 +331,12 @@ void GxsForumsFillThread::run()
|
||||
kids_array[msgIt->second.mMeta.mParentId].push_back(msgIt->first) ;
|
||||
kept_msgs.insert(*msgIt) ;
|
||||
}
|
||||
}
|
||||
|
||||
msgs = kept_msgs;
|
||||
|
||||
// Also create a list of posts by time, when they are new versions of existing posts. Only the last one will have an item created.
|
||||
|
||||
// Add a fake toplevel item for the parent IDs that we dont actually have.
|
||||
|
||||
for(std::set<RsGxsMessageId>::const_iterator it(missing_parents.begin());it!=missing_parents.end();++it)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user