mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merge pull request #48 from hunbernd/New-Posted-Card-View
New posted card view
This commit is contained in:
commit
d79db171cc
@ -111,6 +111,7 @@ p3discovery2::p3discovery2(
|
|||||||
|
|
||||||
if(rsEvents)
|
if(rsEvents)
|
||||||
rsEvents->registerEventsHandler(
|
rsEvents->registerEventsHandler(
|
||||||
|
RsEventType::GOSSIP_DISCOVERY,
|
||||||
[this](std::shared_ptr<const RsEvent> event)
|
[this](std::shared_ptr<const RsEvent> event)
|
||||||
{
|
{
|
||||||
rsEventsHandler(*event);
|
rsEventsHandler(*event);
|
||||||
@ -1345,8 +1346,3 @@ void p3discovery2::rsEventsHandler(const RsEvent& event)
|
|||||||
//
|
//
|
||||||
// /* ignore other operations */
|
// /* ignore other operations */
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// (cyril) do we still need this??
|
|
||||||
RsGossipDiscoveryFriendInviteReceivedEvent::RsGossipDiscoveryFriendInviteReceivedEvent(const std::string& invite) :
|
|
||||||
RsEvent(RsEventType::GOSSIP_DISCOVERY_INVITE_RECEIVED),
|
|
||||||
mInvite(invite) {}
|
|
||||||
|
@ -108,7 +108,7 @@ void RsGRouterGenericDataItem::serial_process(RsGenericSerializer::SerializeJob
|
|||||||
|
|
||||||
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,signature,"signature") ;
|
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,signature,"signature") ;
|
||||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,duplication_factor,"duplication_factor") ;
|
RsTypeSerializer::serial_process<uint32_t>(j,ctx,duplication_factor,"duplication_factor") ;
|
||||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,flags,"flags") ;
|
RS_SERIAL_PROCESS(flags);
|
||||||
|
|
||||||
if(j == RsGenericSerializer::DESERIALIZE) // make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more.
|
if(j == RsGenericSerializer::DESERIALIZE) // make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more.
|
||||||
{
|
{
|
||||||
@ -128,7 +128,7 @@ void RsGRouterGenericDataItem::serial_process(RsGenericSerializer::SerializeJob
|
|||||||
void RsGRouterSignedReceiptItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
void RsGRouterSignedReceiptItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
{
|
{
|
||||||
RsTypeSerializer::serial_process<uint64_t> (j,ctx,routing_id,"routing_id") ;
|
RsTypeSerializer::serial_process<uint64_t> (j,ctx,routing_id,"routing_id") ;
|
||||||
RsTypeSerializer::serial_process<uint32_t> (j,ctx,flags,"flags") ;
|
RS_SERIAL_PROCESS(flags);
|
||||||
RsTypeSerializer::serial_process (j,ctx,destination_key,"destination_key") ;
|
RsTypeSerializer::serial_process (j,ctx,destination_key,"destination_key") ;
|
||||||
RsTypeSerializer::serial_process<uint32_t> (j,ctx,service_id,"service_id") ;
|
RsTypeSerializer::serial_process<uint32_t> (j,ctx,service_id,"service_id") ;
|
||||||
RsTypeSerializer::serial_process (j,ctx,data_hash,"data_hash") ;
|
RsTypeSerializer::serial_process (j,ctx,data_hash,"data_hash") ;
|
||||||
@ -269,3 +269,4 @@ RsGRouterSignedReceiptItem *RsGRouterSignedReceiptItem::duplicate() const
|
|||||||
return item ;
|
return item ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RsGRouterAbstractMsgItem::~RsGRouterAbstractMsgItem() = default;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "serialiser/rstlvkeys.h"
|
#include "serialiser/rstlvkeys.h"
|
||||||
#include "rsitems/rsserviceids.h"
|
#include "rsitems/rsserviceids.h"
|
||||||
#include "retroshare/rstypes.h"
|
#include "retroshare/rstypes.h"
|
||||||
|
#include "retroshare/rsflags.h"
|
||||||
#include "retroshare/rsgrouter.h"
|
#include "retroshare/rsgrouter.h"
|
||||||
#include "groutermatrix.h"
|
#include "groutermatrix.h"
|
||||||
|
|
||||||
@ -83,40 +83,59 @@ class RsGRouterNonCopyableObject
|
|||||||
// and routing ID. Sub-items are responsible for providing the serialised data to be signed for
|
// and routing ID. Sub-items are responsible for providing the serialised data to be signed for
|
||||||
// both signing and checking.
|
// both signing and checking.
|
||||||
|
|
||||||
class RsGRouterAbstractMsgItem: public RsGRouterItem
|
enum class RsGRouterItemFlags : uint32_t
|
||||||
{
|
{
|
||||||
public:
|
NONE = 0x0,
|
||||||
explicit RsGRouterAbstractMsgItem(uint8_t pkt_subtype) : RsGRouterItem(pkt_subtype), flags(0) {}
|
ENCRYPTED = 0x1,
|
||||||
virtual ~RsGRouterAbstractMsgItem() {}
|
SERVICE_UNKNOWN = 0x2
|
||||||
|
};
|
||||||
|
RS_REGISTER_ENUM_FLAGS_TYPE(RsGRouterItemFlags)
|
||||||
|
|
||||||
|
struct RsGRouterAbstractMsgItem: RsGRouterItem
|
||||||
|
{
|
||||||
|
explicit RsGRouterAbstractMsgItem(uint8_t pkt_subtype):
|
||||||
|
RsGRouterItem(pkt_subtype), flags(RsGRouterItemFlags::NONE) {}
|
||||||
|
|
||||||
GRouterMsgPropagationId routing_id ;
|
GRouterMsgPropagationId routing_id ;
|
||||||
GRouterKeyId destination_key ;
|
GRouterKeyId destination_key ;
|
||||||
GRouterServiceId service_id ;
|
GRouterServiceId service_id ;
|
||||||
RsTlvKeySignature signature ; // signs mid+destination_key+state
|
RsTlvKeySignature signature ; // signs mid+destination_key+state
|
||||||
uint32_t flags ; // packet was delivered, not delivered, bounced, etc
|
|
||||||
|
/// packet was delivered, not delivered, bounced, etc
|
||||||
|
RsGRouterItemFlags flags;
|
||||||
|
|
||||||
|
~RsGRouterAbstractMsgItem();
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGRouterGenericDataItem: public RsGRouterAbstractMsgItem, public RsGRouterNonCopyableObject
|
class RsGRouterGenericDataItem:
|
||||||
|
public RsGRouterAbstractMsgItem, public RsGRouterNonCopyableObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGRouterGenericDataItem() : RsGRouterAbstractMsgItem(RS_PKT_SUBTYPE_GROUTER_DATA), data_size(0), data_bytes(NULL), duplication_factor(0) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER) ; }
|
RsGRouterGenericDataItem():
|
||||||
virtual ~RsGRouterGenericDataItem() { clear() ; }
|
RsGRouterAbstractMsgItem(RS_PKT_SUBTYPE_GROUTER_DATA),
|
||||||
|
data_size(0), data_bytes(nullptr), duplication_factor(0)
|
||||||
|
{ setPriorityLevel(QOS_PRIORITY_RS_GROUTER); }
|
||||||
|
|
||||||
|
virtual ~RsGRouterGenericDataItem() { clear(); }
|
||||||
virtual void clear()
|
virtual void clear()
|
||||||
{
|
{
|
||||||
free(data_bytes);
|
free(data_bytes);
|
||||||
data_bytes=NULL;
|
data_bytes = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
virtual void serial_process(
|
||||||
|
RsGenericSerializer::SerializeJob j,
|
||||||
|
RsGenericSerializer::SerializeContext& ctx );
|
||||||
|
|
||||||
RsGRouterGenericDataItem *duplicate() const;
|
RsGRouterGenericDataItem *duplicate() const;
|
||||||
|
|
||||||
// packet data
|
/// packet data
|
||||||
//
|
|
||||||
uint32_t data_size;
|
uint32_t data_size;
|
||||||
uint8_t* data_bytes;
|
uint8_t* data_bytes;
|
||||||
uint32_t duplication_factor ; // number of duplicates allowed. Should be capped at each de-serialise operation!
|
|
||||||
|
/** number of duplicates allowed. Should be capped at each de-serialise
|
||||||
|
* operation! */
|
||||||
|
uint32_t duplication_factor;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem
|
class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem
|
||||||
|
@ -178,7 +178,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
|
|
||||||
#include "util/rsrandom.h"
|
#include "util/rsrandom.h"
|
||||||
#include "util/rsprint.h"
|
#include "util/rsprint.h"
|
||||||
@ -188,7 +188,7 @@
|
|||||||
#include "turtle/p3turtle.h"
|
#include "turtle/p3turtle.h"
|
||||||
#include "gxs/rsgixs.h"
|
#include "gxs/rsgixs.h"
|
||||||
#include "retroshare/rspeers.h"
|
#include "retroshare/rspeers.h"
|
||||||
|
#include "util/cxx17retrocompat.h"
|
||||||
#include "p3grouter.h"
|
#include "p3grouter.h"
|
||||||
#include "grouteritems.h"
|
#include "grouteritems.h"
|
||||||
#include "groutertypes.h"
|
#include "groutertypes.h"
|
||||||
@ -200,25 +200,18 @@
|
|||||||
|
|
||||||
const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ;
|
const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ;
|
||||||
|
|
||||||
p3GRouter::p3GRouter(p3ServiceControl *sc, RsGixs *is)
|
p3GRouter::p3GRouter(p3ServiceControl *sc, RsGixs *is) :
|
||||||
: p3Service(), p3Config(), mServiceControl(sc), mTurtle(NULL), mGixs(is), grMtx("GRouter")
|
p3Service(), p3Config(), mServiceControl(sc), mTurtle(nullptr), mGixs(is),
|
||||||
{
|
grMtx("GRouter"), _changed(false), _debug_enabled(true),
|
||||||
addSerialType(new RsGRouterSerialiser()) ;
|
_last_autowash_time(0), _last_matrix_update_time(0),
|
||||||
|
_last_debug_output_time(0), _last_config_changed(0),
|
||||||
_last_autowash_time = 0 ;
|
_random_salt(RsRandom::random_u64()),
|
||||||
_last_debug_output_time = 0 ;
|
mMissingKeyQueueMtx("GRouterMissingKeyQueue")
|
||||||
_last_config_changed = 0 ;
|
{ addSerialType(new RsGRouterSerialiser()); }
|
||||||
_last_matrix_update_time = 0 ;
|
|
||||||
_debug_enabled = true ;
|
|
||||||
|
|
||||||
_random_salt = RSRandom::random_u64() ;
|
|
||||||
|
|
||||||
_changed = false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int p3GRouter::tick()
|
int p3GRouter::tick()
|
||||||
{
|
{
|
||||||
rstime_t now = time(NULL) ;
|
rstime_t now = time(nullptr);
|
||||||
|
|
||||||
// Sort incoming service data
|
// Sort incoming service data
|
||||||
//
|
//
|
||||||
@ -242,6 +235,41 @@ int p3GRouter::tick()
|
|||||||
//
|
//
|
||||||
handleTunnels() ;
|
handleTunnels() ;
|
||||||
|
|
||||||
|
/* Handle items in mMissingKeyQueue */
|
||||||
|
if(now > mMissingKeyQueueCheckLastCheck + mMissingKeyQueueCheckEvery)
|
||||||
|
{
|
||||||
|
mMissingKeyQueueCheckLastCheck = now;
|
||||||
|
|
||||||
|
RS_STACK_MUTEX(mMissingKeyQueueMtx);
|
||||||
|
for(auto it = mMissingKeyQueue.begin(); it != mMissingKeyQueue.end();)
|
||||||
|
{
|
||||||
|
const RsGxsId& senderId = it->first->signature.keyId;
|
||||||
|
if(rsIdentity->isKnownId(senderId))
|
||||||
|
{
|
||||||
|
Dbg2() << __PRETTY_FUNCTION__ << " got key: " << senderId
|
||||||
|
<< " for item pending validation, calling item handler"
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
handleIncomingItem(it->first.get());
|
||||||
|
it = mMissingKeyQueue.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dbg3() << __PRETTY_FUNCTION__ << " requesting missing key: "
|
||||||
|
<< senderId << " to validate pending item" << std::endl;
|
||||||
|
|
||||||
|
/* At this point the network status may have varied a lot since
|
||||||
|
* we received the item, so we don't even know if the peer who
|
||||||
|
* forwarded the item is still online, moreover the fact that
|
||||||
|
* after specific request we haven't got the key yet suggests it
|
||||||
|
* is not a good route toward the key, so request it to all
|
||||||
|
* available peers */
|
||||||
|
rsIdentity->requestIdentity(senderId);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update routing matrix
|
// Update routing matrix
|
||||||
//
|
//
|
||||||
if(now > _last_matrix_update_time + RS_GROUTER_MATRIX_UPDATE_PERIOD)
|
if(now > _last_matrix_update_time + RS_GROUTER_MATRIX_UPDATE_PERIOD)
|
||||||
@ -325,13 +353,11 @@ bool p3GRouter::unregisterKey(const RsGxsId& key_id,const GRouterServiceId& sid)
|
|||||||
|
|
||||||
Sha1CheckSum hash = makeTunnelHash(key_id,sid) ;
|
Sha1CheckSum hash = makeTunnelHash(key_id,sid) ;
|
||||||
|
|
||||||
std::map<Sha1CheckSum,GRouterPublishedKeyInfo>::iterator it = _owned_key_ids.find(hash) ;
|
const auto it = _owned_key_ids.find(hash);
|
||||||
|
|
||||||
if(it == _owned_key_ids.end())
|
if(it == _owned_key_ids.end())
|
||||||
{
|
{
|
||||||
#ifdef GROUTER_DEBUG
|
RsErr() << __PRETTY_FUNCTION__ << " key " << key_id << " not found."
|
||||||
std::cerr << "p3GRouter::unregisterKey(): key " << key_id << " not found." << std::endl;
|
<< std::endl;
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +505,7 @@ void p3GRouter::handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem *t
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GRouter::receiveTurtleData(const RsTurtleGenericTunnelItem *gitem, const RsFileHash &/*hash*/, const RsPeerId &virtual_peer_id, RsTurtleGenericTunnelItem::Direction /*direction*/)
|
void p3GRouter::receiveTurtleData(const RsTurtleGenericTunnelItem *gitem, const RsFileHash & hash, const RsPeerId &virtual_peer_id, RsTurtleGenericTunnelItem::Direction direction)
|
||||||
{
|
{
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << "p3GRouter::receiveTurtleData() " << std::endl;
|
std::cerr << "p3GRouter::receiveTurtleData() " << std::endl;
|
||||||
@ -1304,7 +1330,7 @@ bool p3GRouter::locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTr
|
|||||||
void p3GRouter::autoWash()
|
void p3GRouter::autoWash()
|
||||||
{
|
{
|
||||||
bool items_deleted = false ;
|
bool items_deleted = false ;
|
||||||
rstime_t now = time(NULL) ;
|
rstime_t now = time(nullptr);
|
||||||
|
|
||||||
std::map<GRouterMsgPropagationId,std::pair<GRouterClientService *,RsGxsId> > failed_msgs ;
|
std::map<GRouterMsgPropagationId,std::pair<GRouterClientService *,RsGxsId> > failed_msgs ;
|
||||||
|
|
||||||
@ -1398,6 +1424,19 @@ void p3GRouter::autoWash()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it ;
|
++it ;
|
||||||
|
|
||||||
|
/* Cleanup timed out items in mMissingKeyQueue */
|
||||||
|
mMissingKeyQueueMtx.lock();
|
||||||
|
while( mMissingKeyQueue.begin() != mMissingKeyQueue.end() &&
|
||||||
|
mMissingKeyQueue.front().second <= now )
|
||||||
|
{
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " Deleting timed out item from "
|
||||||
|
<< "unknown RsGxsId: "
|
||||||
|
<< mMissingKeyQueue.front().first->signature.keyId
|
||||||
|
<< std::endl;
|
||||||
|
mMissingKeyQueue.pop_front();
|
||||||
|
}
|
||||||
|
mMissingKeyQueueMtx.unlock();
|
||||||
}
|
}
|
||||||
// Look into pending items.
|
// Look into pending items.
|
||||||
|
|
||||||
@ -1492,27 +1531,31 @@ void p3GRouter::handleIncoming()
|
|||||||
RsGRouterAbstractMsgItem *item = _incoming_items.front() ;
|
RsGRouterAbstractMsgItem *item = _incoming_items.front() ;
|
||||||
_incoming_items.pop_front() ;
|
_incoming_items.pop_front() ;
|
||||||
|
|
||||||
RsGRouterGenericDataItem *generic_data_item ;
|
handleIncomingItem(item);
|
||||||
RsGRouterSignedReceiptItem *receipt_item ;
|
|
||||||
|
|
||||||
if(NULL != (generic_data_item = dynamic_cast<RsGRouterGenericDataItem*>(item)))
|
|
||||||
handleIncomingDataItem(generic_data_item) ;
|
|
||||||
else if(NULL != (receipt_item = dynamic_cast<RsGRouterSignedReceiptItem*>(item)))
|
|
||||||
handleIncomingReceiptItem(receipt_item) ;
|
|
||||||
else
|
|
||||||
std::cerr << "Item has unknown type (not data nor signed receipt). Dropping!" << std::endl;
|
|
||||||
|
|
||||||
delete item ;
|
delete item ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GRouter::handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_item)
|
void p3GRouter::handleIncomingItem(const RsGRouterAbstractMsgItem *item)
|
||||||
|
{
|
||||||
|
const RsGRouterGenericDataItem *generic_data_item ;
|
||||||
|
const RsGRouterSignedReceiptItem *receipt_item ;
|
||||||
|
|
||||||
|
if(NULL != (generic_data_item = dynamic_cast<const RsGRouterGenericDataItem*>(item)))
|
||||||
|
handleIncomingDataItem(generic_data_item) ;
|
||||||
|
else if(NULL != (receipt_item = dynamic_cast<const RsGRouterSignedReceiptItem*>(item)))
|
||||||
|
handleIncomingReceiptItem(receipt_item) ;
|
||||||
|
else
|
||||||
|
std::cerr << "Item has unknown type (not data nor signed receipt). Dropping!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void p3GRouter::handleIncomingReceiptItem(const RsGRouterSignedReceiptItem *receipt_item)
|
||||||
{
|
{
|
||||||
bool changed = false ;
|
bool changed = false ;
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << "Handling incoming signed receipt item." << std::endl;
|
std::cerr << "Handling incoming signed receipt item." << std::endl;
|
||||||
std::cerr << "Item content:" << std::endl;
|
std::cerr << "Item content:" << std::endl;
|
||||||
receipt_item->print(std::cerr,2) ;
|
const_cast<RsGRouterSignedReceiptItem*>(receipt_item)->print(std::cerr,2) ;
|
||||||
#endif
|
#endif
|
||||||
RsGxsId signer_id ;
|
RsGxsId signer_id ;
|
||||||
|
|
||||||
@ -1613,17 +1656,17 @@ void p3GRouter::handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_it
|
|||||||
IndicateConfigChanged() ;
|
IndicateConfigChanged() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sha1CheckSum p3GRouter::computeDataItemHash(RsGRouterGenericDataItem *data_item)
|
Sha1CheckSum p3GRouter::computeDataItemHash(const RsGRouterGenericDataItem *data_item)
|
||||||
{
|
{
|
||||||
RsGRouterSerialiser signature_serializer(RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER);
|
RsGRouterSerialiser signature_serializer(RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER);
|
||||||
|
|
||||||
uint32_t signed_data_size = signature_serializer.size(data_item);
|
uint32_t signed_data_size = signature_serializer.size(const_cast<RsGRouterGenericDataItem*>(data_item));
|
||||||
uint32_t total_size = signed_data_size + data_item->signature.TlvSize() ;
|
uint32_t total_size = signed_data_size + data_item->signature.TlvSize() ;
|
||||||
RsTemporaryMemory mem(total_size) ;
|
RsTemporaryMemory mem(total_size) ;
|
||||||
|
|
||||||
uint32_t offset = 0 ;
|
uint32_t offset = 0 ;
|
||||||
uint32_t tmp_size = total_size ;
|
uint32_t tmp_size = total_size ;
|
||||||
signature_serializer.serialise(data_item,mem,&tmp_size) ;
|
signature_serializer.serialise(const_cast<RsGRouterGenericDataItem*>(data_item),mem,&tmp_size) ;
|
||||||
if(tmp_size != signed_data_size)
|
if(tmp_size != signed_data_size)
|
||||||
std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl;
|
std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl;
|
||||||
|
|
||||||
@ -1637,12 +1680,12 @@ Sha1CheckSum p3GRouter::computeDataItemHash(RsGRouterGenericDataItem *data_item)
|
|||||||
return RsDirUtil::sha1sum(mem,total_size) ;
|
return RsDirUtil::sha1sum(mem,total_size) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
void p3GRouter::handleIncomingDataItem(const RsGRouterGenericDataItem *data_item)
|
||||||
{
|
{
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << "Handling incoming data item. " << std::endl;
|
std::cerr << "Handling incoming data item. " << std::endl;
|
||||||
std::cerr << "Item content:" << std::endl;
|
std::cerr << "Item content:" << std::endl;
|
||||||
data_item->print(std::cerr,2) ;
|
const_cast<RsGRouterGenericDataItem*>(data_item)->print(std::cerr,2) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// we find 3 things:
|
// we find 3 things:
|
||||||
@ -1654,15 +1697,15 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
// Send a receipt? if A && B
|
// Send a receipt? if A && B
|
||||||
// Notify client? if A && !C
|
// Notify client? if A && !C
|
||||||
//
|
//
|
||||||
GRouterClientService *client = NULL ;
|
GRouterClientService *clientService = NULL ;
|
||||||
GRouterServiceId service_id = data_item->service_id ;
|
GRouterServiceId service_id = data_item->service_id ;
|
||||||
RsGRouterSignedReceiptItem *receipt_item = NULL ;
|
RsGRouterSignedReceiptItem *receipt_item = NULL ;
|
||||||
|
|
||||||
Sha1CheckSum item_hash = computeDataItemHash(data_item) ;
|
Sha1CheckSum item_hash = computeDataItemHash(data_item) ;
|
||||||
|
|
||||||
bool item_is_already_known = false ;
|
bool item_is_already_known = false ;
|
||||||
bool item_is_for_us = false ;
|
|
||||||
bool cache_has_changed = false ;
|
bool cache_has_changed = false ;
|
||||||
|
bool item_is_for_us = _owned_key_ids.find( makeTunnelHash(data_item->destination_key,service_id) ) != _owned_key_ids.end() ;
|
||||||
|
|
||||||
// A - Find client and service ID from destination key.
|
// A - Find client and service ID from destination key.
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
@ -1671,23 +1714,12 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
{
|
{
|
||||||
RS_STACK_MUTEX(grMtx) ;
|
RS_STACK_MUTEX(grMtx) ;
|
||||||
|
|
||||||
std::map<GRouterServiceId,GRouterClientService*>::const_iterator its = _registered_services.find(service_id) ;
|
|
||||||
|
|
||||||
if(its == _registered_services.end())
|
|
||||||
{
|
|
||||||
std::cerr << " ERROR: client id " << service_id << " not registered. Consistency error." << std::endl;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
client = its->second ;
|
|
||||||
|
|
||||||
// also check wether this item is for us or not
|
// also check wether this item is for us or not
|
||||||
|
|
||||||
item_is_for_us = _owned_key_ids.find( makeTunnelHash(data_item->destination_key,service_id) ) != _owned_key_ids.end() ;
|
|
||||||
|
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << " item is " << (item_is_for_us?"":"not") << " for us." << std::endl;
|
std::cerr << " item is " << (item_is_for_us?"":"not") << " for us." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator it = _pending_messages.find(data_item->routing_id) ;
|
auto it = _pending_messages.find(data_item->routing_id) ;
|
||||||
|
|
||||||
if(it != _pending_messages.end())
|
if(it != _pending_messages.end())
|
||||||
{
|
{
|
||||||
@ -1709,26 +1741,56 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
std::cerr << " item is new." << std::endl;
|
std::cerr << " item is new." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!item_is_already_known)
|
||||||
|
{
|
||||||
|
uint32_t error_status ;
|
||||||
|
|
||||||
|
if(!verifySignedDataItem(data_item,RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CHECK,error_status)) // we should get proper flags out of this
|
||||||
|
{
|
||||||
|
switch(error_status)
|
||||||
|
{
|
||||||
|
case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE:
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMissingKeyQueueMtx);
|
||||||
|
|
||||||
|
rstime_t timeout = time(nullptr) + mMissingKeyQueueEntryTimeout;
|
||||||
|
RsGxsId authorId = data_item->signature.keyId;
|
||||||
|
mMissingKeyQueue.push_back( std::make_pair(std::unique_ptr<RsGRouterGenericDataItem>(data_item->duplicate()), timeout) );
|
||||||
|
|
||||||
|
/* Do not request the missing key here to the peer which forwarded the item as verifySignedDataItem(...) does it already */
|
||||||
|
|
||||||
|
RsInfo() << __PRETTY_FUNCTION__ << " Received a message from unknown RsGxsId: " << authorId <<". Cannot verify signature yet, storing in mMissingKeyQueue for later processing. Timeout: " << timeout << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " item signature verification FAILED with: " << error_status << ", Dropping!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef GROUTER_DEBUG
|
||||||
|
else
|
||||||
|
std::cerr << " verifying item signature: CHECKED!" ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// At this point, if item is already known, it is guarrantied to be identical to the stored item.
|
// At this point, if item is already known, it is guarrantied to be identical to the stored item.
|
||||||
// If the item is for us, and not already known, check the signature and hash, and generate a signed receipt
|
// If the item is for us, and not already known, check the signature and hash, and generate a signed receipt
|
||||||
|
|
||||||
if(item_is_for_us && !item_is_already_known)
|
if(item_is_for_us && !item_is_already_known)
|
||||||
{
|
{
|
||||||
|
// Check that we actually have a registered service ready to accept this item. If not, drop it.
|
||||||
|
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(grMtx) ;
|
||||||
|
auto its = _registered_services.find(service_id) ;
|
||||||
|
|
||||||
|
if(its != _registered_services.end())
|
||||||
|
clientService = its->second ;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << " step B: item is for us and is new, so make sure it's authentic and create a receipt" << std::endl;
|
std::cerr << " step B: item is for us and is new, so make sure it's authentic and create a receipt" << std::endl;
|
||||||
#endif
|
|
||||||
uint32_t error_status ;
|
|
||||||
|
|
||||||
if(!verifySignedDataItem(data_item,RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CHECK,error_status)) // we should get proper flags out of this
|
|
||||||
{
|
|
||||||
std::cerr << " verifying item signature: FAILED! Droping that item" ;
|
|
||||||
std::cerr << " You probably received a message from a person you don't have key." << std::endl;
|
|
||||||
std::cerr << " Signature key ID: " << data_item->signature.keyId << std::endl;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
#ifdef GROUTER_DEBUG
|
|
||||||
else
|
|
||||||
std::cerr << " verifying item signature: CHECKED!" ;
|
|
||||||
#endif
|
#endif
|
||||||
// No we need to send a signed receipt to the sender.
|
// No we need to send a signed receipt to the sender.
|
||||||
|
|
||||||
@ -1737,7 +1799,13 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
receipt_item->service_id = data_item->service_id ;
|
receipt_item->service_id = data_item->service_id ;
|
||||||
receipt_item->routing_id = data_item->routing_id ;
|
receipt_item->routing_id = data_item->routing_id ;
|
||||||
receipt_item->destination_key = data_item->signature.keyId ;
|
receipt_item->destination_key = data_item->signature.keyId ;
|
||||||
receipt_item->flags = 0 ;
|
receipt_item->flags = RsGRouterItemFlags::NONE ;
|
||||||
|
|
||||||
|
if(!clientService)
|
||||||
|
{
|
||||||
|
receipt_item->flags = RsGRouterItemFlags::SERVICE_UNKNOWN;
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " got a message from: " << data_item->signature.keyId << " for an unkown service: " << data_item->service_id << " is your RetroShare version updated?" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << " preparing signed receipt." << std::endl;
|
std::cerr << " preparing signed receipt." << std::endl;
|
||||||
@ -1813,7 +1881,7 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
|
|
||||||
// if the item is for us and is not already known, notify the client.
|
// if the item is for us and is not already known, notify the client.
|
||||||
|
|
||||||
if(item_is_for_us && !item_is_already_known)
|
if(clientService && !item_is_already_known)
|
||||||
{
|
{
|
||||||
// compute the hash before decryption.
|
// compute the hash before decryption.
|
||||||
|
|
||||||
@ -1835,9 +1903,9 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
|
|
||||||
std::cerr << " notyfying client." << std::endl;
|
std::cerr << " notyfying client." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if(client->acceptDataFromPeer(decrypted_item->signature.keyId))
|
if(clientService->acceptDataFromPeer(decrypted_item->signature.keyId))
|
||||||
{
|
{
|
||||||
client->receiveGRouterData(decrypted_item->destination_key,decrypted_item->signature.keyId,service_id,decrypted_item->data_bytes,decrypted_item->data_size);
|
clientService->receiveGRouterData(decrypted_item->destination_key,decrypted_item->signature.keyId,service_id,decrypted_item->data_bytes,decrypted_item->data_size);
|
||||||
|
|
||||||
decrypted_item->data_bytes = NULL ;
|
decrypted_item->data_bytes = NULL ;
|
||||||
decrypted_item->data_size = 0 ;
|
decrypted_item->data_size = 0 ;
|
||||||
@ -1871,7 +1939,7 @@ bool p3GRouter::locked_getLocallyRegisteredClientFromServiceId(const GRouterServ
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GRouter::addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id)
|
void p3GRouter::addRoutingClue(const RsGxsId& id, const RsPeerId& peer_id)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(grMtx) ;
|
RS_STACK_MUTEX(grMtx) ;
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
@ -1890,7 +1958,7 @@ bool p3GRouter::registerClientService(const GRouterServiceId& id,GRouterClientSe
|
|||||||
|
|
||||||
bool p3GRouter::encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key)
|
bool p3GRouter::encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key)
|
||||||
{
|
{
|
||||||
assert(!(item->flags & RS_GROUTER_DATA_FLAGS_ENCRYPTED)) ;
|
assert(!(item->flags & RsGRouterItemFlags::ENCRYPTED));
|
||||||
|
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << " Encrypting data for key " << destination_key << std::endl;
|
std::cerr << " Encrypting data for key " << destination_key << std::endl;
|
||||||
@ -1915,7 +1983,7 @@ bool p3GRouter::encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& de
|
|||||||
free(item->data_bytes) ;
|
free(item->data_bytes) ;
|
||||||
item->data_bytes = encrypted_data ;
|
item->data_bytes = encrypted_data ;
|
||||||
item->data_size = encrypted_size ;
|
item->data_size = encrypted_size ;
|
||||||
item->flags |= RS_GROUTER_DATA_FLAGS_ENCRYPTED ;
|
item->flags |= RsGRouterItemFlags::ENCRYPTED;
|
||||||
|
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << " Encrypted size = " << encrypted_size << std::endl;
|
std::cerr << " Encrypted size = " << encrypted_size << std::endl;
|
||||||
@ -1926,7 +1994,7 @@ return true ;
|
|||||||
}
|
}
|
||||||
bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item)
|
bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item)
|
||||||
{
|
{
|
||||||
assert(item->flags & RS_GROUTER_DATA_FLAGS_ENCRYPTED) ;
|
assert(!!(item->flags & RsGRouterItemFlags::ENCRYPTED));
|
||||||
|
|
||||||
#ifdef GROUTER_DEBUG
|
#ifdef GROUTER_DEBUG
|
||||||
std::cerr << " decrypting data for key " << item->destination_key << std::endl;
|
std::cerr << " decrypting data for key " << item->destination_key << std::endl;
|
||||||
@ -1952,7 +2020,7 @@ bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item)
|
|||||||
free(item->data_bytes) ;
|
free(item->data_bytes) ;
|
||||||
item->data_bytes = decrypted_data ;
|
item->data_bytes = decrypted_data ;
|
||||||
item->data_size = decrypted_size ;
|
item->data_size = decrypted_size ;
|
||||||
item->flags &= ~RS_GROUTER_DATA_FLAGS_ENCRYPTED ;
|
item->flags &= ~RsGRouterItemFlags::ENCRYPTED;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -2010,25 +2078,30 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const RsIdentityUsage::UsageCode& info,uint32_t& error_status)
|
bool p3GRouter::verifySignedDataItem(const RsGRouterAbstractMsgItem *item,const RsIdentityUsage::UsageCode& info,uint32_t& error_status)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( rsReputations->overallReputationLevel(item->signature.keyId) ==
|
if( rsReputations->overallReputationLevel(item->signature.keyId) ==
|
||||||
RsReputationLevel::LOCALLY_NEGATIVE )
|
RsReputationLevel::LOCALLY_NEGATIVE )
|
||||||
{
|
{
|
||||||
std::cerr << "(WW) received global router message from banned identity " << item->signature.keyId << ". Rejecting the message." << std::endl;
|
RsWarn() << __PRETTY_FUNCTION__ << " received global router "
|
||||||
|
<< "message from banned identity " << item->signature.keyId
|
||||||
|
<< ". Rejecting the message." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
RsGRouterSerialiser signature_serializer(RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER);
|
|
||||||
|
|
||||||
uint32_t data_size = signature_serializer.size(item) ;
|
RsGRouterSerialiser signature_serializer(
|
||||||
|
RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE |
|
||||||
|
RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER );
|
||||||
|
|
||||||
|
uint32_t data_size = signature_serializer.size(const_cast<RsGRouterAbstractMsgItem*>(item)); // the const cast shouldn't be necessary if size() took a const.
|
||||||
RsTemporaryMemory data(data_size);
|
RsTemporaryMemory data(data_size);
|
||||||
|
|
||||||
if(data == NULL)
|
if(data == NULL)
|
||||||
throw std::runtime_error("Cannot allocate data.") ;
|
throw std::runtime_error("Cannot allocate data.") ;
|
||||||
|
|
||||||
if(!signature_serializer.serialise(item,data,&data_size))
|
if(!signature_serializer.serialise(const_cast<RsGRouterAbstractMsgItem*>(item),data,&data_size))
|
||||||
throw std::runtime_error("Cannot serialise signed data.");
|
throw std::runtime_error("Cannot serialise signed data.");
|
||||||
|
|
||||||
RsIdentityUsage use(RS_SERVICE_TYPE_GROUTER,info);
|
RsIdentityUsage use(RS_SERVICE_TYPE_GROUTER,info);
|
||||||
@ -2042,14 +2115,15 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const RsIden
|
|||||||
std::list<RsPeerId> peer_ids;
|
std::list<RsPeerId> peer_ids;
|
||||||
peer_ids.push_back(item->PeerId());
|
peer_ids.push_back(item->PeerId());
|
||||||
|
|
||||||
std::cerr << "(EE) Key for GXS Id " << item->signature.keyId << " is not available. Cannot verify. Asking key to peer " << item->PeerId() << std::endl;
|
RsWarn() << __PRETTY_FUNCTION__ << " Key for GXS Id " << item->signature.keyId << " is not available. Cannot verify. Asking key to peer " << item->PeerId() << std::endl;
|
||||||
|
mGixs->requestKey(item->signature.keyId,peer_ids,use);
|
||||||
mGixs->requestKey(item->signature.keyId,peer_ids,use) ; // request the key around
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/Corrupted/MITM?." << std::endl;
|
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH:
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " Signature mismatch. " << "Spoofing/Corrupted/MITM?." << std::endl;
|
||||||
break;
|
break;
|
||||||
default: std::cerr << "(EE) Signature verification failed on GRouter message. Unknown error status: " << error_status << std::endl;
|
default:
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " Signature verification failed on GRouter message. Unknown error status: " << error_status << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2059,7 +2133,7 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const RsIden
|
|||||||
}
|
}
|
||||||
catch(std::exception& e)
|
catch(std::exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << " signature verification failed. Error: " << e.what() << std::endl;
|
RsErr() << __PRETTY_FUNCTION__ << " Failed. Error: " << e.what() << std::endl;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2127,7 +2201,7 @@ bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& clie
|
|||||||
data_item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ;
|
data_item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ;
|
||||||
data_item->service_id = client_id ;
|
data_item->service_id = client_id ;
|
||||||
data_item->destination_key = destination ;
|
data_item->destination_key = destination ;
|
||||||
data_item->flags = 0 ; // this is unused for now.
|
data_item->flags = RsGRouterItemFlags::NONE ; // this is unused for now.
|
||||||
|
|
||||||
// First, encrypt.
|
// First, encrypt.
|
||||||
|
|
||||||
@ -2204,8 +2278,12 @@ return true ;
|
|||||||
|
|
||||||
Sha1CheckSum p3GRouter::makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client)
|
Sha1CheckSum p3GRouter::makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client)
|
||||||
{
|
{
|
||||||
assert( destination.SIZE_IN_BYTES == 16) ;
|
static_assert( RsGxsId::SIZE_IN_BYTES == 16,
|
||||||
assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ;
|
"This function breaks if RsGxsId size changes" );
|
||||||
|
static_assert( Sha1CheckSum::SIZE_IN_BYTES == 20,
|
||||||
|
"This function breaks if Sha1CheckSum size changes" );
|
||||||
|
static_assert( sizeof(client) == 4,
|
||||||
|
"This function breaks if client service id size changes" );
|
||||||
|
|
||||||
uint8_t bytes[20] ;
|
uint8_t bytes[20] ;
|
||||||
memcpy(bytes,destination.toByteArray(),16) ;
|
memcpy(bytes,destination.toByteArray(),16) ;
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "retroshare/rsgrouter.h"
|
#include "retroshare/rsgrouter.h"
|
||||||
#include "retroshare/rstypes.h"
|
#include "retroshare/rstypes.h"
|
||||||
@ -33,15 +33,13 @@
|
|||||||
#include "turtle/turtleclientservice.h"
|
#include "turtle/turtleclientservice.h"
|
||||||
#include "services/p3service.h"
|
#include "services/p3service.h"
|
||||||
#include "pqi/p3cfgmgr.h"
|
#include "pqi/p3cfgmgr.h"
|
||||||
|
#include "util/rsdebug.h"
|
||||||
#include "groutertypes.h"
|
#include "groutertypes.h"
|
||||||
#include "groutermatrix.h"
|
#include "groutermatrix.h"
|
||||||
#include "grouteritems.h"
|
#include "grouteritems.h"
|
||||||
|
|
||||||
// To be put in pqi/p3cfgmgr.h
|
// To be put in pqi/p3cfgmgr.h
|
||||||
//
|
|
||||||
static const uint32_t CONFIG_TYPE_GROUTER = 0x0016 ;
|
static const uint32_t CONFIG_TYPE_GROUTER = 0x0016 ;
|
||||||
static const uint32_t RS_GROUTER_DATA_FLAGS_ENCRYPTED = 0x0001 ;
|
|
||||||
|
|
||||||
class p3LinkMgr ;
|
class p3LinkMgr ;
|
||||||
class p3turtle ;
|
class p3turtle ;
|
||||||
@ -126,7 +124,8 @@ public:
|
|||||||
// Routing clue collection methods //
|
// Routing clue collection methods //
|
||||||
//===================================================//
|
//===================================================//
|
||||||
|
|
||||||
virtual void addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id) ;
|
virtual void addRoutingClue(
|
||||||
|
const RsGxsId& id, const RsPeerId& peer_id) override;
|
||||||
|
|
||||||
//===================================================//
|
//===================================================//
|
||||||
// Client/server request services //
|
// Client/server request services //
|
||||||
@ -220,7 +219,7 @@ private:
|
|||||||
void handleLowLevelTransactionChunkItem(RsGRouterTransactionChunkItem *chunk_item);
|
void handleLowLevelTransactionChunkItem(RsGRouterTransactionChunkItem *chunk_item);
|
||||||
void handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem*) ;
|
void handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem*) ;
|
||||||
|
|
||||||
static Sha1CheckSum computeDataItemHash(RsGRouterGenericDataItem *data_item);
|
static Sha1CheckSum computeDataItemHash(const RsGRouterGenericDataItem *data_item);
|
||||||
|
|
||||||
std::ostream& grouter_debug() const
|
std::ostream& grouter_debug() const
|
||||||
{
|
{
|
||||||
@ -238,8 +237,9 @@ private:
|
|||||||
|
|
||||||
void handleIncoming() ;
|
void handleIncoming() ;
|
||||||
|
|
||||||
void handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_item) ;
|
void handleIncomingItem(const RsGRouterAbstractMsgItem *item);
|
||||||
void handleIncomingDataItem(RsGRouterGenericDataItem *data_item) ;
|
void handleIncomingReceiptItem(const RsGRouterSignedReceiptItem *receipt_item) ;
|
||||||
|
void handleIncomingDataItem(const RsGRouterGenericDataItem *data_item) ;
|
||||||
|
|
||||||
bool locked_getLocallyRegisteredClientFromServiceId(const GRouterServiceId& service_id,GRouterClientService *& client);
|
bool locked_getLocallyRegisteredClientFromServiceId(const GRouterServiceId& service_id,GRouterClientService *& client);
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ private:
|
|||||||
|
|
||||||
// signs an item with the given key.
|
// signs an item with the given key.
|
||||||
bool signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& id) ;
|
bool signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& id) ;
|
||||||
bool verifySignedDataItem(RsGRouterAbstractMsgItem *item, const RsIdentityUsage::UsageCode &info, uint32_t &error_status) ;
|
bool verifySignedDataItem(const RsGRouterAbstractMsgItem *item, const RsIdentityUsage::UsageCode &info, uint32_t &error_status) ;
|
||||||
bool encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key) ;
|
bool encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key) ;
|
||||||
bool decryptDataItem(RsGRouterGenericDataItem *item) ;
|
bool decryptDataItem(RsGRouterGenericDataItem *item) ;
|
||||||
|
|
||||||
@ -352,4 +352,23 @@ private:
|
|||||||
rstime_t _last_config_changed ;
|
rstime_t _last_config_changed ;
|
||||||
|
|
||||||
uint64_t _random_salt ;
|
uint64_t _random_salt ;
|
||||||
|
|
||||||
|
/** Temporarly store items that could not have been verified yet due to
|
||||||
|
* missing author key, attempt to handle them once in a while.
|
||||||
|
* The items are discarded if after mMissingKeyQueueEntryTimeout the key
|
||||||
|
* hasn't been received yet, and are not saved on RetroShare stopping. */
|
||||||
|
std::list< std::pair<
|
||||||
|
std::unique_ptr<RsGRouterAbstractMsgItem>, rstime_t > > mMissingKeyQueue;
|
||||||
|
RsMutex mMissingKeyQueueMtx; /// protect mMissingKeyQueue
|
||||||
|
|
||||||
|
/// @see mMissingKeyQueue
|
||||||
|
static constexpr rstime_t mMissingKeyQueueEntryTimeout = 600;
|
||||||
|
|
||||||
|
/// @see mMissingKeyQueue
|
||||||
|
static constexpr rstime_t mMissingKeyQueueCheckEvery = 30;
|
||||||
|
|
||||||
|
/// @see mMissingKeyQueue
|
||||||
|
rstime_t mMissingKeyQueueCheckLastCheck = 0;
|
||||||
|
|
||||||
|
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
||||||
};
|
};
|
||||||
|
@ -146,6 +146,7 @@ bool RsJsonApi::parseToken(
|
|||||||
|
|
||||||
JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||||
mService(std::make_shared<restbed::Service>()),
|
mService(std::make_shared<restbed::Service>()),
|
||||||
|
mServiceMutex("JsonApiServer restbed ptr"),
|
||||||
mListeningPort(RsJsonApi::DEFAULT_PORT),
|
mListeningPort(RsJsonApi::DEFAULT_PORT),
|
||||||
mBindingAddress(RsJsonApi::DEFAULT_BINDING_ADDRESS)
|
mBindingAddress(RsJsonApi::DEFAULT_BINDING_ADDRESS)
|
||||||
{
|
{
|
||||||
@ -310,6 +311,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
registerHandler("/rsEvents/registerEventsHandler",
|
registerHandler("/rsEvents/registerEventsHandler",
|
||||||
[this](const std::shared_ptr<rb::Session> session)
|
[this](const std::shared_ptr<rb::Session> session)
|
||||||
{
|
{
|
||||||
|
const std::weak_ptr<rb::Service> weakService(mService);
|
||||||
const std::multimap<std::string, std::string> headers
|
const std::multimap<std::string, std::string> headers
|
||||||
{
|
{
|
||||||
{ "Connection", "keep-alive" },
|
{ "Connection", "keep-alive" },
|
||||||
@ -319,7 +321,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
|
|
||||||
size_t reqSize = static_cast<size_t>(
|
size_t reqSize = static_cast<size_t>(
|
||||||
session->get_request()->get_header("Content-Length", 0) );
|
session->get_request()->get_header("Content-Length", 0) );
|
||||||
session->fetch( reqSize, [this](
|
session->fetch( reqSize, [weakService](
|
||||||
const std::shared_ptr<rb::Session> session,
|
const std::shared_ptr<rb::Session> session,
|
||||||
const rb::Bytes& body )
|
const rb::Bytes& body )
|
||||||
{
|
{
|
||||||
@ -329,12 +331,29 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
rsEvents, "rsEvents", cAns, session ) )
|
rsEvents, "rsEvents", cAns, session ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
RsEventType eventType = RsEventType::NONE;
|
||||||
|
|
||||||
|
// deserialize input parameters from JSON
|
||||||
|
{
|
||||||
|
RsGenericSerializer::SerializeContext& ctx(cReq);
|
||||||
|
RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);
|
||||||
|
RS_SERIAL_PROCESS(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
const std::weak_ptr<rb::Session> weakSession(session);
|
const std::weak_ptr<rb::Session> weakSession(session);
|
||||||
RsEventsHandlerId_t hId = rsEvents->generateUniqueHandlerId();
|
RsEventsHandlerId_t hId = rsEvents->generateUniqueHandlerId();
|
||||||
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback =
|
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback =
|
||||||
[this, weakSession, hId](std::shared_ptr<const RsEvent> event)
|
[weakSession, weakService, hId](
|
||||||
|
std::shared_ptr<const RsEvent> event )
|
||||||
{
|
{
|
||||||
mService->schedule( [weakSession, hId, event]()
|
auto lService = weakService.lock();
|
||||||
|
if(!lService || lService->is_down())
|
||||||
|
{
|
||||||
|
if(rsEvents) rsEvents->unregisterEventsHandler(hId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lService->schedule( [weakSession, hId, event]()
|
||||||
{
|
{
|
||||||
auto session = weakSession.lock();
|
auto session = weakSession.lock();
|
||||||
if(!session || session->is_closed())
|
if(!session || session->is_closed())
|
||||||
@ -355,7 +374,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
bool retval = rsEvents->registerEventsHandler(multiCallback, hId);
|
bool retval = rsEvents->registerEventsHandler(eventType,multiCallback, hId);
|
||||||
|
|
||||||
{
|
{
|
||||||
RsGenericSerializer::SerializeContext& ctx(cAns);
|
RsGenericSerializer::SerializeContext& ctx(cAns);
|
||||||
@ -500,10 +519,10 @@ bool JsonApiServer::authorizeUser(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!librs::util::is_alphanumeric(passwd))
|
if(passwd.empty())
|
||||||
{
|
{
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " Password is not alphanumeric"
|
RsWarn() << __PRETTY_FUNCTION__ << " Password is empty, are you sure "
|
||||||
<< std::endl;
|
<< "this what you wanted?" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,21 +600,21 @@ std::vector<std::shared_ptr<rb::Resource> > JsonApiServer::getResources() const
|
|||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonApiServer::restart()
|
void JsonApiServer::restart()
|
||||||
|
{
|
||||||
|
/* It is important to wrap into async(...) because fullstop() method can't
|
||||||
|
* be called from same thread of execution hence from JSON API thread! */
|
||||||
|
RsThread::async([this]()
|
||||||
{
|
{
|
||||||
fullstop();
|
fullstop();
|
||||||
RsThread::start("JSON API Server");
|
RsThread::start("JSON API Server");
|
||||||
|
});
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonApiServer::onStopRequested()
|
void JsonApiServer::onStopRequested()
|
||||||
{ if(mService->is_up()) mService->stop(); }
|
|
||||||
|
|
||||||
bool JsonApiServer::fullstop()
|
|
||||||
{
|
{
|
||||||
RsThread::fullstop();
|
RS_STACK_MUTEX(mServiceMutex);
|
||||||
return true;
|
mService->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t JsonApiServer::listeningPort() const { return mListeningPort; }
|
uint16_t JsonApiServer::listeningPort() const { return mListeningPort; }
|
||||||
@ -611,16 +630,12 @@ void JsonApiServer::run()
|
|||||||
settings->set_bind_address(mBindingAddress);
|
settings->set_bind_address(mBindingAddress);
|
||||||
settings->set_default_header("Connection", "close");
|
settings->set_default_header("Connection", "close");
|
||||||
|
|
||||||
if(mService->is_up())
|
|
||||||
{
|
|
||||||
RsWarn() << __PRETTY_FUNCTION__ << " restbed is already running. "
|
|
||||||
<< " stopping it before starting again!" << std::endl;
|
|
||||||
mService->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* re-allocating mService is important because it deletes the existing
|
/* re-allocating mService is important because it deletes the existing
|
||||||
* service and therefore leaves the listening port open */
|
* service and therefore leaves the listening port open */
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mServiceMutex);
|
||||||
mService = std::make_shared<restbed::Service>();
|
mService = std::make_shared<restbed::Service>();
|
||||||
|
}
|
||||||
|
|
||||||
for(auto& r: getResources()) mService->publish(r);
|
for(auto& r: getResources()) mService->publish(r);
|
||||||
|
|
||||||
@ -628,7 +643,7 @@ void JsonApiServer::run()
|
|||||||
{
|
{
|
||||||
RsUrl apiUrl; apiUrl.setScheme("http").setHost(mBindingAddress)
|
RsUrl apiUrl; apiUrl.setScheme("http").setHost(mBindingAddress)
|
||||||
.setPort(mListeningPort);
|
.setPort(mListeningPort);
|
||||||
RsDbg() << __PRETTY_FUNCTION__ << " JSON API server listening on "
|
RsInfo() << __PRETTY_FUNCTION__ << " JSON API server listening on "
|
||||||
<< apiUrl.toString() << std::endl;
|
<< apiUrl.toString() << std::endl;
|
||||||
mService->start(settings);
|
mService->start(settings);
|
||||||
}
|
}
|
||||||
@ -640,7 +655,7 @@ void JsonApiServer::run()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsInfo() << __PRETTY_FUNCTION__ << " finished!" << std::endl;
|
RsDbg() << __PRETTY_FUNCTION__ << " finished!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void RsJsonApi::version(
|
/*static*/ void RsJsonApi::version(
|
||||||
|
@ -63,10 +63,13 @@ public:
|
|||||||
std::vector<std::shared_ptr<rb::Resource>> getResources() const;
|
std::vector<std::shared_ptr<rb::Resource>> getResources() const;
|
||||||
|
|
||||||
/// @see RsJsonApi
|
/// @see RsJsonApi
|
||||||
bool restart() override;
|
void fullstop() override { RsThread::fullstop(); }
|
||||||
|
|
||||||
/// @see RsJsonApi
|
/// @see RsJsonApi
|
||||||
bool fullstop() override;
|
void restart() override;
|
||||||
|
|
||||||
|
/// @see RsJsonApi
|
||||||
|
void askForStop() override { RsThread::askForStop(); }
|
||||||
|
|
||||||
/// @see RsJsonApi
|
/// @see RsJsonApi
|
||||||
inline bool isRunning() override { return RsThread::isRunning(); }
|
inline bool isRunning() override { return RsThread::isRunning(); }
|
||||||
@ -193,6 +196,10 @@ private:
|
|||||||
std::less<const JsonApiResourceProvider> > mResourceProviders;
|
std::less<const JsonApiResourceProvider> > mResourceProviders;
|
||||||
|
|
||||||
std::shared_ptr<restbed::Service> mService;
|
std::shared_ptr<restbed::Service> mService;
|
||||||
|
/** Protect service only during very critical operation like resetting the
|
||||||
|
* pointer, still not 100% thread safe, but hopefully we can avoid
|
||||||
|
* crashes/freeze with this */
|
||||||
|
RsMutex mServiceMutex;
|
||||||
|
|
||||||
uint16_t mListeningPort;
|
uint16_t mListeningPort;
|
||||||
std::string mBindingAddress;
|
std::string mBindingAddress;
|
||||||
|
@ -71,12 +71,21 @@ struct RsBroadcastDiscoveryResult : RsSerializable
|
|||||||
* @brief Event emitted when a non friend new peer is found in the local network
|
* @brief Event emitted when a non friend new peer is found in the local network
|
||||||
* @see RsEvents
|
* @see RsEvents
|
||||||
*/
|
*/
|
||||||
struct RsBroadcastDiscoveryPeerFoundEvent : RsEvent
|
enum class RsBroadcastDiscoveryEventType: uint32_t {
|
||||||
{
|
UNKNOWN = 0x00,
|
||||||
RsBroadcastDiscoveryPeerFoundEvent(
|
PEER_FOUND = 0x01
|
||||||
const RsBroadcastDiscoveryResult& eventData ) :
|
};
|
||||||
RsEvent(RsEventType::BROADCAST_DISCOVERY_PEER_FOUND), mData(eventData) {}
|
|
||||||
|
|
||||||
|
struct RsBroadcastDiscoveryEvent : RsEvent
|
||||||
|
{
|
||||||
|
RsBroadcastDiscoveryEvent()
|
||||||
|
: RsEvent(RsEventType::BROADCAST_DISCOVERY),
|
||||||
|
mDiscoveryEventType(RsBroadcastDiscoveryEventType::UNKNOWN)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~RsBroadcastDiscoveryEvent() override = default;
|
||||||
|
|
||||||
|
RsBroadcastDiscoveryEventType mDiscoveryEventType;
|
||||||
RsBroadcastDiscoveryResult mData;
|
RsBroadcastDiscoveryResult mData;
|
||||||
|
|
||||||
/// @see RsSerializable
|
/// @see RsSerializable
|
||||||
@ -84,10 +93,10 @@ struct RsBroadcastDiscoveryPeerFoundEvent : RsEvent
|
|||||||
RsGenericSerializer::SerializeContext& ctx) override
|
RsGenericSerializer::SerializeContext& ctx) override
|
||||||
{
|
{
|
||||||
RsEvent::serial_process(j, ctx);
|
RsEvent::serial_process(j, ctx);
|
||||||
|
|
||||||
|
RS_SERIAL_PROCESS(mDiscoveryEventType);
|
||||||
RS_SERIAL_PROCESS(mData);
|
RS_SERIAL_PROCESS(mData);
|
||||||
}
|
}
|
||||||
|
|
||||||
~RsBroadcastDiscoveryPeerFoundEvent() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,10 +53,10 @@ enum class RsEventType : uint32_t
|
|||||||
NONE = 0, /// Used to detect uninitialized event
|
NONE = 0, /// Used to detect uninitialized event
|
||||||
|
|
||||||
/// @see RsBroadcastDiscovery
|
/// @see RsBroadcastDiscovery
|
||||||
BROADCAST_DISCOVERY_PEER_FOUND = 1,
|
BROADCAST_DISCOVERY = 1,
|
||||||
|
|
||||||
/// @see RsDiscPendingPgpReceivedEvent
|
/// @see RsDiscPendingPgpReceivedEvent
|
||||||
GOSSIP_DISCOVERY_INVITE_RECEIVED = 2,
|
GOSSIP_DISCOVERY = 2,
|
||||||
|
|
||||||
/// @see AuthSSL
|
/// @see AuthSSL
|
||||||
AUTHSSL_CONNECTION_AUTENTICATION = 3,
|
AUTHSSL_CONNECTION_AUTENTICATION = 3,
|
||||||
@ -64,14 +64,14 @@ enum class RsEventType : uint32_t
|
|||||||
/// @see pqissl
|
/// @see pqissl
|
||||||
PEER_CONNECTION = 4,
|
PEER_CONNECTION = 4,
|
||||||
|
|
||||||
/// @see RsGxsChanges
|
/// @see RsGxsChanges // this one is used in RsGxsBroadcast
|
||||||
GXS_CHANGES = 5,
|
GXS_CHANGES = 5,
|
||||||
|
|
||||||
/// Emitted when a peer state changes, @see RsPeers
|
/// Emitted when a peer state changes, @see RsPeers
|
||||||
PEER_STATE_CHANGED = 6,
|
PEER_STATE_CHANGED = 6,
|
||||||
|
|
||||||
/// @see RsMailStatusEvent
|
/// @see RsMailStatusEvent
|
||||||
MAIL_STATUS_CHANGE = 7,
|
MAIL_STATUS = 7,
|
||||||
|
|
||||||
/// @see RsGxsCircleEvent
|
/// @see RsGxsCircleEvent
|
||||||
GXS_CIRCLES = 8,
|
GXS_CIRCLES = 8,
|
||||||
@ -163,6 +163,7 @@ public:
|
|||||||
* Every time an event is dispatced the registered events handlers will get
|
* Every time an event is dispatced the registered events handlers will get
|
||||||
* their method handleEvent called with the event passed as paramether.
|
* their method handleEvent called with the event passed as paramether.
|
||||||
* @jsonapi{development,manualwrapper}
|
* @jsonapi{development,manualwrapper}
|
||||||
|
* @param eventType Type of event for which the callback is called
|
||||||
* @param multiCallback Function that will be called each time an event
|
* @param multiCallback Function that will be called each time an event
|
||||||
* is dispatched.
|
* is dispatched.
|
||||||
* @param[inout] hId Optional storage for handler id, useful to
|
* @param[inout] hId Optional storage for handler id, useful to
|
||||||
@ -173,6 +174,7 @@ public:
|
|||||||
* @return False on error, true otherwise.
|
* @return False on error, true otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool registerEventsHandler(
|
virtual bool registerEventsHandler(
|
||||||
|
RsEventType eventType,
|
||||||
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
||||||
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
|
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
|
||||||
) = 0;
|
) = 0;
|
||||||
|
@ -45,11 +45,18 @@ extern std::shared_ptr<RsGossipDiscovery> rsGossipDiscovery;
|
|||||||
/**
|
/**
|
||||||
* @brief Emitted when a pending PGP certificate is received
|
* @brief Emitted when a pending PGP certificate is received
|
||||||
*/
|
*/
|
||||||
struct RsGossipDiscoveryFriendInviteReceivedEvent : RsEvent
|
|
||||||
{
|
|
||||||
RsGossipDiscoveryFriendInviteReceivedEvent(
|
|
||||||
const std::string& invite );
|
|
||||||
|
|
||||||
|
enum class RsGossipDiscoveryEventType: uint32_t {
|
||||||
|
UNKNOWN = 0x00,
|
||||||
|
PEER_INVITE_RECEIVED = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RsGossipDiscoveryEvent : RsEvent
|
||||||
|
{
|
||||||
|
RsGossipDiscoveryEvent(): RsEvent(RsEventType::GOSSIP_DISCOVERY) {}
|
||||||
|
virtual ~RsGossipDiscoveryEvent() override {}
|
||||||
|
|
||||||
|
RsGossipDiscoveryEventType mGossipDiscoveryEventType;
|
||||||
std::string mInvite;
|
std::string mInvite;
|
||||||
|
|
||||||
/// @see RsSerializable
|
/// @see RsSerializable
|
||||||
@ -57,6 +64,7 @@ struct RsGossipDiscoveryFriendInviteReceivedEvent : RsEvent
|
|||||||
RsGenericSerializer::SerializeContext& ctx )
|
RsGenericSerializer::SerializeContext& ctx )
|
||||||
{
|
{
|
||||||
RsEvent::serial_process(j,ctx);
|
RsEvent::serial_process(j,ctx);
|
||||||
|
RS_SERIAL_PROCESS(mGossipDiscoveryEventType);
|
||||||
RS_SERIAL_PROCESS(mInvite);
|
RS_SERIAL_PROCESS(mInvite);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/rsdir.h"
|
#include "util/rsdir.h"
|
||||||
|
#include "util/rsdeprecate.h"
|
||||||
#include "retroshare/rsids.h"
|
#include "retroshare/rsids.h"
|
||||||
#include "retroshare/rsgxsifacetypes.h"
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
|
#include "rsitems/rsserviceids.h"
|
||||||
|
|
||||||
typedef RsGxsId GRouterKeyId ; // we use SSLIds, so that it's easier in the GUI to mix up peer ids with grouter ids.
|
typedef RsGxsId GRouterKeyId ; // we use SSLIds, so that it's easier in the GUI to mix up peer ids with grouter ids.
|
||||||
typedef uint32_t GRouterServiceId ;
|
typedef uint32_t GRouterServiceId ;
|
||||||
|
@ -511,9 +511,13 @@ struct RsIdentity : RsGxsIfaceHelper
|
|||||||
* @brief request details of a not yet known identity to the network
|
* @brief request details of a not yet known identity to the network
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[in] id id of the identity to request
|
* @param[in] id id of the identity to request
|
||||||
|
* @param[in] peers optional list of the peers to ask for the key, if empty
|
||||||
|
* all online peers are asked.
|
||||||
* @return false on error, true otherwise
|
* @return false on error, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool requestIdentity(const RsGxsId& id) = 0;
|
virtual bool requestIdentity(
|
||||||
|
const RsGxsId& id,
|
||||||
|
const std::vector<RsPeerId>& peers = std::vector<RsPeerId>() ) = 0;
|
||||||
|
|
||||||
/// default base URL used for indentity links @see exportIdentityLink
|
/// default base URL used for indentity links @see exportIdentityLink
|
||||||
static const std::string DEFAULT_IDENTITY_BASE_URL;
|
static const std::string DEFAULT_IDENTITY_BASE_URL;
|
||||||
|
@ -43,18 +43,25 @@ public:
|
|||||||
static const std::string DEFAULT_BINDING_ADDRESS; // 127.0.0.1
|
static const std::string DEFAULT_BINDING_ADDRESS; // 127.0.0.1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Restart RsJsonApi server
|
* @brief Restart RsJsonApi server asynchronously.
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
*/
|
*/
|
||||||
virtual bool restart() = 0;
|
virtual void restart() = 0;
|
||||||
|
|
||||||
|
/** @brief Request RsJsonApi to stop and wait until it has stopped.
|
||||||
|
* Do not expose this method to JSON API as fullstop must not be called from
|
||||||
|
* the same thread of service execution.
|
||||||
|
*/
|
||||||
|
virtual void fullstop() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Request RsJsonApi to stop and wait until ti has stopped.
|
* @brief Request RsJsonApi to stop asynchronously.
|
||||||
|
* @jsonapi{development}
|
||||||
* Be expecially carefull to call this from JSON API because you will loose
|
* Be expecially carefull to call this from JSON API because you will loose
|
||||||
* access to the API.
|
* access to the API.
|
||||||
* @jsonapi{development}
|
* If you need to wait until stopping has completed @see isRunning().
|
||||||
*/
|
*/
|
||||||
virtual bool fullstop() = 0;
|
virtual void askForStop() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get status of the json api server
|
* @brief Get status of the json api server
|
||||||
@ -128,8 +135,7 @@ public:
|
|||||||
std::string& user, std::string& passwd );
|
std::string& user, std::string& passwd );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new auth (user,passwd) token to the authorized set, creating the
|
* Add new API auth (user,passwd) token to the authorized set.
|
||||||
* token user:passwd internally.
|
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[in] user user name to autorize, must be alphanumerinc
|
* @param[in] user user name to autorize, must be alphanumerinc
|
||||||
* @param[in] password password for the user, must be alphanumerinc
|
* @param[in] password password for the user, must be alphanumerinc
|
||||||
|
@ -296,7 +296,6 @@ struct MsgTagType : RsSerializable
|
|||||||
} //namespace Rs
|
} //namespace Rs
|
||||||
} //namespace Msgs
|
} //namespace Msgs
|
||||||
|
|
||||||
|
|
||||||
enum class RsMailStatusEventCode: uint8_t
|
enum class RsMailStatusEventCode: uint8_t
|
||||||
{
|
{
|
||||||
NEW_MESSAGE = 0x00,
|
NEW_MESSAGE = 0x00,
|
||||||
@ -312,7 +311,7 @@ enum class RsMailStatusEventCode: uint8_t
|
|||||||
|
|
||||||
struct RsMailStatusEvent : RsEvent
|
struct RsMailStatusEvent : RsEvent
|
||||||
{
|
{
|
||||||
RsMailStatusEvent() : RsEvent(RsEventType::MAIL_STATUS_CHANGE) {}
|
RsMailStatusEvent() : RsEvent(RsEventType::MAIL_STATUS) {}
|
||||||
|
|
||||||
RsMailStatusEventCode mMailStatusEventCode;
|
RsMailStatusEventCode mMailStatusEventCode;
|
||||||
std::set<RsMailMessageId> mChangedMsgIds;
|
std::set<RsMailMessageId> mChangedMsgIds;
|
||||||
@ -326,7 +325,7 @@ struct RsMailStatusEvent : RsEvent
|
|||||||
RS_SERIAL_PROCESS(mMailStatusEventCode);
|
RS_SERIAL_PROCESS(mMailStatusEventCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
~RsMailStatusEvent() override;
|
~RsMailStatusEvent() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RS_CHAT_PUBLIC 0x0001
|
#define RS_CHAT_PUBLIC 0x0001
|
||||||
|
@ -538,8 +538,7 @@ bool p3Msgs::initiateDistantChatConnexion(
|
|||||||
const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id,
|
const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id,
|
||||||
DistantChatPeerId& pid, uint32_t& error_code, bool notify )
|
DistantChatPeerId& pid, uint32_t& error_code, bool notify )
|
||||||
{
|
{
|
||||||
return mChatSrv->initiateDistantChatConnexion( to_gxs_id, from_gxs_id,
|
return mChatSrv->initiateDistantChatConnexion( to_gxs_id, from_gxs_id, pid, error_code, notify );
|
||||||
pid, error_code, notify );
|
|
||||||
}
|
}
|
||||||
bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info)
|
bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info)
|
||||||
{
|
{
|
||||||
@ -559,7 +558,6 @@ uint32_t p3Msgs::getDistantChatPermissionFlags()
|
|||||||
}
|
}
|
||||||
|
|
||||||
RsMsgs::~RsMsgs() = default;
|
RsMsgs::~RsMsgs() = default;
|
||||||
RsMailStatusEvent::~RsMailStatusEvent() = default;
|
|
||||||
Rs::Msgs::MessageInfo::~MessageInfo() = default;
|
Rs::Msgs::MessageInfo::~MessageInfo() = default;
|
||||||
MsgInfoSummary::~MsgInfoSummary() = default;
|
MsgInfoSummary::~MsgInfoSummary() = default;
|
||||||
VisibleChatLobbyRecord::~VisibleChatLobbyRecord() = default;
|
VisibleChatLobbyRecord::~VisibleChatLobbyRecord() = default;
|
||||||
|
@ -297,6 +297,7 @@ int RsInit::InitRetroShare(const RsConfigOptions& conf)
|
|||||||
rsInitConfig->inet = conf.forcedInetAddress ;
|
rsInitConfig->inet = conf.forcedInetAddress ;
|
||||||
rsInitConfig->port = conf.forcedPort ;
|
rsInitConfig->port = conf.forcedPort ;
|
||||||
rsInitConfig->debugLevel = conf.debugLevel;
|
rsInitConfig->debugLevel = conf.debugLevel;
|
||||||
|
rsInitConfig->udpListenerOnly = conf.udpListenerOnly;
|
||||||
rsInitConfig->optBaseDir = conf.optBaseDir;
|
rsInitConfig->optBaseDir = conf.optBaseDir;
|
||||||
rsInitConfig->jsonApiPort = conf.jsonApiPort;
|
rsInitConfig->jsonApiPort = conf.jsonApiPort;
|
||||||
rsInitConfig->jsonApiBindAddress = conf.jsonApiBindAddress;
|
rsInitConfig->jsonApiBindAddress = conf.jsonApiBindAddress;
|
||||||
|
@ -182,10 +182,15 @@ void BroadcastDiscoveryService::threadTick()
|
|||||||
}
|
}
|
||||||
else if(!isFriend)
|
else if(!isFriend)
|
||||||
{
|
{
|
||||||
typedef RsBroadcastDiscoveryPeerFoundEvent Evt_t;
|
|
||||||
if(rsEvents)
|
if(rsEvents)
|
||||||
rsEvents->postEvent(
|
{
|
||||||
std::shared_ptr<Evt_t>(new Evt_t(rbdr)) );
|
auto ev = std::make_shared<RsBroadcastDiscoveryEvent>();
|
||||||
|
|
||||||
|
ev->mDiscoveryEventType = RsBroadcastDiscoveryEventType::PEER_FOUND;
|
||||||
|
ev->mData = rbdr;
|
||||||
|
|
||||||
|
rsEvents->postEvent(ev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,5 +312,4 @@ bool BroadcastDiscoveryService::assertMulticastLockIsvalid()
|
|||||||
|
|
||||||
RsBroadcastDiscovery::~RsBroadcastDiscovery() = default;
|
RsBroadcastDiscovery::~RsBroadcastDiscovery() = default;
|
||||||
RsBroadcastDiscoveryResult::~RsBroadcastDiscoveryResult() = default;
|
RsBroadcastDiscoveryResult::~RsBroadcastDiscoveryResult() = default;
|
||||||
RsBroadcastDiscoveryPeerFoundEvent::~RsBroadcastDiscoveryPeerFoundEvent() = default;
|
|
||||||
BroadcastDiscoveryPack::~BroadcastDiscoveryPack() = default;
|
BroadcastDiscoveryPack::~BroadcastDiscoveryPack() = default;
|
||||||
|
@ -247,7 +247,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||||
if (msgChange)
|
if (msgChange)
|
||||||
{
|
{
|
||||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW)
|
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED)
|
||||||
{
|
{
|
||||||
/* message received */
|
/* message received */
|
||||||
if (rsEvents)
|
if (rsEvents)
|
||||||
|
@ -501,7 +501,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
RsGxsCircleDetails details;
|
RsGxsCircleDetails details;
|
||||||
getCircleDetails(circle_id,details);
|
getCircleDetails(circle_id,details);
|
||||||
|
|
||||||
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
|
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) )
|
||||||
for (auto msgIdIt(mit->second.begin()), end(mit->second.end()); msgIdIt != end; ++msgIdIt)
|
for (auto msgIdIt(mit->second.begin()), end(mit->second.end()); msgIdIt != end; ++msgIdIt)
|
||||||
{
|
{
|
||||||
RsGxsCircleMsg msg;
|
RsGxsCircleMsg msg;
|
||||||
|
@ -191,7 +191,7 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||||
if (msgChange)
|
if (msgChange)
|
||||||
{
|
{
|
||||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) /* message received */
|
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */
|
||||||
if (rsEvents)
|
if (rsEvents)
|
||||||
{
|
{
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& msgChangeMap = msgChange->msgChangeMap;
|
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& msgChangeMap = msgChange->msgChangeMap;
|
||||||
|
@ -1163,91 +1163,88 @@ bool p3IdService::havePrivateKey(const RsGxsId &id)
|
|||||||
if(! isOwnId(id))
|
if(! isOwnId(id))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
RS_STACK_MUTEX(mIdMtx);
|
||||||
return mKeyCache.is_cached(id);
|
return mKeyCache.is_cached(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mergeIds(std::map<RsGxsId,std::list<RsPeerId> >& idmap,const RsGxsId& id,const std::list<RsPeerId>& peers)
|
static void mergeIds(std::map<RsGxsId,std::list<RsPeerId> >& idmap,const RsGxsId& id,const std::list<RsPeerId>& peers)
|
||||||
{
|
{
|
||||||
// merge the two lists (I use a std::set to make it more efficient)
|
/* merge the two lists, use std::set to avoid duplicates efficiently */
|
||||||
#ifdef DEBUG_IDS
|
|
||||||
std::cerr << "p3IdService::requestKey(): merging list with existing pending request." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::list<RsPeerId>& old_peers(idmap[id]) ; // create if necessary
|
std::set<RsPeerId> new_peers(std::begin(peers), std::end(peers));
|
||||||
std::set<RsPeerId> new_peers ;
|
|
||||||
|
|
||||||
for(std::list<RsPeerId>::const_iterator it(peers.begin());it!=peers.end();++it)
|
std::list<RsPeerId>& stored_peers(idmap[id]);
|
||||||
new_peers.insert(*it) ;
|
std::copy( std::begin(stored_peers), std::end(stored_peers),
|
||||||
|
std::inserter(new_peers, std::begin(new_peers)) );
|
||||||
for(std::list<RsPeerId>::iterator it(old_peers.begin());it!=old_peers.end();++it)
|
stored_peers.clear();
|
||||||
new_peers.insert(*it) ;
|
std::copy( std::begin(new_peers), std::end(new_peers),
|
||||||
|
std::inserter(stored_peers, std::begin(stored_peers)) );
|
||||||
old_peers.clear();
|
|
||||||
|
|
||||||
for(std::set<RsPeerId>::iterator it(new_peers.begin());it!=new_peers.end();++it)
|
|
||||||
old_peers.push_back(*it) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3IdService::requestIdentity(const RsGxsId& id)
|
bool p3IdService::requestIdentity(
|
||||||
|
const RsGxsId& id, const std::vector<RsPeerId>& peers )
|
||||||
{
|
{
|
||||||
|
std::list<RsPeerId> askPeersList(peers.begin(), peers.end());
|
||||||
|
|
||||||
|
// Empty list passed? Ask to all online peers.
|
||||||
|
if(askPeersList.empty()) rsPeers->getOnlineList(askPeersList);
|
||||||
|
|
||||||
|
if(askPeersList.empty()) // Still empty? Fail!
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " failure retrieving peers list"
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RsIdentityUsage usageInfo( RsServiceType::GXSID,
|
RsIdentityUsage usageInfo( RsServiceType::GXSID,
|
||||||
RsIdentityUsage::IDENTITY_DATA_UPDATE );
|
RsIdentityUsage::IDENTITY_DATA_UPDATE );
|
||||||
std::list<RsPeerId> onlinePeers;
|
|
||||||
|
|
||||||
return rsPeers && rsPeers->getOnlineList(onlinePeers)
|
return requestKey(id, askPeersList, usageInfo);
|
||||||
&& requestKey(id, onlinePeers, usageInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers,const RsIdentityUsage& use_info)
|
bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers,const RsIdentityUsage& use_info)
|
||||||
{
|
{
|
||||||
|
Dbg3() << __PRETTY_FUNCTION__ << " id: " << id << std::endl;
|
||||||
|
|
||||||
if(id.isNull())
|
if(id.isNull())
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) nul ID requested to p3IdService. This should not happen. Callstack:" << std::endl;
|
RsErr() << __PRETTY_FUNCTION__ << " cannot request null id"
|
||||||
print_stacktrace();
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (haveKey(id))
|
if(peers.empty())
|
||||||
return true;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Normally we should call getIdDetails(), but since the key is not known, we need to digg a possibly old information
|
RsErr() << __PRETTY_FUNCTION__ << " cannot request id: " << id
|
||||||
// from the reputation system, which keeps its own list of banned keys. Of course, the owner ID is not known at this point.
|
<< " to empty lists of peers" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_IDS
|
if(isKnownId(id)) return true;
|
||||||
std::cerr << "p3IdService::requesting key " << id <<std::endl;
|
|
||||||
#endif
|
/* Normally we should call getIdDetails(), but since the key is not known,
|
||||||
|
* we need to dig a possibly old information from the reputation system,
|
||||||
|
* which keeps its own list of banned keys.
|
||||||
|
* Of course, the owner ID is not known at this point.c*/
|
||||||
|
|
||||||
RsReputationInfo info;
|
RsReputationInfo info;
|
||||||
rsReputations->getReputationInfo(id, RsPgpId(), info);
|
rsReputations->getReputationInfo(id, RsPgpId(), info);
|
||||||
|
|
||||||
if( info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE )
|
if( info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE )
|
||||||
{
|
{
|
||||||
std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl;
|
RsInfo() << __PRETTY_FUNCTION__ << " not requesting Key " << id
|
||||||
|
<< " because it has been banned." << std::endl;
|
||||||
|
|
||||||
{
|
RS_STACK_MUTEX(mIdMtx);
|
||||||
RS_STACK_MUTEX(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
mIdsNotPresent.erase(id);
|
mIdsNotPresent.erase(id);
|
||||||
}
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
std::map<RsGxsId,std::list<RsPeerId> >::iterator rit = mIdsNotPresent.find(id) ;
|
|
||||||
|
|
||||||
if(rit != mIdsNotPresent.end())
|
|
||||||
{
|
{
|
||||||
if(!peers.empty())
|
RS_STACK_MUTEX(mIdMtx);
|
||||||
mergeIds(mIdsNotPresent, id, peers);
|
mergeIds(mIdsNotPresent, id, peers);
|
||||||
|
mKeysTS[id].usage_map[use_info] = time(nullptr);
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
RS_STACK_MUTEX(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
mKeysTS[id].usage_map[use_info] = time(NULL) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache_request_load(id, peers);
|
return cache_request_load(id, peers);
|
||||||
@ -2772,31 +2769,27 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
|
|||||||
|
|
||||||
bool p3IdService::cache_request_load(const RsGxsId &id, const std::list<RsPeerId> &peers)
|
bool p3IdService::cache_request_load(const RsGxsId &id, const std::list<RsPeerId> &peers)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_IDS
|
Dbg4() << __PRETTY_FUNCTION__ << " id: " << id << std::endl;
|
||||||
std::cerr << "p3IdService::cache_request_load(" << id << ")" << std::endl;
|
|
||||||
#endif // DEBUG_IDS
|
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
RS_STACK_MUTEX(mIdMtx);
|
||||||
|
// merge, even if peers is empty
|
||||||
mergeIds(mCacheLoad_ToCache,id,peers) ; // merge, even if peers is empty
|
mergeIds(mCacheLoad_ToCache, id, peers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RsTickEvent::event_count(GXSID_EVENT_CACHELOAD) > 0)
|
if(RsTickEvent::event_count(GXSID_EVENT_CACHELOAD) > 0)
|
||||||
{
|
{
|
||||||
/* its already scheduled */
|
Dbg3() << __PRETTY_FUNCTION__ << " cache reload already scheduled "
|
||||||
|
<< "skipping" << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t age = 0;
|
int32_t age = 0;
|
||||||
if (RsTickEvent::prev_event_ago(GXSID_EVENT_CACHELOAD, age))
|
if( RsTickEvent::prev_event_ago(GXSID_EVENT_CACHELOAD, age) && age < MIN_CYCLE_GAP )
|
||||||
{
|
|
||||||
if (age < MIN_CYCLE_GAP)
|
|
||||||
{
|
{
|
||||||
RsTickEvent::schedule_in(GXSID_EVENT_CACHELOAD, MIN_CYCLE_GAP - age);
|
RsTickEvent::schedule_in(GXSID_EVENT_CACHELOAD, MIN_CYCLE_GAP - age);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RsTickEvent::schedule_now(GXSID_EVENT_CACHELOAD);
|
RsTickEvent::schedule_now(GXSID_EVENT_CACHELOAD);
|
||||||
return true;
|
return true;
|
||||||
@ -2923,42 +2916,57 @@ bool p3IdService::cache_load_for_token(uint32_t token)
|
|||||||
|
|
||||||
void p3IdService::requestIdsFromNet()
|
void p3IdService::requestIdsFromNet()
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mIdMtx);
|
RS_STACK_MUTEX(mIdMtx);
|
||||||
|
|
||||||
if(!mNes)
|
if(!mNes)
|
||||||
{
|
{
|
||||||
std::cerr << "(WW) cannot request missing GXS IDs because network service is not present." << std::endl;
|
RsErr() << __PRETTY_FUNCTION__ << " Cannot request missing GXS IDs "
|
||||||
|
<< "because network service is not present." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<RsGxsId, std::list<RsPeerId> >::iterator cit;
|
std::map<RsGxsId, std::list<RsPeerId> >::iterator cit;
|
||||||
std::map<RsPeerId, std::list<RsGxsId> > requests;
|
std::map<RsPeerId, std::list<RsGxsId> > requests;
|
||||||
|
|
||||||
// Transform to appropriate structure (<peer, std::list<RsGxsId> > map) to make request to nes per peer ID
|
/* Transform to appropriate structure (<RsPeerId, std::list<RsGxsId> > map)
|
||||||
// Only delete entries in mIdsNotPresent that can actually be performed.
|
* to make request to nes per peer ID
|
||||||
|
* Only delete entries in mIdsNotPresent that can actually be performed, or
|
||||||
|
* that have empty peer list */
|
||||||
|
|
||||||
for(cit = mIdsNotPresent.begin(); cit != mIdsNotPresent.end();)
|
for(cit = mIdsNotPresent.begin(); cit != mIdsNotPresent.end();)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_IDS
|
Dbg2() << __PRETTY_FUNCTION__ << " Processing missing key RsGxsId: "
|
||||||
std::cerr << "p3IdService::requestIdsFromNet() Id not found, deferring for net request: " << cit->first << std::endl;
|
<< cit->first << std::endl;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
const RsGxsId& gxsId = cit->first;
|
||||||
const std::list<RsPeerId>& peers = cit->second;
|
const std::list<RsPeerId>& peers = cit->second;
|
||||||
std::list<RsPeerId>::const_iterator cit2;
|
std::list<RsPeerId>::const_iterator cit2;
|
||||||
|
|
||||||
bool request_can_proceed = false ;
|
bool request_can_proceed = false ;
|
||||||
|
|
||||||
for(cit2 = peers.begin(); cit2 != peers.end(); ++cit2)
|
for(cit2 = peers.begin(); cit2 != peers.end(); ++cit2)
|
||||||
if(rsPeers->isOnline(*cit2) || mNes->isDistantPeer(*cit2)) // make sure that the peer in online, so that we know that the request has some chance to succeed.
|
|
||||||
{
|
{
|
||||||
requests[*cit2].push_back(cit->first);
|
const RsPeerId& peer = *cit2;
|
||||||
|
|
||||||
|
if(rsPeers->isOnline(peer) || mNes->isDistantPeer(peer))
|
||||||
|
{
|
||||||
|
/* make sure that the peer in online, so that we know that the
|
||||||
|
* request has some chance to succeed.*/
|
||||||
|
requests[peer].push_back(cit->first);
|
||||||
request_can_proceed = true ;
|
request_can_proceed = true ;
|
||||||
#ifdef DEBUG_IDS
|
|
||||||
std::cerr << " will ask ID " << cit->first << " to peer ID " << *cit2 << std::endl;
|
Dbg2() << __PRETTY_FUNCTION__ << " Moving missing key RsGxsId:"
|
||||||
#endif
|
<< gxsId << " to peer: " << peer << " requests queue"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(request_can_proceed || peers.empty())
|
const bool noPeersFound = peers.empty();
|
||||||
|
if(noPeersFound)
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " No peers supplied to request "
|
||||||
|
<< "RsGxsId: " << gxsId << " dropping." << std::endl;
|
||||||
|
|
||||||
|
if(request_can_proceed || noPeersFound)
|
||||||
{
|
{
|
||||||
std::map<RsGxsId, std::list<RsPeerId> >::iterator tmp(cit);
|
std::map<RsGxsId, std::list<RsPeerId> >::iterator tmp(cit);
|
||||||
++tmp;
|
++tmp;
|
||||||
@ -2967,26 +2975,28 @@ void p3IdService::requestIdsFromNet()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_IDS
|
RsInfo() << __PRETTY_FUNCTION__ << " no online peers among supplied"
|
||||||
std::cerr << "(EE) no online peers among supply list in ID request for groupId " << cit->first << ". Keeping it until peers show up."<< std::endl;
|
<< " list in request for RsGxsId: " << gxsId
|
||||||
#endif
|
<< ". Keeping it until peers show up."<< std::endl;
|
||||||
++cit;
|
++cit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::map<RsPeerId, std::list<RsGxsId> >::const_iterator cit2(requests.begin()); cit2 != requests.end(); ++cit2)
|
for( std::map<RsPeerId, std::list<RsGxsId> >::const_iterator cit2(
|
||||||
|
requests.begin() ); cit2 != requests.end(); ++cit2 )
|
||||||
{
|
{
|
||||||
std::list<RsGxsId>::const_iterator gxs_id_it = cit2->second.begin();
|
const RsPeerId& peer = cit2->first;
|
||||||
std::list<RsGxsGroupId> grpIds;
|
std::list<RsGxsGroupId> grpIds;
|
||||||
for(; gxs_id_it != cit2->second.end(); ++gxs_id_it)
|
for( std::list<RsGxsId>::const_iterator gxs_id_it = cit2->second.begin();
|
||||||
|
gxs_id_it != cit2->second.end(); ++gxs_id_it )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_IDS
|
Dbg2() << __PRETTY_FUNCTION__ << " passing RsGxsId: " << *gxs_id_it
|
||||||
std::cerr << " asking ID " << *gxs_id_it << " to peer ID " << cit2->first << std::endl;
|
<< " request for peer: " << peer
|
||||||
#endif
|
<< " to RsNetworkExchangeService " << std::endl;
|
||||||
grpIds.push_back(RsGxsGroupId(*gxs_id_it));
|
grpIds.push_back(RsGxsGroupId(*gxs_id_it));
|
||||||
}
|
}
|
||||||
|
|
||||||
mNes->requestGrp(grpIds, cit2->first);
|
mNes->requestGrp(grpIds, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4699,12 +4709,10 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel*
|
|||||||
case GXSID_EVENT_REQUEST_IDS:
|
case GXSID_EVENT_REQUEST_IDS:
|
||||||
requestIdsFromNet();
|
requestIdsFromNet();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* error */
|
RsErr() << __PRETTY_FUNCTION__ << " Unknown Event Type: "
|
||||||
std::cerr << "p3IdService::handle_event() Unknown Event Type: " << event_type;
|
<< event_type << std::endl;
|
||||||
std::cerr << std::endl;
|
print_stacktrace();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,10 @@ public:
|
|||||||
RsGxsId* id = nullptr);
|
RsGxsId* id = nullptr);
|
||||||
|
|
||||||
/// @see RsIdentity
|
/// @see RsIdentity
|
||||||
bool requestIdentity(const RsGxsId& id) override;
|
bool requestIdentity(
|
||||||
|
const RsGxsId& id,
|
||||||
|
const std::vector<RsPeerId>& peers = std::vector<RsPeerId>()
|
||||||
|
) override;
|
||||||
|
|
||||||
/**************** RsGixsReputation Implementation ****************/
|
/**************** RsGixsReputation Implementation ****************/
|
||||||
|
|
||||||
@ -494,7 +497,7 @@ private:
|
|||||||
|
|
||||||
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
|
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
|
||||||
|
|
||||||
std::map<RsPgpId, PGPFingerprintType> mPgpFingerprintMap;
|
std::map<RsPgpId, RsPgpFingerprint> mPgpFingerprintMap;
|
||||||
std::list<RsGxsIdGroup> mGroupsToProcess;
|
std::list<RsGxsIdGroup> mGroupsToProcess;
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -633,5 +636,5 @@ private:
|
|||||||
bool mAutoAddFriendsIdentitiesAsContacts;
|
bool mAutoAddFriendsIdentitiesAsContacts;
|
||||||
uint32_t mMaxKeepKeysBanned;
|
uint32_t mMaxKeepKeysBanned;
|
||||||
|
|
||||||
RS_SET_CONTEXT_DEBUG_LEVEL(1)
|
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
||||||
};
|
};
|
||||||
|
@ -2134,8 +2134,7 @@ bool p3MsgService::receiveGxsTransMail( const RsGxsId& authorId,
|
|||||||
|
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(recentlyReceivedMutex);
|
RS_STACK_MUTEX(recentlyReceivedMutex);
|
||||||
if( mRecentlyReceivedMessageHashes.find(hash) !=
|
if( mRecentlyReceivedMessageHashes.find(hash) != mRecentlyReceivedMessageHashes.end() )
|
||||||
mRecentlyReceivedMessageHashes.end() )
|
|
||||||
{
|
{
|
||||||
RsInfo() << __PRETTY_FUNCTION__ << " (II) receiving "
|
RsInfo() << __PRETTY_FUNCTION__ << " (II) receiving "
|
||||||
<< "message of hash " << hash << " more than once. "
|
<< "message of hash " << hash << " more than once. "
|
||||||
@ -2143,14 +2142,12 @@ bool p3MsgService::receiveGxsTransMail( const RsGxsId& authorId,
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mRecentlyReceivedMessageHashes[hash] =
|
mRecentlyReceivedMessageHashes[hash] = static_cast<uint32_t>(time(nullptr));
|
||||||
static_cast<uint32_t>(time(nullptr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
|
|
||||||
RsItem *item = _serialiser->deserialise(
|
RsItem *item = _serialiser->deserialise( const_cast<uint8_t*>(data), &dataSize );
|
||||||
const_cast<uint8_t*>(data), &dataSize );
|
|
||||||
RsMsgItem *msg_item = dynamic_cast<RsMsgItem*>(item);
|
RsMsgItem *msg_item = dynamic_cast<RsMsgItem*>(item);
|
||||||
|
|
||||||
if(msg_item)
|
if(msg_item)
|
||||||
|
@ -112,7 +112,7 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
// It could be taken a step further and directly request these msgs for an update.
|
// It could be taken a step further and directly request these msgs for an update.
|
||||||
addGroupForProcessing(mit->first);
|
addGroupForProcessing(mit->first);
|
||||||
|
|
||||||
if (rsEvents && msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW)
|
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
||||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
|
@ -100,23 +100,43 @@ RsEventsHandlerId_t RsEventsService::generateUniqueHandlerId_unlocked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RsEventsService::registerEventsHandler(
|
bool RsEventsService::registerEventsHandler(
|
||||||
|
RsEventType eventType,
|
||||||
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
||||||
RsEventsHandlerId_t& hId )
|
RsEventsHandlerId_t& hId )
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mHandlerMapMtx);
|
RS_STACK_MUTEX(mHandlerMapMtx);
|
||||||
if(!hId) hId = generateUniqueHandlerId_unlocked();
|
|
||||||
mHandlerMap[hId] = multiCallback;
|
if( (int)eventType > mHandlerMaps.size() + 10)
|
||||||
|
{
|
||||||
|
RsErr() << "Cannot register an event handler for an event type larger than 10 plus the max pre-defined event (value passed was " << (int)eventType << " whereas max is " << (int)RsEventType::MAX << ")" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (int)eventType >= mHandlerMaps.size())
|
||||||
|
mHandlerMaps.resize( (int)eventType +1 );
|
||||||
|
|
||||||
|
if(!hId)
|
||||||
|
hId = generateUniqueHandlerId_unlocked();
|
||||||
|
|
||||||
|
mHandlerMaps[(int)eventType][hId] = multiCallback;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsEventsService::unregisterEventsHandler(RsEventsHandlerId_t hId)
|
bool RsEventsService::unregisterEventsHandler(RsEventsHandlerId_t hId)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mHandlerMapMtx);
|
RS_STACK_MUTEX(mHandlerMapMtx);
|
||||||
auto it = mHandlerMap.find(hId);
|
|
||||||
if(it == mHandlerMap.end()) return false;
|
for(uint32_t i=0;i<mHandlerMaps.size();++i)
|
||||||
mHandlerMap.erase(it);
|
{
|
||||||
|
auto it = mHandlerMaps[i].find(hId);
|
||||||
|
if(it != mHandlerMaps[i].end())
|
||||||
|
{
|
||||||
|
mHandlerMaps[i].erase(it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RsEventsService::threadTick()
|
void RsEventsService::threadTick()
|
||||||
{
|
{
|
||||||
@ -156,23 +176,25 @@ void RsEventsService::handleEvent(std::shared_ptr<const RsEvent> event)
|
|||||||
{
|
{
|
||||||
std::function<void(std::shared_ptr<const RsEvent>)> mCallback;
|
std::function<void(std::shared_ptr<const RsEvent>)> mCallback;
|
||||||
|
|
||||||
mHandlerMapMtx.lock();
|
uint32_t event_type_index = static_cast<uint32_t>(event->mType);
|
||||||
auto cbpt = mHandlerMap.begin();
|
|
||||||
mHandlerMapMtx.unlock();
|
|
||||||
|
|
||||||
getHandlerFromMapLock:
|
|
||||||
mHandlerMapMtx.lock();
|
|
||||||
if(cbpt != mHandlerMap.end())
|
|
||||||
{
|
{
|
||||||
mCallback = cbpt->second;
|
RS_STACK_MUTEX(mHandlerMapMtx); /* LOCKED AREA */
|
||||||
++cbpt;
|
|
||||||
}
|
|
||||||
mHandlerMapMtx.unlock();
|
|
||||||
|
|
||||||
if(mCallback)
|
if(event_type_index >= mHandlerMaps.size() || event_type_index < 1)
|
||||||
{
|
{
|
||||||
mCallback(event); // It is relevant that this happens outside mutex
|
RsErr() << "Cannot handle an event of type " << event_type_index << ": out of scope!" << std::endl;
|
||||||
mCallback = std::function<void(std::shared_ptr<const RsEvent>)>(nullptr);
|
return;
|
||||||
goto getHandlerFromMapLock;
|
}
|
||||||
|
|
||||||
|
// Call all clients that registered a callback for this event type
|
||||||
|
|
||||||
|
for(auto cbit: mHandlerMaps[event_type_index])
|
||||||
|
cbit.second(event);
|
||||||
|
|
||||||
|
// Also call all clients that registered with NONE, meaning that they expect all events
|
||||||
|
|
||||||
|
for(auto cbit: mHandlerMaps[static_cast<uint32_t>(RsEventType::NONE)])
|
||||||
|
cbit.second(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ class RsEventsService :
|
|||||||
public:
|
public:
|
||||||
RsEventsService():
|
RsEventsService():
|
||||||
mHandlerMapMtx("RsEventsService::mHandlerMapMtx"), mLastHandlerId(1),
|
mHandlerMapMtx("RsEventsService::mHandlerMapMtx"), mLastHandlerId(1),
|
||||||
|
mHandlerMaps(static_cast<int>(RsEventType::MAX)),
|
||||||
mEventQueueMtx("RsEventsService::mEventQueueMtx") {}
|
mEventQueueMtx("RsEventsService::mEventQueueMtx") {}
|
||||||
|
|
||||||
/// @see RsEvents
|
/// @see RsEvents
|
||||||
@ -54,6 +55,7 @@ public:
|
|||||||
|
|
||||||
/// @see RsEvents
|
/// @see RsEvents
|
||||||
bool registerEventsHandler(
|
bool registerEventsHandler(
|
||||||
|
RsEventType eventType,
|
||||||
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
||||||
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
|
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
|
||||||
) override;
|
) override;
|
||||||
@ -64,9 +66,11 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
RsMutex mHandlerMapMtx;
|
RsMutex mHandlerMapMtx;
|
||||||
RsEventsHandlerId_t mLastHandlerId;
|
RsEventsHandlerId_t mLastHandlerId;
|
||||||
|
|
||||||
|
std::vector<
|
||||||
std::map<
|
std::map<
|
||||||
RsEventsHandlerId_t,
|
RsEventsHandlerId_t,
|
||||||
std::function<void(std::shared_ptr<const RsEvent>)> > mHandlerMap;
|
std::function<void(std::shared_ptr<const RsEvent>)> > > mHandlerMaps;
|
||||||
|
|
||||||
RsMutex mEventQueueMtx;
|
RsMutex mEventQueueMtx;
|
||||||
std::deque< std::shared_ptr<const RsEvent> > mEventQueue;
|
std::deque< std::shared_ptr<const RsEvent> > mEventQueue;
|
||||||
|
@ -137,7 +137,7 @@ static int tou_socket_read(BIO *b, char *out, int outl)
|
|||||||
|
|
||||||
int ret=0;
|
int ret=0;
|
||||||
|
|
||||||
if (!out)
|
if (out)
|
||||||
{
|
{
|
||||||
clear_tou_socket_error(BIO_get_fd(b,NULL));
|
clear_tou_socket_error(BIO_get_fd(b,NULL));
|
||||||
/* call tou library */
|
/* call tou library */
|
||||||
|
@ -1886,11 +1886,15 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
|
|||||||
// because there is not too much file hashes to be active at a time,
|
// because there is not too much file hashes to be active at a time,
|
||||||
// and this mostly prevents from sending the hash back in the tunnel.
|
// and this mostly prevents from sending the hash back in the tunnel.
|
||||||
|
|
||||||
bool found = false ;
|
#ifdef P3TURTLE_DEBUG
|
||||||
|
bool ext_found = false ;
|
||||||
|
#endif
|
||||||
for(std::map<TurtleFileHash,TurtleHashInfo>::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it)
|
for(std::map<TurtleFileHash,TurtleHashInfo>::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it)
|
||||||
if(it->second.last_request == item->request_id)
|
if(it->second.last_request == item->request_id)
|
||||||
{
|
{
|
||||||
found = true ;
|
#ifdef P3TURTLE_DEBUG
|
||||||
|
ext_found = true ;
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
// add the tunnel uniquely
|
// add the tunnel uniquely
|
||||||
@ -1917,7 +1921,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef P3TURTLE_DEBUG
|
#ifdef P3TURTLE_DEBUG
|
||||||
if(!found)
|
if(!ext_found)
|
||||||
std::cerr << "p3turtle: error. Could not find hash that emmitted tunnel request " << reinterpret_cast<void*>(item->tunnel_id) << std::endl ;
|
std::cerr << "p3turtle: error. Could not find hash that emmitted tunnel request " << reinterpret_cast<void*>(item->tunnel_id) << std::endl ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -207,14 +207,13 @@ bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest)
|
|||||||
|
|
||||||
bool is_alphanumeric(char c)
|
bool is_alphanumeric(char c)
|
||||||
{
|
{
|
||||||
return (c>='0' && c<'9') || (c>='a' && c<='z') || (c>='A' && c<='Z') ;
|
return (c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_alphanumeric(const std::string& s)
|
bool is_alphanumeric(const std::string& s)
|
||||||
{
|
{
|
||||||
for( uint32_t i=0; i < s.size(); ++i)
|
for( uint32_t i=0; i < s.size(); ++i)
|
||||||
if(!is_alphanumeric(s[i]))
|
if(!is_alphanumeric(s[i])) return false;
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ int RS_pthread_setname_np(pthread_t __target_thread, const char *__buf) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsThread::RsThread() : mHasStopped(true), mShouldStop(false)
|
void RsThread::resetTid()
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS_SYS
|
#ifdef WINDOWS_SYS
|
||||||
memset (&mTid, 0, sizeof(mTid));
|
memset (&mTid, 0, sizeof(mTid));
|
||||||
@ -94,6 +94,9 @@ RsThread::RsThread() : mHasStopped(true), mShouldStop(false)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RsThread::RsThread() : mHasStopped(true), mShouldStop(false), mLastTid()
|
||||||
|
{ resetTid(); }
|
||||||
|
|
||||||
bool RsThread::isRunning() { return !mHasStopped; }
|
bool RsThread::isRunning() { return !mHasStopped; }
|
||||||
|
|
||||||
bool RsThread::shouldStop() { return mShouldStop; }
|
bool RsThread::shouldStop() { return mShouldStop; }
|
||||||
@ -102,13 +105,13 @@ void RsThread::askForStop()
|
|||||||
{
|
{
|
||||||
/* Call onStopRequested() only once even if askForStop() is called multiple
|
/* Call onStopRequested() only once even if askForStop() is called multiple
|
||||||
* times */
|
* times */
|
||||||
if(!mShouldStop.exchange(true))
|
if(!mShouldStop.exchange(true)) onStopRequested();
|
||||||
RsThread::async([&](){ onStopRequested(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsThread::wrapRun()
|
void RsThread::wrapRun()
|
||||||
{
|
{
|
||||||
run();
|
run();
|
||||||
|
resetTid();
|
||||||
mHasStopped = true;
|
mHasStopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +125,8 @@ void RsThread::fullstop()
|
|||||||
RsErr() << __PRETTY_FUNCTION__ << " called by same thread. This should "
|
RsErr() << __PRETTY_FUNCTION__ << " called by same thread. This should "
|
||||||
<< "never happen! this: " << static_cast<void*>(this)
|
<< "never happen! this: " << static_cast<void*>(this)
|
||||||
<< std::hex << ", callerTid: " << callerTid
|
<< std::hex << ", callerTid: " << callerTid
|
||||||
<< ", mTid: " << mTid << std::dec << std::endl;
|
<< ", mTid: " << mTid << std::dec
|
||||||
|
<< ", mFullName: " << mFullName << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -134,9 +138,9 @@ void RsThread::fullstop()
|
|||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
++i;
|
++i;
|
||||||
if(!(i%5))
|
if(!(i%5))
|
||||||
RsInfo() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed"
|
RsDbg() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed"
|
||||||
<< " waiting for thread: " << mTid << " " << mFullName
|
<< " waiting for thread: " << std::hex << mLastTid
|
||||||
<< " to stop" << std::endl;
|
<< std::dec << " " << mFullName << " to stop" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +162,9 @@ bool RsThread::start(const std::string& threadName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Store an extra copy of thread id for debugging */
|
||||||
|
mLastTid = mTid;
|
||||||
|
|
||||||
/* Store thread full name as PThread is not able to keep it entirely */
|
/* Store thread full name as PThread is not able to keep it entirely */
|
||||||
mFullName = threadName;
|
mFullName = threadName;
|
||||||
|
|
||||||
@ -266,10 +273,10 @@ double RsStackMutex::getCurrentTS()
|
|||||||
|
|
||||||
RsThread::~RsThread()
|
RsThread::~RsThread()
|
||||||
{
|
{
|
||||||
if(isRunning())
|
if(!mHasStopped)
|
||||||
{
|
{
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mTid << " "
|
RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mLastTid
|
||||||
<< mFullName << " that is still "
|
<< " " << mFullName << " that is still "
|
||||||
<< "running! Something seems very wrong here and RetroShare is "
|
<< "running! Something seems very wrong here and RetroShare is "
|
||||||
<< "likely to crash because of this." << std::endl;
|
<< "likely to crash because of this." << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
@ -264,9 +264,19 @@ private:
|
|||||||
|
|
||||||
/// Store the id of the corresponding pthread
|
/// Store the id of the corresponding pthread
|
||||||
pthread_t mTid;
|
pthread_t mTid;
|
||||||
|
void resetTid();
|
||||||
|
|
||||||
/// Store thread full name
|
/** Store thread full name for debugging because PThread is limited to 15
|
||||||
|
* char thread names */
|
||||||
std::string mFullName;
|
std::string mFullName;
|
||||||
|
|
||||||
|
/** Store a copy of thread id which is never reset to 0 after initialization
|
||||||
|
* due to RsThread functioning. After RsThread initialization this member is
|
||||||
|
* only re-written with a new tread id in start(...).
|
||||||
|
* This is useful for debugging because mTid is reset at the end of wrapRun
|
||||||
|
* and that might happens concurrently (or just before) a debug message
|
||||||
|
* being printed, thus causing the debug message to print a mangled value.*/
|
||||||
|
pthread_t mLastTid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,8 +47,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void removeItem();
|
void toggle() override;
|
||||||
void toggle();
|
|
||||||
|
|
||||||
void readAndClearItem();
|
void readAndClearItem();
|
||||||
void copyLink();
|
void copyLink();
|
||||||
@ -61,9 +60,7 @@ private:
|
|||||||
|
|
||||||
RsFeedReader *mFeedReader;
|
RsFeedReader *mFeedReader;
|
||||||
FeedReaderNotify *mNotify;
|
FeedReaderNotify *mNotify;
|
||||||
FeedHolder *mParent;
|
|
||||||
|
|
||||||
std::string mFeedId;
|
|
||||||
std::string mMsgId;
|
std::string mMsgId;
|
||||||
QString mLink;
|
QString mLink;
|
||||||
|
|
||||||
|
@ -72,8 +72,21 @@ static NewsFeed *instance = NULL;
|
|||||||
/** Constructor */
|
/** Constructor */
|
||||||
NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed)
|
NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed)
|
||||||
{
|
{
|
||||||
mEventHandlerId =0; // needed to force intialization by registerEventsHandler()
|
mEventTypes = {
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { handleEvent(event); }, mEventHandlerId );
|
RsEventType::AUTHSSL_CONNECTION_AUTENTICATION,
|
||||||
|
RsEventType::PEER_CONNECTION ,
|
||||||
|
RsEventType::GXS_CIRCLES ,
|
||||||
|
RsEventType::GXS_CHANNELS ,
|
||||||
|
RsEventType::GXS_FORUMS ,
|
||||||
|
RsEventType::GXS_POSTED ,
|
||||||
|
RsEventType::MAIL_STATUS
|
||||||
|
};
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<mEventTypes.size();++i)
|
||||||
|
{
|
||||||
|
mEventHandlerIds.push_back(0); // needed to force intialization by registerEventsHandler()
|
||||||
|
rsEvents->registerEventsHandler(mEventTypes[i], [this](std::shared_ptr<const RsEvent> event) { handleEvent(event); }, mEventHandlerIds.back() );
|
||||||
|
}
|
||||||
|
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -117,7 +130,8 @@ QString hlp_str = tr(
|
|||||||
|
|
||||||
NewsFeed::~NewsFeed()
|
NewsFeed::~NewsFeed()
|
||||||
{
|
{
|
||||||
rsEvents->unregisterEventsHandler(mEventHandlerId);
|
for(uint32_t i=0;i<mEventHandlerIds.size();++i)
|
||||||
|
rsEvents->unregisterEventsHandler(mEventHandlerIds[i]);
|
||||||
|
|
||||||
// save settings
|
// save settings
|
||||||
processSettings(false);
|
processSettings(false);
|
||||||
@ -188,10 +202,10 @@ void NewsFeed::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
|||||||
handleForumEvent(event);
|
handleForumEvent(event);
|
||||||
|
|
||||||
if(event->mType == RsEventType::GXS_POSTED && (flags & RS_FEED_TYPE_POSTED))
|
if(event->mType == RsEventType::GXS_POSTED && (flags & RS_FEED_TYPE_POSTED))
|
||||||
handleMailEvent(event);
|
|
||||||
|
|
||||||
if(event->mType == RsEventType::MAIL_STATUS_CHANGE && (flags & RS_FEED_TYPE_MSG))
|
|
||||||
handlePostedEvent(event);
|
handlePostedEvent(event);
|
||||||
|
|
||||||
|
if(event->mType == RsEventType::MAIL_STATUS && (flags & RS_FEED_TYPE_MSG))
|
||||||
|
handleMailEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewsFeed::handleMailEvent(std::shared_ptr<const RsEvent> event)
|
void NewsFeed::handleMailEvent(std::shared_ptr<const RsEvent> event)
|
||||||
@ -200,6 +214,7 @@ void NewsFeed::handleMailEvent(std::shared_ptr<const RsEvent> event)
|
|||||||
dynamic_cast<const RsMailStatusEvent*>(event.get());
|
dynamic_cast<const RsMailStatusEvent*>(event.get());
|
||||||
if(!pe) return;
|
if(!pe) return;
|
||||||
|
|
||||||
|
|
||||||
switch(pe->mMailStatusEventCode)
|
switch(pe->mMailStatusEventCode)
|
||||||
{
|
{
|
||||||
case RsMailStatusEventCode::NEW_MESSAGE:
|
case RsMailStatusEventCode::NEW_MESSAGE:
|
||||||
@ -480,14 +495,10 @@ void NewsFeed::addFeedItemIfUnique(FeedItem *item, bool replace)
|
|||||||
|
|
||||||
void NewsFeed::remUniqueFeedItem(FeedItem *item)
|
void NewsFeed::remUniqueFeedItem(FeedItem *item)
|
||||||
{
|
{
|
||||||
FeedItem *feedItem = ui->feedWidget->findFeedItem(item->uniqueIdentifier());
|
//FeedItem *feedItem = ui->feedWidget->findFeedItem(item->uniqueIdentifier());
|
||||||
|
|
||||||
if (feedItem)
|
ui->feedWidget->removeFeedItem(item);
|
||||||
{
|
|
||||||
delete item;
|
delete item;
|
||||||
|
|
||||||
ui->feedWidget->removeFeedItem(feedItem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FeedHolder Functions (for FeedItem functionality) */
|
/* FeedHolder Functions (for FeedItem functionality) */
|
||||||
@ -496,7 +507,7 @@ QScrollArea *NewsFeed::getScrollArea()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewsFeed::deleteFeedItem(QWidget *item, uint32_t /*type*/)
|
void NewsFeed::deleteFeedItem(FeedItem *item, uint32_t /*type*/)
|
||||||
{
|
{
|
||||||
#ifdef NEWS_DEBUG
|
#ifdef NEWS_DEBUG
|
||||||
std::cerr << "NewsFeed::deleteFeedItem()";
|
std::cerr << "NewsFeed::deleteFeedItem()";
|
||||||
@ -504,6 +515,7 @@ void NewsFeed::deleteFeedItem(QWidget *item, uint32_t /*type*/)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
|
ui->feedWidget->removeFeedItem(item);
|
||||||
item->close ();
|
item->close ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ public:
|
|||||||
|
|
||||||
/* FeedHolder Functions (for FeedItem functionality) */
|
/* FeedHolder Functions (for FeedItem functionality) */
|
||||||
virtual QScrollArea *getScrollArea();
|
virtual QScrollArea *getScrollArea();
|
||||||
virtual void deleteFeedItem(QWidget *item, uint32_t type);
|
virtual void deleteFeedItem(FeedItem *item, uint32_t type);
|
||||||
virtual void openChat(const RsPeerId& peerId);
|
virtual void openChat(const RsPeerId& peerId);
|
||||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title);
|
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title);
|
||||||
|
|
||||||
@ -118,7 +118,8 @@ private:
|
|||||||
/* UI - from Designer */
|
/* UI - from Designer */
|
||||||
Ui::NewsFeed *ui;
|
Ui::NewsFeed *ui;
|
||||||
|
|
||||||
RsEventsHandlerId_t mEventHandlerId;
|
std::vector<RsEventsHandlerId_t> mEventHandlerIds;
|
||||||
|
std::vector<RsEventType> mEventTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,17 +51,8 @@ PhotoView::~PhotoView()
|
|||||||
|
|
||||||
void PhotoView::setPixmap(const QPixmap& pixmap)
|
void PhotoView::setPixmap(const QPixmap& pixmap)
|
||||||
{
|
{
|
||||||
QPixmap sqpixmap;
|
|
||||||
if(pixmap.width() > 800 ){
|
|
||||||
QPixmap sqpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
ui->photoLabel->setPixmap(sqpixmap);
|
|
||||||
}else if (pixmap.height() > 600){
|
|
||||||
QPixmap sqpixmap = pixmap.scaled(480,640, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
ui->photoLabel->setPixmap(sqpixmap);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ui->photoLabel->setPixmap(pixmap);
|
ui->photoLabel->setPixmap(pixmap);
|
||||||
}
|
this->adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhotoView::setTitle(const QString& text)
|
void PhotoView::setTitle(const QString& text)
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>565</width>
|
<width>346</width>
|
||||||
<height>464</height>
|
<height>107</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -38,7 +38,7 @@
|
|||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
<widget class="QFrame" name="frame">
|
<widget class="QFrame" name="frame">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
@ -51,38 +51,12 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<spacer name="horizontalSpacer_2">
|
<widget class="AspectRatioPixmapLabel" name="photoLabel">
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="photoLabel">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
|
||||||
<spacer name="horizontalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -165,7 +139,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>398</width>
|
<width>0</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -207,9 +181,13 @@
|
|||||||
<header>gui/common/AvatarWidget.h</header>
|
<header>gui/common/AvatarWidget.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>AspectRatioPixmapLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>util/aspectratiopixmaplabel.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../icons.qrc"/>
|
|
||||||
<include location="Posted_images.qrc"/>
|
<include location="Posted_images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
const RsPostedPost &getPost() const;
|
const RsPostedPost &getPost() const;
|
||||||
RsPostedPost &post();
|
RsPostedPost &post();
|
||||||
|
|
||||||
uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + mMessageId.toStdString()); }
|
uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + messageId().toStdString()); }
|
||||||
protected:
|
protected:
|
||||||
/* FeedItem */
|
/* FeedItem */
|
||||||
virtual void doExpand(bool open);
|
virtual void doExpand(bool open);
|
||||||
@ -60,7 +60,7 @@ private slots:
|
|||||||
void makeDownVote();
|
void makeDownVote();
|
||||||
void readToggled(bool checked);
|
void readToggled(bool checked);
|
||||||
void readAndClearItem();
|
void readAndClearItem();
|
||||||
void toggle();
|
void toggle() override;
|
||||||
void copyMessageLink();
|
void copyMessageLink();
|
||||||
void toggleNotes();
|
void toggleNotes();
|
||||||
void viewPicture();
|
void viewPicture();
|
||||||
|
@ -168,8 +168,7 @@ QScrollArea *PostedListWidget::getScrollArea()
|
|||||||
return ui->scrollAreaCardView;
|
return ui->scrollAreaCardView;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
void PostedListWidget::deleteFeedItem(FeedItem *, uint32_t /*type*/)
|
||||||
void PostedListWidget::deleteFeedItem(QWidget */*item*/, uint32_t /*type*/)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_POSTED_LIST_WIDGET
|
#ifdef DEBUG_POSTED_LIST_WIDGET
|
||||||
std::cerr << "PostedListWidget::deleteFeedItem() Nah";
|
std::cerr << "PostedListWidget::deleteFeedItem() Nah";
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
|
|
||||||
/* FeedHolder */
|
/* FeedHolder */
|
||||||
virtual QScrollArea *getScrollArea();
|
virtual QScrollArea *getScrollArea();
|
||||||
virtual void deleteFeedItem(QWidget *item, uint32_t type);
|
virtual void deleteFeedItem(FeedItem *item, uint32_t type);
|
||||||
virtual void openChat(const RsPeerId& peerId);
|
virtual void openChat(const RsPeerId& peerId);
|
||||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title);
|
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title);
|
||||||
|
|
||||||
|
@ -390,13 +390,24 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
|
|||||||
// it can happen that a message is first added to the message history
|
// it can happen that a message is first added to the message history
|
||||||
// and later the gui receives the message through notify
|
// and later the gui receives the message through notify
|
||||||
// avoid this by not adding history entries if their age is < 2secs
|
// avoid this by not adding history entries if their age is < 2secs
|
||||||
if ((time(NULL)-2) <= historyIt->recvTime)
|
if (time(nullptr) <= historyIt->recvTime+2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
if (chatId.isLobbyId() || chatId.isDistantChatId())
|
if (chatId.isLobbyId() || chatId.isDistantChatId())
|
||||||
{
|
{
|
||||||
RsIdentityDetails details;
|
RsIdentityDetails details;
|
||||||
|
time_t start = time(nullptr);
|
||||||
|
while (!rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
if (time(nullptr)>start+2)
|
||||||
|
{
|
||||||
|
std::cerr << "ChatWidget History haven't found Id Details and have wait 1 sec for it." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
|
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
|
||||||
name = QString::fromUtf8(details.mNickname.c_str());
|
name = QString::fromUtf8(details.mNickname.c_str());
|
||||||
else
|
else
|
||||||
|
@ -178,7 +178,7 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent)
|
|||||||
ui->filterLineEdit->showFilterIcon();
|
ui->filterLineEdit->showFilterIcon();
|
||||||
|
|
||||||
mEventHandlerId=0; // forces initialization
|
mEventHandlerId=0; // forces initialization
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> e) { handleEvent(e); }, mEventHandlerId );
|
rsEvents->registerEventsHandler( RsEventType::PEER_CONNECTION, [this](std::shared_ptr<const RsEvent> e) { handleEvent(e); }, mEventHandlerId );
|
||||||
|
|
||||||
mModel = new RsFriendListModel();
|
mModel = new RsFriendListModel();
|
||||||
mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this);
|
mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this);
|
||||||
@ -257,15 +257,12 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NewFriendList::handleEvent(std::shared_ptr<const RsEvent> e)
|
void NewFriendList::handleEvent(std::shared_ptr<const RsEvent> e)
|
||||||
{
|
|
||||||
if(e->mType == RsEventType::PEER_CONNECTION)
|
|
||||||
{
|
{
|
||||||
// /!\ The function we're in is called from a different thread. It's very important
|
// /!\ The function we're in is called from a different thread. It's very important
|
||||||
// to use this trick in order to avoid data races.
|
// to use this trick in order to avoid data races.
|
||||||
|
|
||||||
RsQThreadUtils::postToObject( [=]() { forceUpdateDisplay() ; }, this ) ;
|
RsQThreadUtils::postToObject( [=]() { forceUpdateDisplay() ; }, this ) ;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NewFriendList::~NewFriendList()
|
NewFriendList::~NewFriendList()
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,6 @@ bool RSFeedWidget::eventFilter(QObject *object, QEvent *event)
|
|||||||
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
||||||
if (feedItem) {
|
if (feedItem) {
|
||||||
disconnectSignals(feedItem);
|
disconnectSignals(feedItem);
|
||||||
feedRemoved(feedItem);
|
|
||||||
delete(feedItem);
|
delete(feedItem);
|
||||||
}
|
}
|
||||||
delete(treeItem);
|
delete(treeItem);
|
||||||
@ -135,23 +134,19 @@ void RSFeedWidget::feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSFeedWidget::feedRemoved(FeedItem *feedItem)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSFeedWidget::feedsCleared()
|
void RSFeedWidget::feedsCleared()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSFeedWidget::connectSignals(FeedItem *feedItem)
|
void RSFeedWidget::connectSignals(FeedItem *feedItem)
|
||||||
{
|
{
|
||||||
connect(feedItem, SIGNAL(feedItemDestroyed(FeedItem*)), this, SLOT(feedItemDestroyed(FeedItem*)));
|
connect(feedItem, SIGNAL(feedItemNeedsClosing(qulonglong)), this, SLOT(feedItemDestroyed(qulonglong)));
|
||||||
connect(feedItem, SIGNAL(sizeChanged(FeedItem*)), this, SLOT(feedItemSizeChanged(FeedItem*)));
|
connect(feedItem, SIGNAL(sizeChanged(FeedItem*)), this, SLOT(feedItemSizeChanged(FeedItem*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSFeedWidget::disconnectSignals(FeedItem *feedItem)
|
void RSFeedWidget::disconnectSignals(FeedItem *feedItem)
|
||||||
{
|
{
|
||||||
disconnect(feedItem, SIGNAL(feedItemDestroyed(FeedItem*)), this, SLOT(feedItemDestroyed(FeedItem*)));
|
disconnect(feedItem, SIGNAL(feedItemNeedsClosing(qulonglong)), this, SLOT(feedItemDestroyed(qulonglong)));
|
||||||
disconnect(feedItem, SIGNAL(sizeChanged(FeedItem*)), this, SLOT(feedItemSizeChanged(FeedItem*)));
|
disconnect(feedItem, SIGNAL(sizeChanged(FeedItem*)), this, SLOT(feedItemSizeChanged(FeedItem*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,11 +379,10 @@ FeedItem *RSFeedWidget::feedItem(int index)
|
|||||||
|
|
||||||
void RSFeedWidget::removeFeedItem(FeedItem *feedItem)
|
void RSFeedWidget::removeFeedItem(FeedItem *feedItem)
|
||||||
{
|
{
|
||||||
if (!feedItem) {
|
if (!feedItem)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem->uniqueIdentifier());
|
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem);// WARNING: do not use the other function based on identifier here, because some items change their identifier when loading.
|
||||||
|
|
||||||
if (treeItem)
|
if (treeItem)
|
||||||
{
|
{
|
||||||
@ -396,11 +390,10 @@ void RSFeedWidget::removeFeedItem(FeedItem *feedItem)
|
|||||||
|
|
||||||
if(treeItem_index < 0)
|
if(treeItem_index < 0)
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) Cannot remove designated item \"" << feedItem->uniqueIdentifier() << "\": not found!" << std::endl;
|
std::cerr << "(EE) Cannot remove designated item \"" << (void*)feedItem << "\": not found!" << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
feedRemoved(feedItem);
|
|
||||||
disconnectSignals(feedItem);
|
disconnectSignals(feedItem);
|
||||||
|
|
||||||
delete ui->treeWidget->takeTopLevelItem(treeItem_index);
|
delete ui->treeWidget->takeTopLevelItem(treeItem_index);
|
||||||
@ -424,13 +417,12 @@ void RSFeedWidget::feedItemSizeChanged(FeedItem */*feedItem*/)
|
|||||||
ui->treeWidget->doItemsLayout();
|
ui->treeWidget->doItemsLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSFeedWidget::feedItemDestroyed(FeedItem *feedItem)
|
void RSFeedWidget::feedItemDestroyed(qulonglong id)
|
||||||
{
|
{
|
||||||
/* No need to disconnect when object will be destroyed */
|
/* No need to disconnect when object will be destroyed */
|
||||||
|
|
||||||
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem->uniqueIdentifier());
|
QTreeWidgetItem *treeItem = findTreeWidgetItem(id);
|
||||||
|
|
||||||
feedRemoved(feedItem);
|
|
||||||
if(treeItem)
|
if(treeItem)
|
||||||
delete(treeItem);
|
delete(treeItem);
|
||||||
|
|
||||||
@ -438,6 +430,26 @@ void RSFeedWidget::feedItemDestroyed(FeedItem *feedItem)
|
|||||||
emit feedCountChanged();
|
emit feedCountChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(const FeedItem *w)
|
||||||
|
{
|
||||||
|
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||||
|
QTreeWidgetItem *treeItem=NULL;
|
||||||
|
|
||||||
|
// this search could probably be automatised by giving the tree items the identifier as data for some specific role, then calling QTreeWidget::findItems()
|
||||||
|
#warning TODO
|
||||||
|
while (*it)
|
||||||
|
{
|
||||||
|
FeedItem *feedItem = feedItemFromTreeItem(*it);
|
||||||
|
|
||||||
|
if (feedItem == w)
|
||||||
|
return *it;
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(uint64_t identifier)
|
QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(uint64_t identifier)
|
||||||
{
|
{
|
||||||
QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER);
|
QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER);
|
||||||
@ -490,26 +502,20 @@ void RSFeedWidget::withAll(RSFeedWidgetCallbackFunction callback, void *data)
|
|||||||
|
|
||||||
FeedItem *RSFeedWidget::findFeedItem(uint64_t identifier)
|
FeedItem *RSFeedWidget::findFeedItem(uint64_t identifier)
|
||||||
{
|
{
|
||||||
QTreeWidgetItemIterator it(ui->treeWidget);
|
QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER);
|
||||||
QTreeWidgetItem *treeItem=NULL;
|
|
||||||
|
|
||||||
// this search could probably be automatised by giving the tree items the identifier as data for some specific role, then calling QTreeWidget::findItems()
|
if(list.empty())
|
||||||
#warning TODO
|
return nullptr;
|
||||||
while ((treeItem = *it) != NULL) {
|
else if(list.size() == 1)
|
||||||
++it;
|
return feedItemFromTreeItem(list.front());
|
||||||
|
else
|
||||||
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
{
|
||||||
if (!feedItem)
|
std::cerr << "(EE) More than a single item with identifier \"" << identifier << "\" in the feed tree widget. This shouldn't happen!" << std::endl;
|
||||||
continue;
|
return nullptr;
|
||||||
|
}
|
||||||
uint64_t id = feedItem->uniqueIdentifier();
|
|
||||||
|
|
||||||
if (id == identifier)
|
|
||||||
return feedItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSFeedWidget::selectedFeedItems(QList<FeedItem*> &feedItems)
|
void RSFeedWidget::selectedFeedItems(QList<FeedItem*> &feedItems)
|
||||||
{
|
{
|
||||||
|
@ -87,11 +87,10 @@ public slots:
|
|||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event);
|
bool eventFilter(QObject *object, QEvent *event);
|
||||||
virtual void feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem);
|
virtual void feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem);
|
||||||
virtual void feedRemoved(FeedItem *feedItem);
|
|
||||||
virtual void feedsCleared();
|
virtual void feedsCleared();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void feedItemDestroyed(FeedItem *feedItem);
|
void feedItemDestroyed(qulonglong id);
|
||||||
void feedItemSizeChanged(FeedItem *feedItem);
|
void feedItemSizeChanged(FeedItem *feedItem);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -99,6 +98,7 @@ private:
|
|||||||
void disconnectSignals(FeedItem *feedItem);
|
void disconnectSignals(FeedItem *feedItem);
|
||||||
FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem);
|
FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem);
|
||||||
QTreeWidgetItem *findTreeWidgetItem(uint64_t identifier);
|
QTreeWidgetItem *findTreeWidgetItem(uint64_t identifier);
|
||||||
|
QTreeWidgetItem *findTreeWidgetItem(const FeedItem *w);
|
||||||
void filterItems();
|
void filterItems();
|
||||||
void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem);
|
void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem);
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1139</width>
|
<width>600</width>
|
||||||
<height>1171</height>
|
<height>400</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
ChatMsgItem::ChatMsgItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, const std::string &message) :
|
ChatMsgItem::ChatMsgItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, const std::string &message) :
|
||||||
FeedItem(NULL), mParent(parent), mFeedId(feedId), mPeerId(peerId)
|
FeedItem(parent,feedId,NULL), mPeerId(peerId)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
@ -153,26 +153,6 @@ void ChatMsgItem::insertChat(const std::string &message)
|
|||||||
chatTextlabel->setText(formatMsg);
|
chatTextlabel->setText(formatMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatMsgItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "ChatMsgItem::removeItem()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mParent) {
|
|
||||||
mParent->lockLayout(this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
hide();
|
|
||||||
|
|
||||||
if (mParent) {
|
|
||||||
mParent->lockLayout(this, false);
|
|
||||||
|
|
||||||
mParent->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatMsgItem::gotoHome()
|
void ChatMsgItem::gotoHome()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ITEM
|
#ifdef DEBUG_ITEM
|
||||||
@ -191,7 +171,7 @@ void ChatMsgItem::sendMsg()
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mParent)
|
if (mFeedHolder)
|
||||||
{
|
{
|
||||||
|
|
||||||
MessageComposer *nMsgDialog = MessageComposer::newMsg();
|
MessageComposer *nMsgDialog = MessageComposer::newMsg();
|
||||||
@ -214,15 +194,15 @@ void ChatMsgItem::openChat()
|
|||||||
std::cerr << "ChatMsgItem::openChat()";
|
std::cerr << "ChatMsgItem::openChat()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (mParent)
|
if (mFeedHolder)
|
||||||
{
|
{
|
||||||
mParent->openChat(mPeerId);
|
mFeedHolder->openChat(mPeerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatMsgItem::togglequickmessage()
|
void ChatMsgItem::togglequickmessage()
|
||||||
{
|
{
|
||||||
mParent->lockLayout(this, true);
|
mFeedHolder->lockLayout(this, true);
|
||||||
|
|
||||||
if (messageFrame->isHidden())
|
if (messageFrame->isHidden())
|
||||||
{
|
{
|
||||||
@ -239,7 +219,7 @@ void ChatMsgItem::togglequickmessage()
|
|||||||
|
|
||||||
emit sizeChanged(this);
|
emit sizeChanged(this);
|
||||||
|
|
||||||
mParent->lockLayout(this, false);
|
mFeedHolder->lockLayout(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatMsgItem::sendMessage()
|
void ChatMsgItem::sendMessage()
|
||||||
|
@ -45,7 +45,6 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void gotoHome();
|
void gotoHome();
|
||||||
void removeItem();
|
|
||||||
|
|
||||||
void sendMsg();
|
void sendMsg();
|
||||||
void openChat();
|
void openChat();
|
||||||
@ -60,9 +59,6 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void insertChat(const std::string &message);
|
void insertChat(const std::string &message);
|
||||||
|
|
||||||
FeedHolder *mParent;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
|
|
||||||
RsPeerId mPeerId;
|
RsPeerId mPeerId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <retroshare/rsgxschannels.h> // WRONG ONE - BUT IT'LL DO FOR NOW.
|
#include <retroshare/rsgxschannels.h> // WRONG ONE - BUT IT'LL DO FOR NOW.
|
||||||
|
|
||||||
class QScrollArea;
|
class QScrollArea;
|
||||||
|
class FeedItem;
|
||||||
|
|
||||||
class FeedHolder
|
class FeedHolder
|
||||||
{
|
{
|
||||||
@ -34,7 +35,7 @@ public:
|
|||||||
FeedHolder();
|
FeedHolder();
|
||||||
|
|
||||||
virtual QScrollArea *getScrollArea() = 0;
|
virtual QScrollArea *getScrollArea() = 0;
|
||||||
virtual void deleteFeedItem(QWidget *item, uint32_t type) = 0;
|
virtual void deleteFeedItem(FeedItem *item, uint32_t type) = 0;
|
||||||
virtual void openChat(const RsPeerId& peerId) = 0;
|
virtual void openChat(const RsPeerId& peerId) = 0;
|
||||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title)=0;
|
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title)=0;
|
||||||
|
|
||||||
|
@ -20,17 +20,15 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "FeedItem.h"
|
#include "FeedItem.h"
|
||||||
|
#include "FeedHolder.h"
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
FeedItem::FeedItem(QWidget *parent) : QWidget(parent), mHash(0)
|
FeedItem::FeedItem(FeedHolder *fh, uint32_t feedId, QWidget *parent) : QWidget(parent), mHash(0),mFeedHolder(fh),mFeedId(feedId)
|
||||||
{
|
{
|
||||||
mWasExpanded = false;
|
mWasExpanded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedItem::~FeedItem()
|
FeedItem::~FeedItem() { }
|
||||||
{
|
|
||||||
emit feedItemDestroyed(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FeedItem::expand(bool open)
|
void FeedItem::expand(bool open)
|
||||||
{
|
{
|
||||||
@ -48,12 +46,28 @@ void FeedItem::expand(bool open)
|
|||||||
uint64_t FeedItem::hash_64bits(const std::string& s) const
|
uint64_t FeedItem::hash_64bits(const std::string& s) const
|
||||||
{
|
{
|
||||||
if(mHash == 0)
|
if(mHash == 0)
|
||||||
{
|
mHash = hash64(s);
|
||||||
mHash = 0x01110bbfa09;
|
|
||||||
|
|
||||||
for(uint32_t i=0;i<s.size();++i)
|
|
||||||
mHash = ~(((mHash << 31) ^ (mHash >> 3)) + s[i]*0x217898fbba7 + 0x0294379);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mHash;
|
return mHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t FeedItem::hash64(const std::string& s)
|
||||||
|
{
|
||||||
|
uint64_t hash = 0x01110bbfa09;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<s.size();++i)
|
||||||
|
hash = ~(((hash << 31) ^ (hash >> 3)) + s[i]*0x217898fbba7 + 0x0294379);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeedItem::removeItem()
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_ITEM
|
||||||
|
std::cerr << "MsgItem::removeItem()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mFeedHolder->deleteFeedItem(this,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -23,13 +23,15 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
class FeedHolder;
|
||||||
|
|
||||||
class FeedItem : public QWidget
|
class FeedItem : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Default Constructor */
|
/** Default Constructor */
|
||||||
FeedItem(QWidget *parent = 0);
|
FeedItem(FeedHolder *fh,uint32_t feedId,QWidget *parent = 0);
|
||||||
/** Default Destructor */
|
/** Default Destructor */
|
||||||
virtual ~FeedItem();
|
virtual ~FeedItem();
|
||||||
|
|
||||||
@ -42,14 +44,25 @@ public:
|
|||||||
* would contain the same information. It should therefore sumarise the data represented by the item.
|
* would contain the same information. It should therefore sumarise the data represented by the item.
|
||||||
*/
|
*/
|
||||||
virtual uint64_t uniqueIdentifier() const =0;
|
virtual uint64_t uniqueIdentifier() const =0;
|
||||||
|
|
||||||
|
static uint64_t hash64(const std::string& s);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void removeItem();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void doExpand(bool open) = 0;
|
virtual void doExpand(bool open) = 0;
|
||||||
virtual void expandFill(bool /*first*/) {}
|
virtual void expandFill(bool /*first*/) {}
|
||||||
|
|
||||||
|
virtual void toggle() {}
|
||||||
|
|
||||||
uint64_t hash_64bits(const std::string& s) const;
|
uint64_t hash_64bits(const std::string& s) const;
|
||||||
|
|
||||||
|
FeedHolder *mFeedHolder;
|
||||||
|
uint32_t mFeedId;
|
||||||
signals:
|
signals:
|
||||||
void sizeChanged(FeedItem *feedItem);
|
void sizeChanged(FeedItem *feedItem);
|
||||||
void feedItemDestroyed(FeedItem *feedItem);
|
void feedItemNeedsClosing(qulonglong);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mWasExpanded;
|
bool mWasExpanded;
|
||||||
|
@ -53,7 +53,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void toggle();
|
void toggle() override;
|
||||||
|
|
||||||
void subscribeChannel();
|
void subscribeChannel();
|
||||||
|
|
||||||
|
@ -46,12 +46,14 @@
|
|||||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
||||||
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate)
|
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate)
|
||||||
{
|
{
|
||||||
|
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
|
||||||
init(messageId,older_versions) ;
|
init(messageId,older_versions) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
||||||
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
|
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
|
||||||
{
|
{
|
||||||
|
mPost.mMeta.mMsgId.clear(); // security
|
||||||
init(post.mMeta.mMsgId,older_versions) ;
|
init(post.mMeta.mMsgId,older_versions) ;
|
||||||
mPost = post ;
|
mPost = post ;
|
||||||
}
|
}
|
||||||
@ -71,63 +73,9 @@ void GxsChannelPostItem::init(const RsGxsMessageId& messageId,const std::set<RsG
|
|||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
|
|
||||||
mLoaded = false ;
|
mLoaded = false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This code has been suspended because it adds more complexity than usefulness.
|
|
||||||
// It was used to load a channel post where the post item is already known.
|
|
||||||
|
|
||||||
#ifdef SUSPENDED
|
|
||||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, const RsGxsChannelPost &post, bool isHome, bool autoUpdate) :
|
|
||||||
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "GxsChannelPostItem::GxsChannelPostItem() Direct Load";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QVector<RsGxsMessageId> v;
|
|
||||||
bool self = false;
|
|
||||||
|
|
||||||
for(std::set<RsGxsMessageId>::const_iterator it(post.mOlderVersions.begin());it!=post.mOlderVersions.end();++it)
|
|
||||||
{
|
|
||||||
if(*it == post.mMeta.mMsgId)
|
|
||||||
self = true ;
|
|
||||||
|
|
||||||
v.push_back(*it) ;
|
|
||||||
}
|
|
||||||
if(!self)
|
|
||||||
v.push_back(post.mMeta.mMsgId);
|
|
||||||
|
|
||||||
setMessageVersions(v) ;
|
|
||||||
|
|
||||||
setup();
|
|
||||||
|
|
||||||
setGroup(group, false);
|
|
||||||
|
|
||||||
setPost(post,false);
|
|
||||||
mLoaded = false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate) :
|
|
||||||
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "GxsChannelPostItem::GxsChannelPostItem() Direct Load";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setup();
|
|
||||||
|
|
||||||
mLoaded = true ;
|
|
||||||
requestGroup();
|
|
||||||
setPost(post);
|
|
||||||
requestComment();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void GxsChannelPostItem::paintEvent(QPaintEvent *e)
|
void GxsChannelPostItem::paintEvent(QPaintEvent *e)
|
||||||
{
|
{
|
||||||
/* This method employs a trick to trigger a deferred loading. The post and group is requested only
|
/* This method employs a trick to trigger a deferred loading. The post and group is requested only
|
||||||
@ -168,7 +116,6 @@ void GxsChannelPostItem::setup()
|
|||||||
|
|
||||||
/* clear ui */
|
/* clear ui */
|
||||||
ui->titleLabel->setText(tr("Loading"));
|
ui->titleLabel->setText(tr("Loading"));
|
||||||
ui->subjectLabel->clear();
|
|
||||||
ui->datetimelabel->clear();
|
ui->datetimelabel->clear();
|
||||||
ui->filelabel->clear();
|
ui->filelabel->clear();
|
||||||
ui->newCommentLabel->hide();
|
ui->newCommentLabel->hide();
|
||||||
@ -207,7 +154,7 @@ void GxsChannelPostItem::setup()
|
|||||||
ui->warning_label->hide();
|
ui->warning_label->hide();
|
||||||
|
|
||||||
ui->titleLabel->setMinimumWidth(100);
|
ui->titleLabel->setMinimumWidth(100);
|
||||||
ui->subjectLabel->setMinimumWidth(100);
|
//ui->subjectLabel->setMinimumWidth(100);
|
||||||
ui->warning_label->setMinimumWidth(100);
|
ui->warning_label->setMinimumWidth(100);
|
||||||
|
|
||||||
ui->mainFrame->setProperty("new", false);
|
ui->mainFrame->setProperty("new", false);
|
||||||
@ -326,12 +273,14 @@ void GxsChannelPostItem::loadMessage(const uint32_t &token)
|
|||||||
|
|
||||||
if (posts.size() == 1)
|
if (posts.size() == 1)
|
||||||
{
|
{
|
||||||
|
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
|
||||||
setPost(posts[0]);
|
setPost(posts[0]);
|
||||||
}
|
}
|
||||||
else if (cmts.size() == 1)
|
else if (cmts.size() == 1)
|
||||||
{
|
{
|
||||||
RsGxsComment cmt = cmts[0];
|
RsGxsComment cmt = cmts[0];
|
||||||
|
|
||||||
|
std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
|
||||||
ui->newCommentLabel->show();
|
ui->newCommentLabel->show();
|
||||||
ui->commLabel->show();
|
ui->commLabel->show();
|
||||||
ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str()));
|
ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str()));
|
||||||
@ -428,7 +377,7 @@ void GxsChannelPostItem::fill()
|
|||||||
ui->titleLabel->setText(title);
|
ui->titleLabel->setText(title);
|
||||||
|
|
||||||
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName());
|
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName());
|
||||||
ui->subjectLabel->setText(msgLink.toHtml());
|
//ui->subjectLabel->setText(msgLink.toHtml());
|
||||||
|
|
||||||
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags))
|
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags))
|
||||||
{
|
{
|
||||||
@ -451,10 +400,10 @@ void GxsChannelPostItem::fill()
|
|||||||
/* subject */
|
/* subject */
|
||||||
ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str()));
|
ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str()));
|
||||||
|
|
||||||
uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->titleLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height());
|
//uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->titleLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height());
|
||||||
|
|
||||||
// fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy
|
// fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy
|
||||||
ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
//ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||||
|
|
||||||
//ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ;
|
//ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ;
|
||||||
|
|
||||||
@ -522,7 +471,13 @@ void GxsChannelPostItem::fill()
|
|||||||
voteDownButton->setEnabled(false);
|
voteDownButton->setEnabled(false);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
ui->msgFrame->setVisible(!mPost.mMsg.empty());
|
{
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml( QString::fromUtf8(mPost.mMsg.c_str()) );
|
||||||
|
|
||||||
|
ui->msgFrame->setVisible(doc.toPlainText().length() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (wasExpanded() || ui->expandFrame->isVisible()) {
|
if (wasExpanded() || ui->expandFrame->isVisible()) {
|
||||||
fillExpandFrame();
|
fillExpandFrame();
|
||||||
}
|
}
|
||||||
@ -531,7 +486,7 @@ void GxsChannelPostItem::fill()
|
|||||||
|
|
||||||
if ( (mPost.mCount != 0) || (mPost.mSize != 0) ) {
|
if ( (mPost.mCount != 0) || (mPost.mSize != 0) ) {
|
||||||
ui->filelabel->setVisible(true);
|
ui->filelabel->setVisible(true);
|
||||||
ui->filelabel->setText(QString("(%1 %2) %3").arg(mPost.mCount).arg(tr("Files")).arg(misc::friendlyUnit(mPost.mSize)));
|
ui->filelabel->setText(QString("(%1 %2) %3").arg(mPost.mCount).arg( (mPost.mCount > 1)?tr("Files"):tr("File")).arg(misc::friendlyUnit(mPost.mSize)));
|
||||||
} else {
|
} else {
|
||||||
ui->filelabel->setVisible(false);
|
ui->filelabel->setVisible(false);
|
||||||
}
|
}
|
||||||
@ -575,6 +530,7 @@ void GxsChannelPostItem::fill()
|
|||||||
void GxsChannelPostItem::fillExpandFrame()
|
void GxsChannelPostItem::fillExpandFrame()
|
||||||
{
|
{
|
||||||
ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GxsChannelPostItem::messageName()
|
QString GxsChannelPostItem::messageName()
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
//GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
|
//GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
|
||||||
virtual ~GxsChannelPostItem();
|
virtual ~GxsChannelPostItem();
|
||||||
|
|
||||||
uint64_t uniqueIdentifier() const override { hash_64bits("GxsChannelPostItem " + mPost.mMeta.mMsgId.toStdString()) ; }
|
uint64_t uniqueIdentifier() const override { hash_64bits("GxsChannelPostItem " + messageId().toStdString()) ; }
|
||||||
|
|
||||||
bool setGroup(const RsGxsChannelGroup &group, bool doFill = true);
|
bool setGroup(const RsGxsChannelGroup &group, bool doFill = true);
|
||||||
bool setPost(const RsGxsChannelPost &post, bool doFill = true);
|
bool setPost(const RsGxsChannelPost &post, bool doFill = true);
|
||||||
@ -66,6 +66,7 @@ public:
|
|||||||
|
|
||||||
bool isUnread() const ;
|
bool isUnread() const ;
|
||||||
|
|
||||||
|
static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { return hash64("GxsChannelPostItem " + msgid.toStdString()) ; }
|
||||||
protected:
|
protected:
|
||||||
void init(const RsGxsMessageId& messageId,const std::set<RsGxsMessageId>& older_versions);
|
void init(const RsGxsMessageId& messageId,const std::set<RsGxsMessageId>& older_versions);
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void toggle();
|
void toggle() override;
|
||||||
void readAndClearItem();
|
void readAndClearItem();
|
||||||
void download();
|
void download();
|
||||||
void play();
|
void play();
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1359</width>
|
<width>1433</width>
|
||||||
<height>342</height>
|
<height>541</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gxsChannelPostItem_GLayout">
|
<layout class="QGridLayout" name="gxsChannelPostItem_GLayout">
|
||||||
@ -49,10 +49,12 @@
|
|||||||
<layout class="QVBoxLayout" name="mainFrameVLayout">
|
<layout class="QVBoxLayout" name="mainFrameVLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="mainTopHLayout">
|
<layout class="QHBoxLayout" name="mainTopHLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="logoLabel">
|
<widget class="QLabel" name="logoLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
@ -71,6 +73,8 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="mainRTopVLayout">
|
<layout class="QVBoxLayout" name="mainRTopVLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -114,41 +118,18 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="subjectHLayout">
|
<widget class="QLabel" name="newLabel">
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="subjectLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">Short Description</string>
|
<string>New</string>
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="openExternalLinks">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="filelabel">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">fileLabel</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="subjectHLayout"/>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="warningHLayout">
|
<layout class="QHBoxLayout" name="warningHLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -234,13 +215,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="newLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>New</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="scoreLabel">
|
<widget class="QLabel" name="scoreLabel">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
@ -335,19 +309,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="copyLinkButton">
|
<widget class="QPushButton" name="copyLinkButton">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -368,6 +329,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="filelabel">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">fileLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="unsubscribeButton">
|
<widget class="QPushButton" name="unsubscribeButton">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -387,6 +358,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="expandButton">
|
<widget class="QPushButton" name="expandButton">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
|
|
||||||
GxsCircleItem::GxsCircleItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsCircleId &circleId, const RsGxsId &gxsId, const uint32_t type)
|
GxsCircleItem::GxsCircleItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsCircleId &circleId, const RsGxsId &gxsId, const uint32_t type)
|
||||||
:FeedItem(NULL), mFeedHolder(feedHolder), mFeedId(feedId), mType(type), mCircleId(circleId), mGxsId(gxsId)
|
:FeedItem(feedHolder,feedId,NULL), mType(type), mCircleId(circleId), mGxsId(gxsId)
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
@ -172,22 +172,6 @@ uint64_t GxsCircleItem::uniqueIdentifier() const
|
|||||||
return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString() + " " + QString::number(mType).toStdString());
|
return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString() + " " + QString::number(mType).toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsCircleItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "GxsCircleItem::removeItem()" << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mFeedHolder)
|
|
||||||
{
|
|
||||||
mFeedHolder->lockLayout(this, true);
|
|
||||||
hide();
|
|
||||||
mFeedHolder->lockLayout(this, false);
|
|
||||||
|
|
||||||
mFeedHolder->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GxsCircleItem::loadRequest(const TokenQueue * queue, const TokenRequest &req)
|
void GxsCircleItem::loadRequest(const TokenQueue * queue, const TokenRequest &req)
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
|
@ -65,9 +65,6 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
|
||||||
void removeItem();
|
|
||||||
|
|
||||||
void showCircleDetails();
|
void showCircleDetails();
|
||||||
void acceptCircleSubscription();
|
void acceptCircleSubscription();
|
||||||
void grantCircleMembership() ;
|
void grantCircleMembership() ;
|
||||||
@ -76,8 +73,6 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
FeedHolder *mFeedHolder;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
uint32_t mType;
|
uint32_t mType;
|
||||||
|
|
||||||
RsGxsCircleId mCircleId;
|
RsGxsCircleId mCircleId;
|
||||||
|
@ -158,7 +158,6 @@ void GxsForumGroupItem::fill()
|
|||||||
ui->clearButton->setEnabled(false);
|
ui->clearButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumGroupItem::toggle()
|
void GxsForumGroupItem::toggle()
|
||||||
{
|
{
|
||||||
expand(ui->expandFrame->isHidden());
|
expand(ui->expandFrame->isHidden());
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
/* FeedItem */
|
/* FeedItem */
|
||||||
virtual void doExpand(bool open);
|
virtual void doExpand(bool open);
|
||||||
|
void toggle() override;
|
||||||
|
|
||||||
/* GxsGroupFeedItem */
|
/* GxsGroupFeedItem */
|
||||||
virtual QString groupName();
|
virtual QString groupName();
|
||||||
@ -53,9 +54,6 @@ protected:
|
|||||||
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; }
|
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
|
||||||
void toggle();
|
|
||||||
|
|
||||||
void subscribeForum();
|
void subscribeForum();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
bool setGroup(const RsGxsForumGroup &group, bool doFill = true);
|
bool setGroup(const RsGxsForumGroup &group, bool doFill = true);
|
||||||
bool setMessage(const RsGxsForumMsg &msg, bool doFill = true);
|
bool setMessage(const RsGxsForumMsg &msg, bool doFill = true);
|
||||||
|
|
||||||
uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumMsgItem " + mMessage.mMeta.mMsgId.toStdString()) ; }
|
uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumMsgItem " + messageId().toStdString()) ; }
|
||||||
protected:
|
protected:
|
||||||
/* FeedItem */
|
/* FeedItem */
|
||||||
virtual void doExpand(bool open);
|
virtual void doExpand(bool open);
|
||||||
@ -67,7 +67,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void toggle();
|
void toggle() override;
|
||||||
void readAndClearItem();
|
void readAndClearItem();
|
||||||
|
|
||||||
void unsubscribeForum();
|
void unsubscribeForum();
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, bool isHome) :
|
MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, bool isHome) :
|
||||||
FeedItem(NULL), mParent(parent), mFeedId(feedId), mMsgId(msgId), mIsHome(isHome)
|
FeedItem(parent,feedId,NULL), mMsgId(msgId), mIsHome(isHome)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
@ -222,15 +222,10 @@ void MsgItem::updateItem()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MsgItem::toggle()
|
|
||||||
{
|
|
||||||
expand(expandFrame->isHidden());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MsgItem::doExpand(bool open)
|
void MsgItem::doExpand(bool open)
|
||||||
{
|
{
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, true);
|
mFeedHolder->lockLayout(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open)
|
if (open)
|
||||||
@ -252,8 +247,8 @@ void MsgItem::doExpand(bool open)
|
|||||||
|
|
||||||
emit sizeChanged(this);
|
emit sizeChanged(this);
|
||||||
|
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, false);
|
mFeedHolder->lockLayout(this, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,23 +261,6 @@ void MsgItem::expandFill(bool first)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MsgItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "MsgItem::removeItem()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mParent->lockLayout(this, true);
|
|
||||||
hide();
|
|
||||||
mParent->lockLayout(this, false);
|
|
||||||
|
|
||||||
if (mParent)
|
|
||||||
{
|
|
||||||
mParent->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MsgItem::gotoHome()
|
void MsgItem::gotoHome()
|
||||||
{
|
{
|
||||||
@ -315,7 +293,7 @@ void MsgItem::replyMsg()
|
|||||||
std::cerr << "MsgItem::replyMsg()";
|
std::cerr << "MsgItem::replyMsg()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (mParent)
|
if (mFeedHolder)
|
||||||
{
|
{
|
||||||
//mParent->openMsg(FEEDHOLDER_MSG_MESSAGE, mPeerId, mMsgId);
|
//mParent->openMsg(FEEDHOLDER_MSG_MESSAGE, mPeerId, mMsgId);
|
||||||
|
|
||||||
@ -339,6 +317,11 @@ void MsgItem::playMedia()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MsgItem::toggle()
|
||||||
|
{
|
||||||
|
expand(expandFrame->isHidden());
|
||||||
|
}
|
||||||
|
|
||||||
void MsgItem::checkMessageReadStatus()
|
void MsgItem::checkMessageReadStatus()
|
||||||
{
|
{
|
||||||
if (!mCloseOnRead) {
|
if (!mCloseOnRead) {
|
||||||
|
@ -50,7 +50,6 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void gotoHome();
|
void gotoHome();
|
||||||
void removeItem();
|
|
||||||
void toggle();
|
void toggle();
|
||||||
|
|
||||||
void playMedia();
|
void playMedia();
|
||||||
@ -62,9 +61,6 @@ private slots:
|
|||||||
void updateItem();
|
void updateItem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FeedHolder *mParent;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
|
|
||||||
std::string mMsgId;
|
std::string mMsgId;
|
||||||
QString mMsg;
|
QString mMsg;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
PeerItem::PeerItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, uint32_t type, bool isHome) :
|
PeerItem::PeerItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, uint32_t type, bool isHome) :
|
||||||
FeedItem(NULL), mParent(parent), mFeedId(feedId),
|
FeedItem(parent,feedId,NULL),
|
||||||
mPeerId(peerId), mType(type), mIsHome(isHome)
|
mPeerId(peerId), mType(type), mIsHome(isHome)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
@ -50,11 +50,11 @@ PeerItem::PeerItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId,
|
|||||||
sendmsgButton->setEnabled(false);
|
sendmsgButton->setEnabled(false);
|
||||||
|
|
||||||
/* general ones */
|
/* general ones */
|
||||||
connect( expandButton, SIGNAL( clicked( void ) ), this, SLOT( toggle ( void ) ) );
|
connect( expandButton, SIGNAL( clicked() ), this, SLOT( toggle() ) );
|
||||||
connect( clearButton, SIGNAL( clicked( void ) ), this, SLOT( removeItem ( void ) ) );
|
connect( clearButton, SIGNAL( clicked() ), this, SLOT( removeItem() ) );
|
||||||
|
|
||||||
/* specific ones */
|
/* specific ones */
|
||||||
connect( chatButton, SIGNAL( clicked( void ) ), this, SLOT( openChat ( void ) ) );
|
connect( chatButton, SIGNAL( clicked() ), this, SLOT( openChat() ) );
|
||||||
connect( sendmsgButton, SIGNAL( clicked() ), this, SLOT( sendMsg() ) );
|
connect( sendmsgButton, SIGNAL( clicked() ), this, SLOT( sendMsg() ) );
|
||||||
|
|
||||||
connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()), this, SLOT(updateItem()));
|
connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()), this, SLOT(updateItem()));
|
||||||
@ -225,7 +225,7 @@ void PeerItem::updateItem()
|
|||||||
/* slow Tick */
|
/* slow Tick */
|
||||||
int msec_rate = 10129;
|
int msec_rate = 10129;
|
||||||
|
|
||||||
QTimer::singleShot( msec_rate, this, SLOT(updateItem( void ) ));
|
QTimer::singleShot( msec_rate, this, SLOT(updateItem() ));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,8 +236,8 @@ void PeerItem::toggle()
|
|||||||
|
|
||||||
void PeerItem::doExpand(bool open)
|
void PeerItem::doExpand(bool open)
|
||||||
{
|
{
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, true);
|
mFeedHolder->lockLayout(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open)
|
if (open)
|
||||||
@ -255,25 +255,8 @@ void PeerItem::doExpand(bool open)
|
|||||||
|
|
||||||
emit sizeChanged(this);
|
emit sizeChanged(this);
|
||||||
|
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, false);
|
mFeedHolder->lockLayout(this, false);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PeerItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "PeerItem::removeItem()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mParent->lockLayout(this, true);
|
|
||||||
hide();
|
|
||||||
mParent->lockLayout(this, false);
|
|
||||||
|
|
||||||
if (mParent)
|
|
||||||
{
|
|
||||||
mParent->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,9 +304,9 @@ void PeerItem::openChat()
|
|||||||
std::cerr << "PeerItem::openChat()";
|
std::cerr << "PeerItem::openChat()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (mParent)
|
if (mFeedHolder)
|
||||||
{
|
{
|
||||||
mParent->openChat(mPeerId);
|
mFeedHolder->openChat(mPeerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void removeItem();
|
void toggle() override;
|
||||||
void toggle();
|
|
||||||
|
|
||||||
void addFriend();
|
void addFriend();
|
||||||
void removeFriend();
|
void removeFriend();
|
||||||
@ -63,8 +62,6 @@ private slots:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FeedHolder *mParent;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
|
|
||||||
RsPeerId mPeerId;
|
RsPeerId mPeerId;
|
||||||
uint32_t mType;
|
uint32_t mType;
|
||||||
|
@ -54,9 +54,7 @@ protected:
|
|||||||
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; }
|
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
void toggle() override;
|
||||||
void toggle();
|
|
||||||
|
|
||||||
void subscribePosted();
|
void subscribePosted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -40,14 +40,14 @@
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
SecurityIpItem::SecurityIpItem(FeedHolder *parent, const RsPeerId &sslId, const std::string &ipAddr, uint32_t result, uint32_t type, bool isTest) :
|
SecurityIpItem::SecurityIpItem(FeedHolder *parent, const RsPeerId &sslId, const std::string &ipAddr, uint32_t result, uint32_t type, bool isTest) :
|
||||||
FeedItem(NULL), mParent(parent), mType(type), mSslId(sslId), mIpAddr(ipAddr), mResult(result), mIsTest(isTest),
|
FeedItem(parent,0,NULL), mType(type), mSslId(sslId), mIpAddr(ipAddr), mResult(result), mIsTest(isTest),
|
||||||
ui(new(Ui::SecurityIpItem))
|
ui(new(Ui::SecurityIpItem))
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityIpItem::SecurityIpItem(FeedHolder *parent, const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported, uint32_t type, bool isTest) :
|
SecurityIpItem::SecurityIpItem(FeedHolder *parent, const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported, uint32_t type, bool isTest) :
|
||||||
FeedItem(NULL), mParent(parent), mType(type), mSslId(sslId), mIpAddr(ipAddr), mIpAddrReported(ipAddrReported), mResult(0), mIsTest(isTest),
|
FeedItem(parent,0,NULL), mType(type), mSslId(sslId), mIpAddr(ipAddr), mIpAddrReported(ipAddrReported), mResult(0), mIsTest(isTest),
|
||||||
ui(new(Ui::SecurityIpItem))
|
ui(new(Ui::SecurityIpItem))
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
@ -192,8 +192,8 @@ void SecurityIpItem::toggle()
|
|||||||
|
|
||||||
void SecurityIpItem::doExpand(bool open)
|
void SecurityIpItem::doExpand(bool open)
|
||||||
{
|
{
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, true);
|
mFeedHolder->lockLayout(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open)
|
if (open)
|
||||||
@ -211,25 +211,8 @@ void SecurityIpItem::doExpand(bool open)
|
|||||||
|
|
||||||
emit sizeChanged(this);
|
emit sizeChanged(this);
|
||||||
|
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, false);
|
mFeedHolder->lockLayout(this, false);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecurityIpItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "SecurityIpItem::removeItem()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mParent->lockLayout(this, true);
|
|
||||||
hide();
|
|
||||||
mParent->lockLayout(this, false);
|
|
||||||
|
|
||||||
if (mParent)
|
|
||||||
{
|
|
||||||
mParent->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,16 +54,12 @@ private:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void removeItem();
|
void toggle() override;
|
||||||
void toggle();
|
|
||||||
void peerDetails();
|
void peerDetails();
|
||||||
void updateItem();
|
void updateItem();
|
||||||
void banIpListChanged(const QString &ipAddress);
|
void banIpListChanged(const QString &ipAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FeedHolder *mParent;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
|
|
||||||
uint32_t mType;
|
uint32_t mType;
|
||||||
RsPeerId mSslId;
|
RsPeerId mSslId;
|
||||||
std::string mIpAddr;
|
std::string mIpAddr;
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
SecurityItem::SecurityItem(FeedHolder *parent, uint32_t feedId, const RsPgpId &gpgId, const RsPeerId &sslId, const std::string &sslCn, const std::string& ip_address,uint32_t type, bool isHome) :
|
SecurityItem::SecurityItem(FeedHolder *parent, uint32_t feedId, const RsPgpId &gpgId, const RsPeerId &sslId, const std::string &sslCn, const std::string& ip_address,uint32_t type, bool isHome) :
|
||||||
FeedItem(NULL), mParent(parent), mFeedId(feedId),
|
FeedItem(parent,feedId,NULL),
|
||||||
mGpgId(gpgId), mSslId(sslId), mSslCn(sslCn), mIP(ip_address), mType(type), mIsHome(isHome)
|
mGpgId(gpgId), mSslId(sslId), mSslCn(sslCn), mIP(ip_address), mType(type), mIsHome(isHome)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
@ -288,8 +288,8 @@ void SecurityItem::toggle()
|
|||||||
|
|
||||||
void SecurityItem::doExpand(bool open)
|
void SecurityItem::doExpand(bool open)
|
||||||
{
|
{
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, true);
|
mFeedHolder->lockLayout(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open)
|
if (open)
|
||||||
@ -307,25 +307,8 @@ void SecurityItem::doExpand(bool open)
|
|||||||
|
|
||||||
emit sizeChanged(this);
|
emit sizeChanged(this);
|
||||||
|
|
||||||
if (mParent) {
|
if (mFeedHolder) {
|
||||||
mParent->lockLayout(this, false);
|
mFeedHolder->lockLayout(this, false);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecurityItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "SecurityItem::removeItem()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mParent->lockLayout(this, true);
|
|
||||||
hide();
|
|
||||||
mParent->lockLayout(this, false);
|
|
||||||
|
|
||||||
if (mParent)
|
|
||||||
{
|
|
||||||
mParent->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,8 +396,8 @@ void SecurityItem::openChat()
|
|||||||
std::cerr << "SecurityItem::openChat()";
|
std::cerr << "SecurityItem::openChat()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (mParent)
|
if (mFeedHolder)
|
||||||
{
|
{
|
||||||
mParent->openChat(mSslId);
|
mFeedHolder->openChat(mSslId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
void removeItem();
|
void toggle() override;
|
||||||
void toggle();
|
|
||||||
|
|
||||||
void friendRequest();
|
void friendRequest();
|
||||||
void removeFriend();
|
void removeFriend();
|
||||||
@ -62,9 +61,6 @@ private slots:
|
|||||||
void updateItem();
|
void updateItem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FeedHolder *mParent;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
|
|
||||||
RsPgpId mGpgId;
|
RsPgpId mGpgId;
|
||||||
RsPeerId mSslId;
|
RsPeerId mSslId;
|
||||||
std::string mSslCn;
|
std::string mSslCn;
|
||||||
|
@ -46,8 +46,6 @@ void GxsFeedWidget::feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem)
|
|||||||
|
|
||||||
void GxsFeedWidget::feedRemoved(FeedItem *feedItem)
|
void GxsFeedWidget::feedRemoved(FeedItem *feedItem)
|
||||||
{
|
{
|
||||||
RSFeedWidget::feedRemoved(feedItem);
|
|
||||||
|
|
||||||
GxsFeedItem *gxsFeedItem = dynamic_cast<GxsFeedItem*>(feedItem);
|
GxsFeedItem *gxsFeedItem = dynamic_cast<GxsFeedItem*>(feedItem);
|
||||||
if (!gxsFeedItem) {
|
if (!gxsFeedItem) {
|
||||||
return;
|
return;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate) :
|
GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate) :
|
||||||
FeedItem(NULL)
|
FeedItem(feedHolder,feedId,NULL)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ITEM
|
#ifdef DEBUG_ITEM
|
||||||
std::cerr << "GxsGroupFeedItem::GxsGroupFeedItem()";
|
std::cerr << "GxsGroupFeedItem::GxsGroupFeedItem()";
|
||||||
@ -40,8 +40,6 @@ GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, cons
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* this are just generally useful for all children */
|
/* this are just generally useful for all children */
|
||||||
mFeedHolder = feedHolder;
|
|
||||||
mFeedId = feedId;
|
|
||||||
mIsHome = isHome;
|
mIsHome = isHome;
|
||||||
|
|
||||||
/* load data if we can */
|
/* load data if we can */
|
||||||
@ -93,27 +91,6 @@ bool GxsGroupFeedItem::initLoadQueue()
|
|||||||
return (mLoadQueue != NULL);
|
return (mLoadQueue != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsGroupFeedItem::removeItem()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "GxsGroupFeedItem::removeItem()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mFeedHolder)
|
|
||||||
{
|
|
||||||
mFeedHolder->lockLayout(this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
hide();
|
|
||||||
|
|
||||||
if (mFeedHolder)
|
|
||||||
{
|
|
||||||
mFeedHolder->lockLayout(this, false);
|
|
||||||
mFeedHolder->deleteFeedItem(this, mFeedId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GxsGroupFeedItem::unsubscribe()
|
void GxsGroupFeedItem::unsubscribe()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ITEM
|
#ifdef DEBUG_ITEM
|
||||||
|
@ -64,12 +64,9 @@ protected:
|
|||||||
protected slots:
|
protected slots:
|
||||||
void subscribe();
|
void subscribe();
|
||||||
void unsubscribe();
|
void unsubscribe();
|
||||||
void removeItem();
|
|
||||||
void copyGroupLink();
|
void copyGroupLink();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FeedHolder *mFeedHolder;
|
|
||||||
uint32_t mFeedId;
|
|
||||||
bool mIsHome;
|
bool mIsHome;
|
||||||
RsGxsIfaceHelper *mGxsIface;
|
RsGxsIfaceHelper *mGxsIface;
|
||||||
TokenQueue *mLoadQueue;
|
TokenQueue *mLoadQueue;
|
||||||
|
@ -52,12 +52,10 @@ GxsChannelDialog::GxsChannelDialog(QWidget *parent)
|
|||||||
{
|
{
|
||||||
mEventHandlerId = 0;
|
mEventHandlerId = 0;
|
||||||
// Needs to be asynced because this function is likely to be called by another thread!
|
// Needs to be asynced because this function is likely to be called by another thread!
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
rsEvents->registerEventsHandler(RsEventType::GXS_CHANNELS, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
{
|
|
||||||
if(event->mType == RsEventType::GXS_CHANNELS)
|
|
||||||
{
|
{
|
||||||
const RsGxsChannelEvent *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
|
const RsGxsChannelEvent *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
|
||||||
|
|
||||||
@ -72,7 +70,6 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> ev
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
GxsChannelDialog::~GxsChannelDialog()
|
GxsChannelDialog::~GxsChannelDialog()
|
||||||
{
|
{
|
||||||
|
@ -132,12 +132,10 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid
|
|||||||
mEventHandlerId = 0;
|
mEventHandlerId = 0;
|
||||||
// Needs to be asynced because this function is likely to be called by another thread!
|
// Needs to be asynced because this function is likely to be called by another thread!
|
||||||
|
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
rsEvents->registerEventsHandler(RsEventType::GXS_CHANNELS, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
{
|
|
||||||
if(event->mType == RsEventType::GXS_CHANNELS)
|
|
||||||
{
|
{
|
||||||
const RsGxsChannelEvent *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
|
const RsGxsChannelEvent *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
|
||||||
|
|
||||||
@ -157,7 +155,6 @@ void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr<const RsEven
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
GxsChannelPostsWidget::~GxsChannelPostsWidget()
|
GxsChannelPostsWidget::~GxsChannelPostsWidget()
|
||||||
{
|
{
|
||||||
@ -233,8 +230,12 @@ QScrollArea *GxsChannelPostsWidget::getScrollArea()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsChannelPostsWidget::deleteFeedItem(QWidget * /*item*/, uint32_t /*type*/)
|
void GxsChannelPostsWidget::deleteFeedItem(FeedItem *feedItem, uint32_t /*type*/)
|
||||||
{
|
{
|
||||||
|
if (!feedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ui->feedWidget->removeFeedItem(feedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/)
|
void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/)
|
||||||
@ -460,7 +461,7 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re
|
|||||||
|
|
||||||
if(!post.mMeta.mOrigMsgId.isNull())
|
if(!post.mMeta.mOrigMsgId.isNull())
|
||||||
{
|
{
|
||||||
FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(post.mMeta.mGroupId, post.mMeta.mOrigMsgId);
|
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(post.mMeta.mOrigMsgId)) ;
|
||||||
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
||||||
|
|
||||||
if(item)
|
if(item)
|
||||||
@ -476,7 +477,7 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re
|
|||||||
|
|
||||||
if (related)
|
if (related)
|
||||||
{
|
{
|
||||||
FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(post.mMeta.mGroupId, post.mMeta.mMsgId);
|
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(post.mMeta.mMsgId)) ;
|
||||||
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
||||||
}
|
}
|
||||||
if (item) {
|
if (item) {
|
||||||
@ -669,7 +670,7 @@ void GxsChannelPostsWidget::blank()
|
|||||||
|
|
||||||
bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId)
|
bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId)
|
||||||
{
|
{
|
||||||
FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(groupId(), msgId);
|
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(msgId));
|
||||||
if (!feedItem) {
|
if (!feedItem) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -718,17 +719,17 @@ void GxsChannelPostsWidget::toggleAutoDownload()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsQThreadUtils::postToObject( [=]()
|
// RsQThreadUtils::postToObject( [=]()
|
||||||
{
|
// {
|
||||||
/* Here it goes any code you want to be executed on the Qt Gui
|
// /* Here it goes any code you want to be executed on the Qt Gui
|
||||||
* thread, for example to update the data model with new information
|
// * thread, for example to update the data model with new information
|
||||||
* after a blocking call to RetroShare API complete, note that
|
// * after a blocking call to RetroShare API complete, note that
|
||||||
* Qt::QueuedConnection is important!
|
// * Qt::QueuedConnection is important!
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
|
// std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
|
||||||
<< "thread but was scheduled by async thread" << std::endl;
|
// << "thread but was scheduled by async thread" << std::endl;
|
||||||
}, this );
|
// }, this );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
/* FeedHolder */
|
/* FeedHolder */
|
||||||
virtual QScrollArea *getScrollArea();
|
virtual QScrollArea *getScrollArea();
|
||||||
virtual void deleteFeedItem(QWidget *item, uint32_t type);
|
virtual void deleteFeedItem(FeedItem *feedItem, uint32_t type);
|
||||||
virtual void openChat(const RsPeerId& peerId);
|
virtual void openChat(const RsPeerId& peerId);
|
||||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title);
|
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title);
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>880</width>
|
<width>977</width>
|
||||||
<height>557</height>
|
<height>628</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
@ -369,7 +369,7 @@
|
|||||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textInteractionFlags">
|
<property name="textInteractionFlags">
|
||||||
@ -525,7 +525,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="GxsFeedWidget" name="feedWidget" native="true">
|
<widget class="RSFeedWidget" name="feedWidget" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
@ -572,22 +572,22 @@ p, li { white-space: pre-wrap; }
|
|||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header location="global">gui/common/LineEditClear.h</header>
|
<header location="global">gui/common/LineEditClear.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>GxsFeedWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>gui/gxs/GxsFeedWidget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>GxsChannelFilesWidget</class>
|
<class>GxsChannelFilesWidget</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
<header>gui/gxschannels/GxsChannelFilesWidget.h</header>
|
<header>gui/gxschannels/GxsChannelFilesWidget.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>RSFeedWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>gui/common/RSFeedWidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -436,7 +436,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
mEventHandlerId = 0;
|
mEventHandlerId = 0;
|
||||||
// Needs to be asynced because this function is likely to be called by another thread!
|
// Needs to be asynced because this function is likely to be called by another thread!
|
||||||
|
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
rsEvents->registerEventsHandler(RsEventType::GXS_FORUMS, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
void GxsForumThreadWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
|
@ -45,7 +45,7 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent)
|
|||||||
mEventHandlerId = 0;
|
mEventHandlerId = 0;
|
||||||
// Needs to be asynced because this function is likely to be called by another thread!
|
// Needs to be asynced because this function is likely to be called by another thread!
|
||||||
|
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
rsEvents->registerEventsHandler(RsEventType::GXS_FORUMS, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include "AspectRatioPixmapLabel.h"
|
#include "AspectRatioPixmapLabel.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) :
|
AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) :
|
||||||
QLabel(parent)
|
QLabel(parent)
|
||||||
@ -30,7 +31,8 @@ AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) :
|
|||||||
void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p)
|
void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p)
|
||||||
{
|
{
|
||||||
pix = p;
|
pix = p;
|
||||||
QLabel::setPixmap(scaledPixmap());
|
QLabel::setPixmap(pix);
|
||||||
|
//std::cout << "Information size: " << pix.width() << 'x' << pix.height() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AspectRatioPixmapLabel::heightForWidth( int width ) const
|
int AspectRatioPixmapLabel::heightForWidth( int width ) const
|
||||||
@ -40,8 +42,7 @@ int AspectRatioPixmapLabel::heightForWidth( int width ) const
|
|||||||
|
|
||||||
QSize AspectRatioPixmapLabel::sizeHint() const
|
QSize AspectRatioPixmapLabel::sizeHint() const
|
||||||
{
|
{
|
||||||
int w = this->width();
|
return QSize(pix.width(), pix.height());
|
||||||
return QSize( w, heightForWidth(w) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap AspectRatioPixmapLabel::scaledPixmap() const
|
QPixmap AspectRatioPixmapLabel::scaledPixmap() const
|
||||||
@ -53,4 +54,6 @@ void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e)
|
|||||||
{
|
{
|
||||||
if(!pix.isNull())
|
if(!pix.isNull())
|
||||||
QLabel::setPixmap(scaledPixmap());
|
QLabel::setPixmap(scaledPixmap());
|
||||||
|
QLabel::resizeEvent(e);
|
||||||
|
//std::cout << "Information resized: " << e->oldSize().width() << 'x' << e->oldSize().height() << " to " << e->size().width() << 'x' << e->size().height() << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -29,13 +29,14 @@ class AspectRatioPixmapLabel : public QLabel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AspectRatioPixmapLabel(QWidget *parent = 0);
|
explicit AspectRatioPixmapLabel(QWidget *parent = nullptr);
|
||||||
virtual int heightForWidth( int width ) const;
|
virtual int heightForWidth( int width ) const override;
|
||||||
virtual QSize sizeHint() const;
|
virtual QSize sizeHint() const override;
|
||||||
QPixmap scaledPixmap() const;
|
QPixmap scaledPixmap() const;
|
||||||
public slots:
|
public slots:
|
||||||
void setPixmap ( const QPixmap & );
|
void setPixmap ( const QPixmap & );
|
||||||
void resizeEvent(QResizeEvent *);
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
private:
|
private:
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
};
|
};
|
||||||
|
@ -39,11 +39,9 @@ RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl) :
|
|||||||
{
|
{
|
||||||
mEventHandlerId = 0; // forces initialization in registerEventsHandler()
|
mEventHandlerId = 0; // forces initialization in registerEventsHandler()
|
||||||
|
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event)
|
rsEvents->registerEventsHandler(RsEventType::GXS_CHANGES, [this](std::shared_ptr<const RsEvent> event)
|
||||||
{
|
{
|
||||||
if(event->mType == RsEventType::GXS_CHANGES)
|
|
||||||
onChangesReceived(*dynamic_cast<const RsGxsChanges*>(event.get()));
|
onChangesReceived(*dynamic_cast<const RsGxsChanges*>(event.get()));
|
||||||
|
|
||||||
}, mEventHandlerId );
|
}, mEventHandlerId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user