diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index d918b2264..81dd097e0 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -111,6 +111,7 @@ p3discovery2::p3discovery2( if(rsEvents) rsEvents->registerEventsHandler( + RsEventType::GOSSIP_DISCOVERY, [this](std::shared_ptr event) { rsEventsHandler(*event); @@ -1345,8 +1346,3 @@ void p3discovery2::rsEventsHandler(const RsEvent& event) // // /* ignore other operations */ // } - -// (cyril) do we still need this?? -RsGossipDiscoveryFriendInviteReceivedEvent::RsGossipDiscoveryFriendInviteReceivedEvent(const std::string& invite) : - RsEvent(RsEventType::GOSSIP_DISCOVERY_INVITE_RECEIVED), - mInvite(invite) {} diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc index a3df21c82..302465414 100644 --- a/libretroshare/src/grouter/grouteritems.cc +++ b/libretroshare/src/grouter/grouteritems.cc @@ -108,7 +108,7 @@ void RsGRouterGenericDataItem::serial_process(RsGenericSerializer::SerializeJob RsTypeSerializer::serial_process(j,ctx,signature,"signature") ; RsTypeSerializer::serial_process(j,ctx,duplication_factor,"duplication_factor") ; - RsTypeSerializer::serial_process(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. { @@ -128,7 +128,7 @@ void RsGRouterGenericDataItem::serial_process(RsGenericSerializer::SerializeJob void RsGRouterSignedReceiptItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) { RsTypeSerializer::serial_process (j,ctx,routing_id,"routing_id") ; - RsTypeSerializer::serial_process (j,ctx,flags,"flags") ; + RS_SERIAL_PROCESS(flags); RsTypeSerializer::serial_process (j,ctx,destination_key,"destination_key") ; RsTypeSerializer::serial_process (j,ctx,service_id,"service_id") ; RsTypeSerializer::serial_process (j,ctx,data_hash,"data_hash") ; @@ -269,3 +269,4 @@ RsGRouterSignedReceiptItem *RsGRouterSignedReceiptItem::duplicate() const return item ; } +RsGRouterAbstractMsgItem::~RsGRouterAbstractMsgItem() = default; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h index baf7c0576..14957ab87 100644 --- a/libretroshare/src/grouter/grouteritems.h +++ b/libretroshare/src/grouter/grouteritems.h @@ -27,7 +27,7 @@ #include "serialiser/rstlvkeys.h" #include "rsitems/rsserviceids.h" #include "retroshare/rstypes.h" - +#include "retroshare/rsflags.h" #include "retroshare/rsgrouter.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 // both signing and checking. -class RsGRouterAbstractMsgItem: public RsGRouterItem +enum class RsGRouterItemFlags : uint32_t { -public: - explicit RsGRouterAbstractMsgItem(uint8_t pkt_subtype) : RsGRouterItem(pkt_subtype), flags(0) {} - virtual ~RsGRouterAbstractMsgItem() {} + NONE = 0x0, + ENCRYPTED = 0x1, + 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 ; GRouterKeyId destination_key ; GRouterServiceId service_id ; 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: - RsGRouterGenericDataItem() : RsGRouterAbstractMsgItem(RS_PKT_SUBTYPE_GROUTER_DATA), data_size(0), data_bytes(NULL), duplication_factor(0) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER) ; } - virtual ~RsGRouterGenericDataItem() { clear() ; } +public: + RsGRouterGenericDataItem(): + RsGRouterAbstractMsgItem(RS_PKT_SUBTYPE_GROUTER_DATA), + data_size(0), data_bytes(nullptr), duplication_factor(0) + { setPriorityLevel(QOS_PRIORITY_RS_GROUTER); } - virtual void clear() - { - free(data_bytes); - data_bytes=NULL; - } + virtual ~RsGRouterGenericDataItem() { clear(); } + virtual void clear() + { + free(data_bytes); + 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 - // - uint32_t data_size ; - uint8_t *data_bytes; - uint32_t duplication_factor ; // number of duplicates allowed. Should be capped at each de-serialise operation! + /// packet data + uint32_t data_size; + uint8_t* data_bytes; + + /** number of duplicates allowed. Should be capped at each de-serialise + * operation! */ + uint32_t duplication_factor; }; class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index 6dbc444aa..7fe2cc19e 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -178,7 +178,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////// #include -#include +#include #include "util/rsrandom.h" #include "util/rsprint.h" @@ -188,7 +188,7 @@ #include "turtle/p3turtle.h" #include "gxs/rsgixs.h" #include "retroshare/rspeers.h" - +#include "util/cxx17retrocompat.h" #include "p3grouter.h" #include "grouteritems.h" #include "groutertypes.h" @@ -200,25 +200,18 @@ const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ; -p3GRouter::p3GRouter(p3ServiceControl *sc, RsGixs *is) - : p3Service(), p3Config(), mServiceControl(sc), mTurtle(NULL), mGixs(is), grMtx("GRouter") -{ - addSerialType(new RsGRouterSerialiser()) ; - - _last_autowash_time = 0 ; - _last_debug_output_time = 0 ; - _last_config_changed = 0 ; - _last_matrix_update_time = 0 ; - _debug_enabled = true ; - - _random_salt = RSRandom::random_u64() ; - - _changed = false ; -} +p3GRouter::p3GRouter(p3ServiceControl *sc, RsGixs *is) : + p3Service(), p3Config(), mServiceControl(sc), mTurtle(nullptr), mGixs(is), + grMtx("GRouter"), _changed(false), _debug_enabled(true), + _last_autowash_time(0), _last_matrix_update_time(0), + _last_debug_output_time(0), _last_config_changed(0), + _random_salt(RsRandom::random_u64()), + mMissingKeyQueueMtx("GRouterMissingKeyQueue") +{ addSerialType(new RsGRouterSerialiser()); } int p3GRouter::tick() { - rstime_t now = time(NULL) ; + rstime_t now = time(nullptr); // Sort incoming service data // @@ -242,6 +235,41 @@ int p3GRouter::tick() // 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 // if(now > _last_matrix_update_time + RS_GROUTER_MATRIX_UPDATE_PERIOD) @@ -325,14 +353,12 @@ bool p3GRouter::unregisterKey(const RsGxsId& key_id,const GRouterServiceId& sid) Sha1CheckSum hash = makeTunnelHash(key_id,sid) ; - std::map::iterator it = _owned_key_ids.find(hash) ; - + const auto it = _owned_key_ids.find(hash); if(it == _owned_key_ids.end()) { -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::unregisterKey(): key " << key_id << " not found." << std::endl; -#endif - return false ; + RsErr() << __PRETTY_FUNCTION__ << " key " << key_id << " not found." + << std::endl; + return false; } #ifdef GROUTER_DEBUG @@ -479,7 +505,7 @@ void p3GRouter::handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem *t #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 std::cerr << "p3GRouter::receiveTurtleData() " << std::endl; @@ -1304,7 +1330,7 @@ bool p3GRouter::locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTr void p3GRouter::autoWash() { bool items_deleted = false ; - rstime_t now = time(NULL) ; + rstime_t now = time(nullptr); std::map > failed_msgs ; @@ -1395,9 +1421,22 @@ void p3GRouter::autoWash() it->second.clear() ; _incoming_data_pipes.erase(it) ; it = ittmp ; - } - else - ++it ; + } + else + ++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. @@ -1492,27 +1531,31 @@ void p3GRouter::handleIncoming() RsGRouterAbstractMsgItem *item = _incoming_items.front() ; _incoming_items.pop_front() ; - RsGRouterGenericDataItem *generic_data_item ; - RsGRouterSignedReceiptItem *receipt_item ; - - if(NULL != (generic_data_item = dynamic_cast(item))) - handleIncomingDataItem(generic_data_item) ; - else if(NULL != (receipt_item = dynamic_cast(item))) - handleIncomingReceiptItem(receipt_item) ; - else - std::cerr << "Item has unknown type (not data nor signed receipt). Dropping!" << std::endl; - + handleIncomingItem(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(item))) + handleIncomingDataItem(generic_data_item) ; + else if(NULL != (receipt_item = dynamic_cast(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 ; #ifdef GROUTER_DEBUG std::cerr << "Handling incoming signed receipt item." << std::endl; std::cerr << "Item content:" << std::endl; - receipt_item->print(std::cerr,2) ; + const_cast(receipt_item)->print(std::cerr,2) ; #endif RsGxsId signer_id ; @@ -1613,17 +1656,17 @@ void p3GRouter::handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_it 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); - uint32_t signed_data_size = signature_serializer.size(data_item); + uint32_t signed_data_size = signature_serializer.size(const_cast(data_item)); uint32_t total_size = signed_data_size + data_item->signature.TlvSize() ; RsTemporaryMemory mem(total_size) ; uint32_t offset = 0 ; uint32_t tmp_size = total_size ; - signature_serializer.serialise(data_item,mem,&tmp_size) ; + signature_serializer.serialise(const_cast(data_item),mem,&tmp_size) ; if(tmp_size != signed_data_size) 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) ; } -void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item) +void p3GRouter::handleIncomingDataItem(const RsGRouterGenericDataItem *data_item) { #ifdef GROUTER_DEBUG std::cerr << "Handling incoming data item. " << std::endl; std::cerr << "Item content:" << std::endl; - data_item->print(std::cerr,2) ; + const_cast(data_item)->print(std::cerr,2) ; #endif // we find 3 things: @@ -1654,15 +1697,15 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item) // Send a receipt? if A && B // Notify client? if A && !C // - GRouterClientService *client = NULL ; + GRouterClientService *clientService = NULL ; GRouterServiceId service_id = data_item->service_id ; RsGRouterSignedReceiptItem *receipt_item = NULL ; Sha1CheckSum item_hash = computeDataItemHash(data_item) ; bool item_is_already_known = false ; - bool item_is_for_us = 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. #ifdef GROUTER_DEBUG @@ -1671,23 +1714,12 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item) { RS_STACK_MUTEX(grMtx) ; - std::map::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 - item_is_for_us = _owned_key_ids.find( makeTunnelHash(data_item->destination_key,service_id) ) != _owned_key_ids.end() ; - #ifdef GROUTER_DEBUG std::cerr << " item is " << (item_is_for_us?"":"not") << " for us." << std::endl; #endif - std::map::iterator it = _pending_messages.find(data_item->routing_id) ; + auto it = _pending_messages.find(data_item->routing_id) ; if(it != _pending_messages.end()) { @@ -1709,26 +1741,56 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item) std::cerr << " item is new." << std::endl; #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(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. // 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) { + // 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 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 // 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->routing_id = data_item->routing_id ; 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 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(item_is_for_us && !item_is_already_known) + if(clientService && !item_is_already_known) { // compute the hash before decryption. @@ -1835,9 +1903,9 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item) std::cerr << " notyfying client." << std::endl; #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_size = 0 ; @@ -1871,7 +1939,7 @@ bool p3GRouter::locked_getLocallyRegisteredClientFromServiceId(const GRouterServ 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) ; #ifdef GROUTER_DEBUG @@ -1890,7 +1958,7 @@ bool p3GRouter::registerClientService(const GRouterServiceId& id,GRouterClientSe 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 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) ; item->data_bytes = encrypted_data ; item->data_size = encrypted_size ; - item->flags |= RS_GROUTER_DATA_FLAGS_ENCRYPTED ; + item->flags |= RsGRouterItemFlags::ENCRYPTED; #ifdef GROUTER_DEBUG std::cerr << " Encrypted size = " << encrypted_size << std::endl; @@ -1926,7 +1994,7 @@ return true ; } bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item) { - assert(item->flags & RS_GROUTER_DATA_FLAGS_ENCRYPTED) ; + assert(!!(item->flags & RsGRouterItemFlags::ENCRYPTED)); #ifdef GROUTER_DEBUG std::cerr << " decrypting data for key " << item->destination_key << std::endl; @@ -1952,7 +2020,7 @@ bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item) free(item->data_bytes) ; item->data_bytes = decrypted_data ; item->data_size = decrypted_size ; - item->flags &= ~RS_GROUTER_DATA_FLAGS_ENCRYPTED ; + item->flags &= ~RsGRouterItemFlags::ENCRYPTED; return true ; } @@ -2010,56 +2078,62 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi 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 { if( rsReputations->overallReputationLevel(item->signature.keyId) == RsReputationLevel::LOCALLY_NEGATIVE ) - { - std::cerr << "(WW) received global router message from banned identity " << item->signature.keyId << ". Rejecting the message." << std::endl; - return false ; - } - RsGRouterSerialiser signature_serializer(RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER); + { + RsWarn() << __PRETTY_FUNCTION__ << " received global router " + << "message from banned identity " << item->signature.keyId + << ". Rejecting the message." << std::endl; + return false; + } - uint32_t data_size = signature_serializer.size(item) ; - RsTemporaryMemory data(data_size) ; + RsGRouterSerialiser signature_serializer( + RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | + RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER ); + + uint32_t data_size = signature_serializer.size(const_cast(item)); // the const cast shouldn't be necessary if size() took a const. + RsTemporaryMemory data(data_size); if(data == NULL) throw std::runtime_error("Cannot allocate data.") ; - if(!signature_serializer.serialise(item,data,&data_size)) - throw std::runtime_error("Cannot serialise signed data.") ; + if(!signature_serializer.serialise(const_cast(item),data,&data_size)) + throw std::runtime_error("Cannot serialise signed data."); - RsIdentityUsage use(RS_SERVICE_TYPE_GROUTER,info) ; + RsIdentityUsage use(RS_SERVICE_TYPE_GROUTER,info); - if(!mGixs->validateData(data,data_size,item->signature,true,use, error_status)) - { - switch(error_status) - { - case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: - { - std::list peer_ids ; - 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; - - mGixs->requestKey(item->signature.keyId,peer_ids,use) ; // request the key around - } - break ; - case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/Corrupted/MITM?." << std::endl; - break ; - default: std::cerr << "(EE) Signature verification failed on GRouter message. Unknown error status: " << error_status << std::endl; - break ; - } - return false; - } + if(!mGixs->validateData( data, data_size, item->signature, true, use, error_status )) + { + switch(error_status) + { + case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: + { + std::list peer_ids; + peer_ids.push_back(item->PeerId()); - return true ; - } - catch(std::exception& e) - { - std::cerr << " signature verification failed. Error: " << e.what() << 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); + } + break; + case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: + RsWarn() << __PRETTY_FUNCTION__ << " Signature mismatch. " << "Spoofing/Corrupted/MITM?." << std::endl; + break; + default: + RsErr() << __PRETTY_FUNCTION__ << " Signature verification failed on GRouter message. Unknown error status: " << error_status << std::endl; + break; + } + return false; + } + + return true; + } + catch(std::exception& e) + { + RsErr() << __PRETTY_FUNCTION__ << " Failed. Error: " << e.what() << std::endl; return false ; } } @@ -2093,7 +2167,7 @@ bool p3GRouter::cancel(GRouterMsgPropagationId mid) return true ; } -bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& client_id,const uint8_t *data, uint32_t data_size,const RsGxsId& signing_id, GRouterMsgPropagationId &propagation_id) +bool p3GRouter::sendData( const RsGxsId& destination, const GRouterServiceId& client_id, const uint8_t* data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId&propagation_id ) { // std::cerr << "GRouter currently disabled." << std::endl; // 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->service_id = client_id ; 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. @@ -2204,8 +2278,12 @@ return true ; Sha1CheckSum p3GRouter::makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client) { - assert( destination.SIZE_IN_BYTES == 16) ; - assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ; + static_assert( RsGxsId::SIZE_IN_BYTES == 16, + "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] ; memcpy(bytes,destination.toByteArray(),16) ; diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h index fca320843..236c8b7a5 100644 --- a/libretroshare/src/grouter/p3grouter.h +++ b/libretroshare/src/grouter/p3grouter.h @@ -22,8 +22,8 @@ #pragma once #include -#include #include +#include #include "retroshare/rsgrouter.h" #include "retroshare/rstypes.h" @@ -33,15 +33,13 @@ #include "turtle/turtleclientservice.h" #include "services/p3service.h" #include "pqi/p3cfgmgr.h" - +#include "util/rsdebug.h" #include "groutertypes.h" #include "groutermatrix.h" #include "grouteritems.h" // To be put in pqi/p3cfgmgr.h -// static const uint32_t CONFIG_TYPE_GROUTER = 0x0016 ; -static const uint32_t RS_GROUTER_DATA_FLAGS_ENCRYPTED = 0x0001 ; class p3LinkMgr ; class p3turtle ; @@ -126,7 +124,8 @@ public: // 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 // @@ -220,7 +219,7 @@ private: void handleLowLevelTransactionChunkItem(RsGRouterTransactionChunkItem *chunk_item); void handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem*) ; - static Sha1CheckSum computeDataItemHash(RsGRouterGenericDataItem *data_item); + static Sha1CheckSum computeDataItemHash(const RsGRouterGenericDataItem *data_item); std::ostream& grouter_debug() const { @@ -238,8 +237,9 @@ private: void handleIncoming() ; - void handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_item) ; - void handleIncomingDataItem(RsGRouterGenericDataItem *data_item) ; + void handleIncomingItem(const RsGRouterAbstractMsgItem *item); + void handleIncomingReceiptItem(const RsGRouterSignedReceiptItem *receipt_item) ; + void handleIncomingDataItem(const RsGRouterGenericDataItem *data_item) ; bool locked_getLocallyRegisteredClientFromServiceId(const GRouterServiceId& service_id,GRouterClientService *& client); @@ -252,7 +252,7 @@ private: // signs an item with the given key. 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 decryptDataItem(RsGRouterGenericDataItem *item) ; @@ -352,4 +352,23 @@ private: rstime_t _last_config_changed ; 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, 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) }; diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp index 08bb9ea49..70443bf5f 100644 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ b/libretroshare/src/jsonapi/jsonapi.cpp @@ -146,6 +146,7 @@ bool RsJsonApi::parseToken( JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), mService(std::make_shared()), + mServiceMutex("JsonApiServer restbed ptr"), mListeningPort(RsJsonApi::DEFAULT_PORT), mBindingAddress(RsJsonApi::DEFAULT_BINDING_ADDRESS) { @@ -223,7 +224,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), rsLoginHelper->attemptLogin(account, password); if( retval == RsInit::OK ) - authorizeUser(account.toStdString(),password); + authorizeUser(account.toStdString(), password); // serialize out parameters and return value to JSON { @@ -310,6 +311,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), registerHandler("/rsEvents/registerEventsHandler", [this](const std::shared_ptr session) { + const std::weak_ptr weakService(mService); const std::multimap headers { { "Connection", "keep-alive" }, @@ -319,7 +321,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), size_t reqSize = static_cast( session->get_request()->get_header("Content-Length", 0) ); - session->fetch( reqSize, [this]( + session->fetch( reqSize, [weakService]( const std::shared_ptr session, const rb::Bytes& body ) { @@ -329,12 +331,29 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), rsEvents, "rsEvents", cAns, session ) ) 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 weakSession(session); RsEventsHandlerId_t hId = rsEvents->generateUniqueHandlerId(); std::function)> multiCallback = - [this, weakSession, hId](std::shared_ptr event) + [weakSession, weakService, hId]( + std::shared_ptr 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(); 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); @@ -500,10 +519,10 @@ bool JsonApiServer::authorizeUser( return false; } - if(!librs::util::is_alphanumeric(passwd)) + if(passwd.empty()) { - RsErr() << __PRETTY_FUNCTION__ << " Password is not alphanumeric" - << std::endl; + RsWarn() << __PRETTY_FUNCTION__ << " Password is empty, are you sure " + << "this what you wanted?" << std::endl; return false; } @@ -581,21 +600,21 @@ std::vector > JsonApiServer::getResources() const return tab; } -bool JsonApiServer::restart() +void JsonApiServer::restart() { - fullstop(); - RsThread::start("JSON API Server"); - - return true; + /* 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(); + RsThread::start("JSON API Server"); + }); } void JsonApiServer::onStopRequested() -{ if(mService->is_up()) mService->stop(); } - -bool JsonApiServer::fullstop() { - RsThread::fullstop(); - return true; + RS_STACK_MUTEX(mServiceMutex); + mService->stop(); } uint16_t JsonApiServer::listeningPort() const { return mListeningPort; } @@ -611,16 +630,12 @@ void JsonApiServer::run() settings->set_bind_address(mBindingAddress); 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 * service and therefore leaves the listening port open */ - mService = std::make_shared(); + { + RS_STACK_MUTEX(mServiceMutex); + mService = std::make_shared(); + } for(auto& r: getResources()) mService->publish(r); @@ -628,8 +643,8 @@ void JsonApiServer::run() { RsUrl apiUrl; apiUrl.setScheme("http").setHost(mBindingAddress) .setPort(mListeningPort); - RsDbg() << __PRETTY_FUNCTION__ << " JSON API server listening on " - << apiUrl.toString() << std::endl; + RsInfo() << __PRETTY_FUNCTION__ << " JSON API server listening on " + << apiUrl.toString() << std::endl; mService->start(settings); } catch(std::exception& e) @@ -640,7 +655,7 @@ void JsonApiServer::run() return; } - RsInfo() << __PRETTY_FUNCTION__ << " finished!" << std::endl; + RsDbg() << __PRETTY_FUNCTION__ << " finished!" << std::endl; } /*static*/ void RsJsonApi::version( diff --git a/libretroshare/src/jsonapi/jsonapi.h b/libretroshare/src/jsonapi/jsonapi.h index 5067397a8..803be8459 100644 --- a/libretroshare/src/jsonapi/jsonapi.h +++ b/libretroshare/src/jsonapi/jsonapi.h @@ -63,10 +63,13 @@ public: std::vector> getResources() const; /// @see RsJsonApi - bool restart() override; + void fullstop() override { RsThread::fullstop(); } /// @see RsJsonApi - bool fullstop() override; + void restart() override; + + /// @see RsJsonApi + void askForStop() override { RsThread::askForStop(); } /// @see RsJsonApi inline bool isRunning() override { return RsThread::isRunning(); } @@ -193,6 +196,10 @@ private: std::less > mResourceProviders; std::shared_ptr 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; std::string mBindingAddress; diff --git a/libretroshare/src/retroshare/rsbroadcastdiscovery.h b/libretroshare/src/retroshare/rsbroadcastdiscovery.h index 1bb1e1cc6..92b0e5b0e 100644 --- a/libretroshare/src/retroshare/rsbroadcastdiscovery.h +++ b/libretroshare/src/retroshare/rsbroadcastdiscovery.h @@ -71,23 +71,32 @@ struct RsBroadcastDiscoveryResult : RsSerializable * @brief Event emitted when a non friend new peer is found in the local network * @see RsEvents */ -struct RsBroadcastDiscoveryPeerFoundEvent : RsEvent -{ - RsBroadcastDiscoveryPeerFoundEvent( - const RsBroadcastDiscoveryResult& eventData ) : - RsEvent(RsEventType::BROADCAST_DISCOVERY_PEER_FOUND), mData(eventData) {} +enum class RsBroadcastDiscoveryEventType: uint32_t { + UNKNOWN = 0x00, + PEER_FOUND = 0x01 +}; - RsBroadcastDiscoveryResult mData; +struct RsBroadcastDiscoveryEvent : RsEvent +{ + RsBroadcastDiscoveryEvent() + : RsEvent(RsEventType::BROADCAST_DISCOVERY), + mDiscoveryEventType(RsBroadcastDiscoveryEventType::UNKNOWN) + {} + + virtual ~RsBroadcastDiscoveryEvent() override = default; + + RsBroadcastDiscoveryEventType mDiscoveryEventType; + RsBroadcastDiscoveryResult mData; /// @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override { RsEvent::serial_process(j, ctx); + + RS_SERIAL_PROCESS(mDiscoveryEventType); RS_SERIAL_PROCESS(mData); } - - ~RsBroadcastDiscoveryPeerFoundEvent() override; }; diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index bc5d00cf5..7d6d24505 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -53,10 +53,10 @@ enum class RsEventType : uint32_t NONE = 0, /// Used to detect uninitialized event /// @see RsBroadcastDiscovery - BROADCAST_DISCOVERY_PEER_FOUND = 1, + BROADCAST_DISCOVERY = 1, /// @see RsDiscPendingPgpReceivedEvent - GOSSIP_DISCOVERY_INVITE_RECEIVED = 2, + GOSSIP_DISCOVERY = 2, /// @see AuthSSL AUTHSSL_CONNECTION_AUTENTICATION = 3, @@ -64,14 +64,14 @@ enum class RsEventType : uint32_t /// @see pqissl PEER_CONNECTION = 4, - /// @see RsGxsChanges + /// @see RsGxsChanges // this one is used in RsGxsBroadcast GXS_CHANGES = 5, /// Emitted when a peer state changes, @see RsPeers PEER_STATE_CHANGED = 6, /// @see RsMailStatusEvent - MAIL_STATUS_CHANGE = 7, + MAIL_STATUS = 7, /// @see RsGxsCircleEvent GXS_CIRCLES = 8, @@ -163,6 +163,7 @@ public: * Every time an event is dispatced the registered events handlers will get * their method handleEvent called with the event passed as paramether. * @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 * is dispatched. * @param[inout] hId Optional storage for handler id, useful to @@ -173,6 +174,7 @@ public: * @return False on error, true otherwise. */ virtual bool registerEventsHandler( + RsEventType eventType, std::function)> multiCallback, RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0) ) = 0; diff --git a/libretroshare/src/retroshare/rsgossipdiscovery.h b/libretroshare/src/retroshare/rsgossipdiscovery.h index c9dc9924a..ca1ab0d7c 100644 --- a/libretroshare/src/retroshare/rsgossipdiscovery.h +++ b/libretroshare/src/retroshare/rsgossipdiscovery.h @@ -45,11 +45,18 @@ extern std::shared_ptr rsGossipDiscovery; /** * @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; /// @see RsSerializable @@ -57,6 +64,7 @@ struct RsGossipDiscoveryFriendInviteReceivedEvent : RsEvent RsGenericSerializer::SerializeContext& ctx ) { RsEvent::serial_process(j,ctx); + RS_SERIAL_PROCESS(mGossipDiscoveryEventType); RS_SERIAL_PROCESS(mInvite); } }; diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h index e29c5df50..84349f75e 100644 --- a/libretroshare/src/retroshare/rsgrouter.h +++ b/libretroshare/src/retroshare/rsgrouter.h @@ -19,12 +19,13 @@ * along with this program. If not, see . * * * *******************************************************************************/ - #pragma once #include "util/rsdir.h" +#include "util/rsdeprecate.h" #include "retroshare/rsids.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 uint32_t GRouterServiceId ; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index ddda6e65a..67844cde0 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -511,9 +511,13 @@ struct RsIdentity : RsGxsIfaceHelper * @brief request details of a not yet known identity to the network * @jsonapi{development} * @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 */ - virtual bool requestIdentity(const RsGxsId& id) = 0; + virtual bool requestIdentity( + const RsGxsId& id, + const std::vector& peers = std::vector() ) = 0; /// default base URL used for indentity links @see exportIdentityLink static const std::string DEFAULT_IDENTITY_BASE_URL; diff --git a/libretroshare/src/retroshare/rsjsonapi.h b/libretroshare/src/retroshare/rsjsonapi.h index 2fbad4a44..251310aaa 100644 --- a/libretroshare/src/retroshare/rsjsonapi.h +++ b/libretroshare/src/retroshare/rsjsonapi.h @@ -43,18 +43,25 @@ public: static const std::string DEFAULT_BINDING_ADDRESS; // 127.0.0.1 /** - * @brief Restart RsJsonApi server + * @brief Restart RsJsonApi server asynchronously. * @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 * 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 @@ -128,8 +135,7 @@ public: std::string& user, std::string& passwd ); /** - * Add new auth (user,passwd) token to the authorized set, creating the - * token user:passwd internally. + * Add new API auth (user,passwd) token to the authorized set. * @jsonapi{development} * @param[in] user user name to autorize, must be alphanumerinc * @param[in] password password for the user, must be alphanumerinc diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index 915444360..3bdc76505 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -296,7 +296,6 @@ struct MsgTagType : RsSerializable } //namespace Rs } //namespace Msgs - enum class RsMailStatusEventCode: uint8_t { NEW_MESSAGE = 0x00, @@ -312,9 +311,9 @@ enum class RsMailStatusEventCode: uint8_t struct RsMailStatusEvent : RsEvent { - RsMailStatusEvent() : RsEvent(RsEventType::MAIL_STATUS_CHANGE) {} + RsMailStatusEvent() : RsEvent(RsEventType::MAIL_STATUS) {} - RsMailStatusEventCode mMailStatusEventCode; + RsMailStatusEventCode mMailStatusEventCode; std::set mChangedMsgIds; /// @see RsEvent @@ -326,7 +325,7 @@ struct RsMailStatusEvent : RsEvent RS_SERIAL_PROCESS(mMailStatusEventCode); } - ~RsMailStatusEvent() override; + ~RsMailStatusEvent() override = default; }; #define RS_CHAT_PUBLIC 0x0001 @@ -335,7 +334,7 @@ struct RsMailStatusEvent : RsEvent #define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000 #define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001 -#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0002 +#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0002 #define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0003 #define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000 diff --git a/libretroshare/src/rsitems/rsposteditems.cc b/libretroshare/src/rsitems/rsposteditems.cc index 23fb6633b..3c16ff5bd 100644 --- a/libretroshare/src/rsitems/rsposteditems.cc +++ b/libretroshare/src/rsitems/rsposteditems.cc @@ -33,8 +33,8 @@ void RsGxsPostedPostItem::serial_process(RsGenericSerializer::SerializeJob j,RsG // and do not expect to deserialize mImage member if the data block has been consummed entirely (keeps compatibility // of new RS with older posts. - if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize) - return ; + if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize) + return ; if((j == RsGenericSerializer::SIZE_ESTIMATE || j == RsGenericSerializer::SERIALIZE) && mImage.empty()) return ; diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index ad74dbdde..48a694fb0 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -538,8 +538,7 @@ bool p3Msgs::initiateDistantChatConnexion( const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId& pid, uint32_t& error_code, bool notify ) { - return mChatSrv->initiateDistantChatConnexion( to_gxs_id, from_gxs_id, - pid, error_code, notify ); + return mChatSrv->initiateDistantChatConnexion( to_gxs_id, from_gxs_id, pid, error_code, notify ); } bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info) { @@ -559,7 +558,6 @@ uint32_t p3Msgs::getDistantChatPermissionFlags() } RsMsgs::~RsMsgs() = default; -RsMailStatusEvent::~RsMailStatusEvent() = default; Rs::Msgs::MessageInfo::~MessageInfo() = default; MsgInfoSummary::~MsgInfoSummary() = default; VisibleChatLobbyRecord::~VisibleChatLobbyRecord() = default; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 98b0e53fb..db290ea63 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -297,6 +297,7 @@ int RsInit::InitRetroShare(const RsConfigOptions& conf) rsInitConfig->inet = conf.forcedInetAddress ; rsInitConfig->port = conf.forcedPort ; rsInitConfig->debugLevel = conf.debugLevel; + rsInitConfig->udpListenerOnly = conf.udpListenerOnly; rsInitConfig->optBaseDir = conf.optBaseDir; rsInitConfig->jsonApiPort = conf.jsonApiPort; rsInitConfig->jsonApiBindAddress = conf.jsonApiBindAddress; diff --git a/libretroshare/src/services/broadcastdiscoveryservice.cc b/libretroshare/src/services/broadcastdiscoveryservice.cc index e4947a586..f691fd7ed 100644 --- a/libretroshare/src/services/broadcastdiscoveryservice.cc +++ b/libretroshare/src/services/broadcastdiscoveryservice.cc @@ -182,10 +182,15 @@ void BroadcastDiscoveryService::threadTick() } else if(!isFriend) { - typedef RsBroadcastDiscoveryPeerFoundEvent Evt_t; if(rsEvents) - rsEvents->postEvent( - std::shared_ptr(new Evt_t(rbdr)) ); + { + auto ev = std::make_shared(); + + ev->mDiscoveryEventType = RsBroadcastDiscoveryEventType::PEER_FOUND; + ev->mData = rbdr; + + rsEvents->postEvent(ev); + } } } } @@ -307,5 +312,4 @@ bool BroadcastDiscoveryService::assertMulticastLockIsvalid() RsBroadcastDiscovery::~RsBroadcastDiscovery() = default; RsBroadcastDiscoveryResult::~RsBroadcastDiscoveryResult() = default; -RsBroadcastDiscoveryPeerFoundEvent::~RsBroadcastDiscoveryPeerFoundEvent() = default; BroadcastDiscoveryPack::~BroadcastDiscoveryPack() = default; diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 8ee484d08..800c148f4 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -247,7 +247,7 @@ void p3GxsChannels::notifyChanges(std::vector &changes) RsGxsMsgChange *msgChange = dynamic_cast(*it); if (msgChange) { - if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) + if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) { /* message received */ if (rsEvents) diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index a2fac2db8..b5b7ae9ad 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -501,7 +501,7 @@ void p3GxsCircles::notifyChanges(std::vector &changes) RsGxsCircleDetails 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) { RsGxsCircleMsg msg; diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 128b5db39..6ef0dae34 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -191,7 +191,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) RsGxsMsgChange *msgChange = dynamic_cast(*it); 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) { std::map >& msgChangeMap = msgChange->msgChangeMap; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 0821f3286..85de0abcb 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1163,92 +1163,89 @@ bool p3IdService::havePrivateKey(const RsGxsId &id) if(! isOwnId(id)) return false ; - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - return mKeyCache.is_cached(id) ; + RS_STACK_MUTEX(mIdMtx); + return mKeyCache.is_cached(id); } static void mergeIds(std::map >& idmap,const RsGxsId& id,const std::list& peers) { - // merge the two lists (I use a std::set to make it more efficient) -#ifdef DEBUG_IDS - std::cerr << "p3IdService::requestKey(): merging list with existing pending request." << std::endl; -#endif + /* merge the two lists, use std::set to avoid duplicates efficiently */ - std::list& old_peers(idmap[id]) ; // create if necessary - std::set new_peers ; + std::set new_peers(std::begin(peers), std::end(peers)); - for(std::list::const_iterator it(peers.begin());it!=peers.end();++it) - new_peers.insert(*it) ; - - for(std::list::iterator it(old_peers.begin());it!=old_peers.end();++it) - new_peers.insert(*it) ; - - old_peers.clear(); - - for(std::set::iterator it(new_peers.begin());it!=new_peers.end();++it) - old_peers.push_back(*it) ; + std::list& stored_peers(idmap[id]); + std::copy( std::begin(stored_peers), std::end(stored_peers), + std::inserter(new_peers, std::begin(new_peers)) ); + stored_peers.clear(); + std::copy( std::begin(new_peers), std::end(new_peers), + std::inserter(stored_peers, std::begin(stored_peers)) ); } -bool p3IdService::requestIdentity(const RsGxsId& id) +bool p3IdService::requestIdentity( + const RsGxsId& id, const std::vector& peers ) { + std::list 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::IDENTITY_DATA_UPDATE ); - std::list onlinePeers; - return rsPeers && rsPeers->getOnlineList(onlinePeers) - && requestKey(id, onlinePeers, usageInfo); + return requestKey(id, askPeersList, usageInfo); } bool p3IdService::requestKey(const RsGxsId &id, const std::list& peers,const RsIdentityUsage& use_info) { - if(id.isNull()) - { - std::cerr << "(EE) nul ID requested to p3IdService. This should not happen. Callstack:" << std::endl; - print_stacktrace(); - return false ; - } + Dbg3() << __PRETTY_FUNCTION__ << " id: " << id << std::endl; - if (haveKey(id)) - return true; - else - { - // Normally we should call getIdDetails(), but since the key is not known, we need to digg 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. + if(id.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " cannot request null id" + << std::endl; + return false; + } -#ifdef DEBUG_IDS - std::cerr << "p3IdService::requesting key " << id <getReputationInfo(id,RsPgpId(),info) ; + if(isKnownId(id)) return true; - if( info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE ) - { - std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl; + /* 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*/ - { - RS_STACK_MUTEX(mIdMtx); /********** STACK LOCKED MTX ******/ - mIdsNotPresent.erase(id) ; - } - return true; - } + RsReputationInfo info; + rsReputations->getReputationInfo(id, RsPgpId(), info); - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if( info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE ) + { + RsInfo() << __PRETTY_FUNCTION__ << " not requesting Key " << id + << " because it has been banned." << std::endl; - std::map >::iterator rit = mIdsNotPresent.find(id) ; + RS_STACK_MUTEX(mIdMtx); + mIdsNotPresent.erase(id); - if(rit != mIdsNotPresent.end()) - { - if(!peers.empty()) - mergeIds(mIdsNotPresent,id,peers) ; + return false; + } - return true ; - } - } - { - RS_STACK_MUTEX(mIdMtx); /********** STACK LOCKED MTX ******/ - mKeysTS[id].usage_map[use_info] = time(NULL) ; - } + { + RS_STACK_MUTEX(mIdMtx); + mergeIds(mIdsNotPresent, id, peers); + mKeysTS[id].usage_map[use_info] = time(nullptr); + } return cache_request_load(id, peers); } @@ -2772,34 +2769,30 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) bool p3IdService::cache_request_load(const RsGxsId &id, const std::list &peers) { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_request_load(" << id << ")" << std::endl; -#endif // DEBUG_IDS + Dbg4() << __PRETTY_FUNCTION__ << " id: " << id << std::endl; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + { + RS_STACK_MUTEX(mIdMtx); + // merge, even if peers is empty + mergeIds(mCacheLoad_ToCache, id, peers); + } - mergeIds(mCacheLoad_ToCache,id,peers) ; // merge, even if peers is empty - } + if(RsTickEvent::event_count(GXSID_EVENT_CACHELOAD) > 0) + { + Dbg3() << __PRETTY_FUNCTION__ << " cache reload already scheduled " + << "skipping" << std::endl; + return true; + } - if (RsTickEvent::event_count(GXSID_EVENT_CACHELOAD) > 0) - { - /* its already scheduled */ - return true; - } + int32_t age = 0; + if( RsTickEvent::prev_event_ago(GXSID_EVENT_CACHELOAD, age) && age < MIN_CYCLE_GAP ) + { + RsTickEvent::schedule_in(GXSID_EVENT_CACHELOAD, MIN_CYCLE_GAP - age); + return true; + } - int32_t age = 0; - if (RsTickEvent::prev_event_ago(GXSID_EVENT_CACHELOAD, age)) - { - if (age < MIN_CYCLE_GAP) - { - RsTickEvent::schedule_in(GXSID_EVENT_CACHELOAD, MIN_CYCLE_GAP - age); - return true; - } - } - - RsTickEvent::schedule_now(GXSID_EVENT_CACHELOAD); - return true; + RsTickEvent::schedule_now(GXSID_EVENT_CACHELOAD); + return true; } @@ -2923,71 +2916,88 @@ bool p3IdService::cache_load_for_token(uint32_t token) void p3IdService::requestIdsFromNet() { - RsStackMutex stack(mIdMtx); + RS_STACK_MUTEX(mIdMtx); - if(!mNes) - { - std::cerr << "(WW) cannot request missing GXS IDs because network service is not present." << std::endl; - return ; - } + if(!mNes) + { + RsErr() << __PRETTY_FUNCTION__ << " Cannot request missing GXS IDs " + << "because network service is not present." << std::endl; + return; + } std::map >::iterator cit; std::map > requests; - // Transform to appropriate structure ( > map) to make request to nes per peer ID - // Only delete entries in mIdsNotPresent that can actually be performed. + /* Transform to appropriate structure ( > map) + * 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();) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::requestIdsFromNet() Id not found, deferring for net request: " << cit->first << std::endl; -#endif + for(cit = mIdsNotPresent.begin(); cit != mIdsNotPresent.end();) + { + Dbg2() << __PRETTY_FUNCTION__ << " Processing missing key RsGxsId: " + << cit->first << std::endl; - const std::list& peers = cit->second; - std::list::const_iterator cit2; + const RsGxsId& gxsId = cit->first; + const std::list& peers = cit->second; + std::list::const_iterator cit2; bool request_can_proceed = false ; - 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); - request_can_proceed = true ; -#ifdef DEBUG_IDS - std::cerr << " will ask ID " << cit->first << " to peer ID " << *cit2 << std::endl; -#endif - } + for(cit2 = peers.begin(); cit2 != peers.end(); ++cit2) + { + const RsPeerId& peer = *cit2; - if(request_can_proceed || peers.empty()) - { - std::map >::iterator tmp(cit); - ++tmp ; - mIdsNotPresent.erase(cit) ; - cit = tmp ; - } - else - { -#ifdef DEBUG_IDS - std::cerr << "(EE) no online peers among supply list in ID request for groupId " << cit->first << ". Keeping it until peers show up."<< std::endl; -#endif - ++cit ; - } - } + 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 ; - for(std::map >::const_iterator cit2(requests.begin()); cit2 != requests.end(); ++cit2) - { - std::list::const_iterator gxs_id_it = cit2->second.begin(); - std::list grpIds; - for(; gxs_id_it != cit2->second.end(); ++gxs_id_it) - { -#ifdef DEBUG_IDS - std::cerr << " asking ID " << *gxs_id_it << " to peer ID " << cit2->first << std::endl; -#endif - grpIds.push_back(RsGxsGroupId(*gxs_id_it)); - } + Dbg2() << __PRETTY_FUNCTION__ << " Moving missing key RsGxsId:" + << gxsId << " to peer: " << peer << " requests queue" + << std::endl; + } + } - mNes->requestGrp(grpIds, cit2->first); - } + 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 >::iterator tmp(cit); + ++tmp; + mIdsNotPresent.erase(cit); + cit = tmp; + } + else + { + RsInfo() << __PRETTY_FUNCTION__ << " no online peers among supplied" + << " list in request for RsGxsId: " << gxsId + << ". Keeping it until peers show up."<< std::endl; + ++cit; + } + } + + for( std::map >::const_iterator cit2( + requests.begin() ); cit2 != requests.end(); ++cit2 ) + { + const RsPeerId& peer = cit2->first; + std::list grpIds; + for( std::list::const_iterator gxs_id_it = cit2->second.begin(); + gxs_id_it != cit2->second.end(); ++gxs_id_it ) + { + Dbg2() << __PRETTY_FUNCTION__ << " passing RsGxsId: " << *gxs_id_it + << " request for peer: " << peer + << " to RsNetworkExchangeService " << std::endl; + grpIds.push_back(RsGxsGroupId(*gxs_id_it)); + } + + mNes->requestGrp(grpIds, peer); + } } bool p3IdService::cache_update_if_cached(const RsGxsId &id, std::string serviceString) @@ -4698,14 +4708,12 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel* break; case GXSID_EVENT_REQUEST_IDS: requestIdsFromNet(); - break; - - - default: - /* error */ - std::cerr << "p3IdService::handle_event() Unknown Event Type: " << event_type; - std::cerr << std::endl; - break; + break; + default: + RsErr() << __PRETTY_FUNCTION__ << " Unknown Event Type: " + << event_type << std::endl; + print_stacktrace(); + break; } } diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 26121cd8a..3c6b6677c 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -381,7 +381,10 @@ public: RsGxsId* id = nullptr); /// @see RsIdentity - bool requestIdentity(const RsGxsId& id) override; + bool requestIdentity( + const RsGxsId& id, + const std::vector& peers = std::vector() + ) override; /**************** RsGixsReputation Implementation ****************/ @@ -494,7 +497,7 @@ private: /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - std::map mPgpFingerprintMap; + std::map mPgpFingerprintMap; std::list mGroupsToProcess; /************************************************************************ @@ -633,5 +636,5 @@ private: bool mAutoAddFriendsIdentitiesAsContacts; uint32_t mMaxKeepKeysBanned; - RS_SET_CONTEXT_DEBUG_LEVEL(1) + RS_SET_CONTEXT_DEBUG_LEVEL(2) }; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 8acd44501..b1c1bf847 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -2134,8 +2134,7 @@ bool p3MsgService::receiveGxsTransMail( const RsGxsId& authorId, { RS_STACK_MUTEX(recentlyReceivedMutex); - if( mRecentlyReceivedMessageHashes.find(hash) != - mRecentlyReceivedMessageHashes.end() ) + if( mRecentlyReceivedMessageHashes.find(hash) != mRecentlyReceivedMessageHashes.end() ) { RsInfo() << __PRETTY_FUNCTION__ << " (II) receiving " << "message of hash " << hash << " more than once. " @@ -2143,14 +2142,12 @@ bool p3MsgService::receiveGxsTransMail( const RsGxsId& authorId, << std::endl; return true; } - mRecentlyReceivedMessageHashes[hash] = - static_cast(time(nullptr)); + mRecentlyReceivedMessageHashes[hash] = static_cast(time(nullptr)); } IndicateConfigChanged(); - RsItem *item = _serialiser->deserialise( - const_cast(data), &dataSize ); + RsItem *item = _serialiser->deserialise( const_cast(data), &dataSize ); RsMsgItem *msg_item = dynamic_cast(item); if(msg_item) diff --git a/libretroshare/src/services/p3postbase.cc b/libretroshare/src/services/p3postbase.cc index 51308194c..12799c4f7 100644 --- a/libretroshare/src/services/p3postbase.cc +++ b/libretroshare/src/services/p3postbase.cc @@ -112,7 +112,7 @@ void p3PostBase::notifyChanges(std::vector &changes) // It could be taken a step further and directly request these msgs for an update. 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) { auto ev = std::make_shared(); diff --git a/libretroshare/src/services/rseventsservice.cc b/libretroshare/src/services/rseventsservice.cc index b0329fbb2..c1aa0958c 100644 --- a/libretroshare/src/services/rseventsservice.cc +++ b/libretroshare/src/services/rseventsservice.cc @@ -100,22 +100,42 @@ RsEventsHandlerId_t RsEventsService::generateUniqueHandlerId_unlocked() } bool RsEventsService::registerEventsHandler( + RsEventType eventType, std::function)> multiCallback, RsEventsHandlerId_t& hId ) { 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; } bool RsEventsService::unregisterEventsHandler(RsEventsHandlerId_t hId) { RS_STACK_MUTEX(mHandlerMapMtx); - auto it = mHandlerMap.find(hId); - if(it == mHandlerMap.end()) return false; - mHandlerMap.erase(it); - return true; + + for(uint32_t i=0;i event) { std::function)> mCallback; - mHandlerMapMtx.lock(); - auto cbpt = mHandlerMap.begin(); - mHandlerMapMtx.unlock(); + uint32_t event_type_index = static_cast(event->mType); -getHandlerFromMapLock: - mHandlerMapMtx.lock(); - if(cbpt != mHandlerMap.end()) { - mCallback = cbpt->second; - ++cbpt; - } - mHandlerMapMtx.unlock(); + RS_STACK_MUTEX(mHandlerMapMtx); /* LOCKED AREA */ - if(mCallback) - { - mCallback(event); // It is relevant that this happens outside mutex - mCallback = std::function)>(nullptr); - goto getHandlerFromMapLock; + if(event_type_index >= mHandlerMaps.size() || event_type_index < 1) + { + RsErr() << "Cannot handle an event of type " << event_type_index << ": out of scope!" << std::endl; + return; + } + + // 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(RsEventType::NONE)]) + cbit.second(event); } } diff --git a/libretroshare/src/services/rseventsservice.h b/libretroshare/src/services/rseventsservice.h index b467358af..805a173a0 100644 --- a/libretroshare/src/services/rseventsservice.h +++ b/libretroshare/src/services/rseventsservice.h @@ -35,6 +35,7 @@ class RsEventsService : public: RsEventsService(): mHandlerMapMtx("RsEventsService::mHandlerMapMtx"), mLastHandlerId(1), + mHandlerMaps(static_cast(RsEventType::MAX)), mEventQueueMtx("RsEventsService::mEventQueueMtx") {} /// @see RsEvents @@ -54,6 +55,7 @@ public: /// @see RsEvents bool registerEventsHandler( + RsEventType eventType, std::function)> multiCallback, RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0) ) override; @@ -64,9 +66,11 @@ public: protected: RsMutex mHandlerMapMtx; RsEventsHandlerId_t mLastHandlerId; - std::map< - RsEventsHandlerId_t, - std::function)> > mHandlerMap; + + std::vector< + std::map< + RsEventsHandlerId_t, + std::function)> > > mHandlerMaps; RsMutex mEventQueueMtx; std::deque< std::shared_ptr > mEventQueue; diff --git a/libretroshare/src/tcponudp/bss_tou.cc b/libretroshare/src/tcponudp/bss_tou.cc index b5b4693aa..286201f53 100644 --- a/libretroshare/src/tcponudp/bss_tou.cc +++ b/libretroshare/src/tcponudp/bss_tou.cc @@ -137,18 +137,18 @@ static int tou_socket_read(BIO *b, char *out, int outl) int ret=0; - if (!out) - { + if (out) + { clear_tou_socket_error(BIO_get_fd(b,NULL)); /* call tou library */ ret=tou_read(BIO_get_fd(b,NULL),out,outl); BIO_clear_retry_flags(b); if (ret <= 0) - { + { if (BIO_tou_socket_should_retry(BIO_get_fd(b,NULL), ret)) BIO_set_retry_read(b); - } } + } #ifdef DEBUG_TOU_BIO fprintf(stderr, "tou_socket_read() = %d\n", ret); #endif diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 328b04772..677b282cd 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -1886,11 +1886,15 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item) // 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. - bool found = false ; +#ifdef P3TURTLE_DEBUG + bool ext_found = false ; +#endif for(std::map::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) if(it->second.last_request == item->request_id) { - found = true ; +#ifdef P3TURTLE_DEBUG + ext_found = true ; +#endif { // add the tunnel uniquely @@ -1917,7 +1921,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item) } } #ifdef P3TURTLE_DEBUG - if(!found) + if(!ext_found) std::cerr << "p3turtle: error. Could not find hash that emmitted tunnel request " << reinterpret_cast(item->tunnel_id) << std::endl ; #endif } diff --git a/libretroshare/src/util/rsstring.cc b/libretroshare/src/util/rsstring.cc index c938ea82f..7b540156a 100644 --- a/libretroshare/src/util/rsstring.cc +++ b/libretroshare/src/util/rsstring.cc @@ -207,15 +207,14 @@ bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest) 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) { - for(uint32_t i=0;i(this) << std::hex << ", callerTid: " << callerTid - << ", mTid: " << mTid << std::dec << std::endl; + << ", mTid: " << mTid << std::dec + << ", mFullName: " << mFullName << std::endl; print_stacktrace(); return; } @@ -134,9 +138,9 @@ void RsThread::fullstop() std::this_thread::sleep_for(std::chrono::milliseconds(200)); ++i; if(!(i%5)) - RsInfo() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed" - << " waiting for thread: " << mTid << " " << mFullName - << " to stop" << std::endl; + RsDbg() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed" + << " waiting for thread: " << std::hex << mLastTid + << std::dec << " " << mFullName << " to stop" << std::endl; } } @@ -158,6 +162,9 @@ bool RsThread::start(const std::string& threadName) 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 */ mFullName = threadName; @@ -266,10 +273,10 @@ double RsStackMutex::getCurrentTS() RsThread::~RsThread() { - if(isRunning()) + if(!mHasStopped) { - RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mTid << " " - << mFullName << " that is still " + RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mLastTid + << " " << mFullName << " that is still " << "running! Something seems very wrong here and RetroShare is " << "likely to crash because of this." << std::endl; print_stacktrace(); diff --git a/libretroshare/src/util/rsthreads.h b/libretroshare/src/util/rsthreads.h index 55af56847..5692bb256 100644 --- a/libretroshare/src/util/rsthreads.h +++ b/libretroshare/src/util/rsthreads.h @@ -264,9 +264,19 @@ private: /// Store the id of the corresponding pthread 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; + + /** 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; }; /** diff --git a/plugins/FeedReader/gui/FeedReaderFeedItem.h b/plugins/FeedReader/gui/FeedReaderFeedItem.h index 10776c08b..29b8c2bba 100644 --- a/plugins/FeedReader/gui/FeedReaderFeedItem.h +++ b/plugins/FeedReader/gui/FeedReaderFeedItem.h @@ -47,8 +47,7 @@ protected: private slots: /* default stuff */ - void removeItem(); - void toggle(); + void toggle() override; void readAndClearItem(); void copyLink(); @@ -61,9 +60,7 @@ private: RsFeedReader *mFeedReader; FeedReaderNotify *mNotify; - FeedHolder *mParent; - std::string mFeedId; std::string mMsgId; QString mLink; diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 995ac13fc..c64c758ea 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -72,8 +72,21 @@ static NewsFeed *instance = NULL; /** Constructor */ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed) { - mEventHandlerId =0; // needed to force intialization by registerEventsHandler() - rsEvents->registerEventsHandler( [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerId ); + mEventTypes = { + 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;iregisterEventsHandler(mEventTypes[i], [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerIds.back() ); + } /* Invoke the Qt Designer generated object setup routine */ ui->setupUi(this); @@ -117,7 +130,8 @@ QString hlp_str = tr( NewsFeed::~NewsFeed() { - rsEvents->unregisterEventsHandler(mEventHandlerId); + for(uint32_t i=0;iunregisterEventsHandler(mEventHandlerIds[i]); // save settings processSettings(false); @@ -188,10 +202,10 @@ void NewsFeed::handleEvent_main_thread(std::shared_ptr event) handleForumEvent(event); 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); + + if(event->mType == RsEventType::MAIL_STATUS && (flags & RS_FEED_TYPE_MSG)) + handleMailEvent(event); } void NewsFeed::handleMailEvent(std::shared_ptr event) @@ -200,6 +214,7 @@ void NewsFeed::handleMailEvent(std::shared_ptr event) dynamic_cast(event.get()); if(!pe) return; + switch(pe->mMailStatusEventCode) { case RsMailStatusEventCode::NEW_MESSAGE: @@ -480,14 +495,10 @@ void NewsFeed::addFeedItemIfUnique(FeedItem *item, bool replace) 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; - - ui->feedWidget->removeFeedItem(feedItem); - } } /* FeedHolder Functions (for FeedItem functionality) */ @@ -496,7 +507,7 @@ QScrollArea *NewsFeed::getScrollArea() return NULL; } -void NewsFeed::deleteFeedItem(QWidget *item, uint32_t /*type*/) +void NewsFeed::deleteFeedItem(FeedItem *item, uint32_t /*type*/) { #ifdef NEWS_DEBUG std::cerr << "NewsFeed::deleteFeedItem()"; @@ -504,6 +515,7 @@ void NewsFeed::deleteFeedItem(QWidget *item, uint32_t /*type*/) #endif if (item) { + ui->feedWidget->removeFeedItem(item); item->close (); } } diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index c255d56ac..ec9aabcb5 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -74,7 +74,7 @@ public: /* FeedHolder Functions (for FeedItem functionality) */ 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 openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &versions, const RsGxsMessageId &msgId, const QString &title); @@ -118,7 +118,8 @@ private: /* UI - from Designer */ Ui::NewsFeed *ui; - RsEventsHandlerId_t mEventHandlerId; + std::vector mEventHandlerIds; + std::vector mEventTypes; }; #endif diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index fcfd374e1..ee572dfac 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -51,17 +51,8 @@ PhotoView::~PhotoView() 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) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index 9c540bc28..b7067eecf 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -6,8 +6,8 @@ 0 0 - 565 - 464 + 346 + 107 @@ -38,7 +38,7 @@ - + 0 0 @@ -51,38 +51,12 @@ 0 - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -165,7 +139,7 @@ - 398 + 0 20 @@ -207,9 +181,13 @@
gui/common/AvatarWidget.h
1 + + AspectRatioPixmapLabel + QLabel +
util/aspectratiopixmaplabel.h
+
- diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 76e612321..97b6974d0 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -49,7 +49,7 @@ public: const RsPostedPost &getPost() const; 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: /* FeedItem */ virtual void doExpand(bool open); @@ -60,7 +60,7 @@ private slots: void makeDownVote(); void readToggled(bool checked); void readAndClearItem(); - void toggle(); + void toggle() override; void copyMessageLink(); void toggleNotes(); void viewPicture(); diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index ab011f719..04fd89186 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -168,8 +168,7 @@ QScrollArea *PostedListWidget::getScrollArea() return ui->scrollAreaCardView; }*/ - -void PostedListWidget::deleteFeedItem(QWidget */*item*/, uint32_t /*type*/) +void PostedListWidget::deleteFeedItem(FeedItem *, uint32_t /*type*/) { #ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::deleteFeedItem() Nah"; diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.h b/retroshare-gui/src/gui/Posted/PostedListWidget.h index ddd726513..fa9f25c8e 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.h +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.h @@ -49,7 +49,7 @@ public: /* FeedHolder */ 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 openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &versions, const RsGxsMessageId &msgId, const QString &title); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 6249d5681..0922793f6 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -382,31 +382,42 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) if (messageCount > 0) { - rsHistory->getMessages(chatId, historyMsgs, messageCount); + rsHistory->getMessages(chatId, historyMsgs, messageCount); std::list::iterator historyIt; for (historyIt = historyMsgs.begin(); historyIt != historyMsgs.end(); ++historyIt) - { - // it can happen that a message is first added to the message history - // and later the gui receives the message through notify - // avoid this by not adding history entries if their age is < 2secs - if ((time(NULL)-2) <= historyIt->recvTime) - continue; + { + // it can happen that a message is first added to the message history + // and later the gui receives the message through notify + // avoid this by not adding history entries if their age is < 2secs + if (time(nullptr) <= historyIt->recvTime+2) + continue; - QString name; - if (chatId.isLobbyId() || chatId.isDistantChatId()) - { - RsIdentityDetails details; - if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details)) - name = QString::fromUtf8(details.mNickname.c_str()); - else - name = QString::fromUtf8(historyIt->peerName.c_str()); - } else { - name = QString::fromUtf8(historyIt->peerName.c_str()); - } + QString name; + if (chatId.isLobbyId() || chatId.isDistantChatId()) + { + 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; + } + } - addChatMsg(historyIt->incoming, name, RsGxsId(historyIt->peerName.c_str()), QDateTime::fromTime_t(historyIt->sendTime), QDateTime::fromTime_t(historyIt->recvTime), QString::fromUtf8(historyIt->message.c_str()), MSGTYPE_HISTORY); - } + if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details)) + name = QString::fromUtf8(details.mNickname.c_str()); + else + name = QString::fromUtf8(historyIt->peerName.c_str()); + } else { + name = QString::fromUtf8(historyIt->peerName.c_str()); + } + + addChatMsg(historyIt->incoming, name, RsGxsId(historyIt->peerName.c_str()), QDateTime::fromTime_t(historyIt->sendTime), QDateTime::fromTime_t(historyIt->recvTime), QString::fromUtf8(historyIt->message.c_str()), MSGTYPE_HISTORY); + } } } diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 7b07f9086..cb4c68030 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -178,7 +178,7 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent) ui->filterLineEdit->showFilterIcon(); mEventHandlerId=0; // forces initialization - rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId ); + rsEvents->registerEventsHandler( RsEventType::PEER_CONNECTION, [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId ); mModel = new RsFriendListModel(); mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this); @@ -258,13 +258,10 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent) void NewFriendList::handleEvent(std::shared_ptr e) { - if(e->mType == RsEventType::PEER_CONNECTION) - { - // /!\ 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. + // /!\ 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. - RsQThreadUtils::postToObject( [=]() { forceUpdateDisplay() ; }, this ) ; - } + RsQThreadUtils::postToObject( [=]() { forceUpdateDisplay() ; }, this ) ; } NewFriendList::~NewFriendList() diff --git a/retroshare-gui/src/gui/common/RSFeedWidget.cpp b/retroshare-gui/src/gui/common/RSFeedWidget.cpp index fff41d11b..3293e3fae 100644 --- a/retroshare-gui/src/gui/common/RSFeedWidget.cpp +++ b/retroshare-gui/src/gui/common/RSFeedWidget.cpp @@ -111,7 +111,6 @@ bool RSFeedWidget::eventFilter(QObject *object, QEvent *event) FeedItem *feedItem = feedItemFromTreeItem(treeItem); if (feedItem) { disconnectSignals(feedItem); - feedRemoved(feedItem); delete(feedItem); } delete(treeItem); @@ -135,23 +134,19 @@ void RSFeedWidget::feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem) { } -void RSFeedWidget::feedRemoved(FeedItem *feedItem) -{ -} - void RSFeedWidget::feedsCleared() { } 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*))); } 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*))); } @@ -384,11 +379,10 @@ FeedItem *RSFeedWidget::feedItem(int index) void RSFeedWidget::removeFeedItem(FeedItem *feedItem) { - if (!feedItem) { + if (!feedItem) 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) { @@ -396,11 +390,10 @@ void RSFeedWidget::removeFeedItem(FeedItem *feedItem) 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 ; } - feedRemoved(feedItem); disconnectSignals(feedItem); delete ui->treeWidget->takeTopLevelItem(treeItem_index); @@ -424,20 +417,39 @@ void RSFeedWidget::feedItemSizeChanged(FeedItem */*feedItem*/) ui->treeWidget->doItemsLayout(); } -void RSFeedWidget::feedItemDestroyed(FeedItem *feedItem) +void RSFeedWidget::feedItemDestroyed(qulonglong id) { /* 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); if (!mCountChangedDisabled) 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) { QList list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER); @@ -490,27 +502,21 @@ void RSFeedWidget::withAll(RSFeedWidgetCallbackFunction callback, void *data) FeedItem *RSFeedWidget::findFeedItem(uint64_t identifier) { - QTreeWidgetItemIterator it(ui->treeWidget); - QTreeWidgetItem *treeItem=NULL; + QList list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER); - // 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 ((treeItem = *it) != NULL) { - ++it; - - FeedItem *feedItem = feedItemFromTreeItem(treeItem); - if (!feedItem) - continue; - - uint64_t id = feedItem->uniqueIdentifier(); - - if (id == identifier) - return feedItem; - } - - return NULL; + if(list.empty()) + return nullptr; + else if(list.size() == 1) + return feedItemFromTreeItem(list.front()); + else + { + std::cerr << "(EE) More than a single item with identifier \"" << identifier << "\" in the feed tree widget. This shouldn't happen!" << std::endl; + return nullptr; + } } + + void RSFeedWidget::selectedFeedItems(QList &feedItems) { foreach (QTreeWidgetItem *treeItem, ui->treeWidget->selectedItems()) { diff --git a/retroshare-gui/src/gui/common/RSFeedWidget.h b/retroshare-gui/src/gui/common/RSFeedWidget.h index bc38adf84..c0278d786 100644 --- a/retroshare-gui/src/gui/common/RSFeedWidget.h +++ b/retroshare-gui/src/gui/common/RSFeedWidget.h @@ -87,11 +87,10 @@ public slots: protected: bool eventFilter(QObject *object, QEvent *event); virtual void feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem); - virtual void feedRemoved(FeedItem *feedItem); virtual void feedsCleared(); private slots: - void feedItemDestroyed(FeedItem *feedItem); + void feedItemDestroyed(qulonglong id); void feedItemSizeChanged(FeedItem *feedItem); private: @@ -99,6 +98,7 @@ private: void disconnectSignals(FeedItem *feedItem); FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem); QTreeWidgetItem *findTreeWidgetItem(uint64_t identifier); + QTreeWidgetItem *findTreeWidgetItem(const FeedItem *w); void filterItems(); void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem); diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui index 9cbd53ca0..e80105688 100644 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui @@ -6,8 +6,8 @@ 0 0 - 1139 - 1171 + 600 + 400 diff --git a/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp b/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp index ee7aa5ca8..7f37aef8b 100644 --- a/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp @@ -43,7 +43,7 @@ /** Constructor */ 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 */ setupUi(this); @@ -153,26 +153,6 @@ void ChatMsgItem::insertChat(const std::string &message) 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() { #ifdef DEBUG_ITEM @@ -191,7 +171,7 @@ void ChatMsgItem::sendMsg() std::cerr << std::endl; #endif - if (mParent) + if (mFeedHolder) { MessageComposer *nMsgDialog = MessageComposer::newMsg(); @@ -214,15 +194,15 @@ void ChatMsgItem::openChat() std::cerr << "ChatMsgItem::openChat()"; std::cerr << std::endl; #endif - if (mParent) + if (mFeedHolder) { - mParent->openChat(mPeerId); + mFeedHolder->openChat(mPeerId); } } void ChatMsgItem::togglequickmessage() { - mParent->lockLayout(this, true); + mFeedHolder->lockLayout(this, true); if (messageFrame->isHidden()) { @@ -239,7 +219,7 @@ void ChatMsgItem::togglequickmessage() emit sizeChanged(this); - mParent->lockLayout(this, false); + mFeedHolder->lockLayout(this, false); } void ChatMsgItem::sendMessage() diff --git a/retroshare-gui/src/gui/feeds/ChatMsgItem.h b/retroshare-gui/src/gui/feeds/ChatMsgItem.h index fe946a4b9..421cbfda8 100644 --- a/retroshare-gui/src/gui/feeds/ChatMsgItem.h +++ b/retroshare-gui/src/gui/feeds/ChatMsgItem.h @@ -45,7 +45,6 @@ protected: private slots: /* default stuff */ void gotoHome(); - void removeItem(); void sendMsg(); void openChat(); @@ -60,9 +59,6 @@ private slots: private: void insertChat(const std::string &message); - FeedHolder *mParent; - uint32_t mFeedId; - RsPeerId mPeerId; }; diff --git a/retroshare-gui/src/gui/feeds/FeedHolder.h b/retroshare-gui/src/gui/feeds/FeedHolder.h index f683bca19..6c2f256e0 100644 --- a/retroshare-gui/src/gui/feeds/FeedHolder.h +++ b/retroshare-gui/src/gui/feeds/FeedHolder.h @@ -27,6 +27,7 @@ #include // WRONG ONE - BUT IT'LL DO FOR NOW. class QScrollArea; +class FeedItem; class FeedHolder { @@ -34,7 +35,7 @@ public: FeedHolder(); 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 openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &msg_versions, const RsGxsMessageId &msgId, const QString &title)=0; diff --git a/retroshare-gui/src/gui/feeds/FeedItem.cpp b/retroshare-gui/src/gui/feeds/FeedItem.cpp index 2e5353e40..83c97eb3b 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.cpp +++ b/retroshare-gui/src/gui/feeds/FeedItem.cpp @@ -20,17 +20,15 @@ #include #include "FeedItem.h" +#include "FeedHolder.h" /** 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; } -FeedItem::~FeedItem() -{ - emit feedItemDestroyed(this); -} +FeedItem::~FeedItem() { } void FeedItem::expand(bool open) { @@ -48,12 +46,28 @@ void FeedItem::expand(bool open) uint64_t FeedItem::hash_64bits(const std::string& s) const { if(mHash == 0) - { - mHash = 0x01110bbfa09; - - for(uint32_t i=0;i> 3)) + s[i]*0x217898fbba7 + 0x0294379); - } + mHash = hash64(s); return mHash; } + +uint64_t FeedItem::hash64(const std::string& s) +{ + uint64_t hash = 0x01110bbfa09; + + for(uint32_t i=0;i> 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); +} + diff --git a/retroshare-gui/src/gui/feeds/FeedItem.h b/retroshare-gui/src/gui/feeds/FeedItem.h index 7cd6808a1..7739ac122 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.h +++ b/retroshare-gui/src/gui/feeds/FeedItem.h @@ -23,13 +23,15 @@ #include +class FeedHolder; + class FeedItem : public QWidget { Q_OBJECT public: /** Default Constructor */ - FeedItem(QWidget *parent = 0); + FeedItem(FeedHolder *fh,uint32_t feedId,QWidget *parent = 0); /** Default Destructor */ virtual ~FeedItem(); @@ -42,14 +44,25 @@ public: * would contain the same information. It should therefore sumarise the data represented by the item. */ virtual uint64_t uniqueIdentifier() const =0; + + static uint64_t hash64(const std::string& s); + +protected slots: + void removeItem(); + protected: virtual void doExpand(bool open) = 0; virtual void expandFill(bool /*first*/) {} + virtual void toggle() {} + uint64_t hash_64bits(const std::string& s) const; + + FeedHolder *mFeedHolder; + uint32_t mFeedId; signals: void sizeChanged(FeedItem *feedItem); - void feedItemDestroyed(FeedItem *feedItem); + void feedItemNeedsClosing(qulonglong); private: bool mWasExpanded; diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h index 1a0c56a70..266d1c019 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h @@ -53,7 +53,7 @@ protected: private slots: /* default stuff */ - void toggle(); + void toggle() override; void subscribeChannel(); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index cdb4eeaf2..af2116616 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -46,12 +46,14 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set& older_versions) : GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate) { + mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded init(messageId,older_versions) ; } GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set& older_versions) : GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate) { + mPost.mMeta.mMsgId.clear(); // security init(post.mMeta.mMsgId,older_versions) ; mPost = post ; } @@ -71,63 +73,9 @@ void GxsChannelPostItem::init(const RsGxsMessageId& messageId,const std::set v; - bool self = false; - - for(std::set::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) { /* 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 */ ui->titleLabel->setText(tr("Loading")); - ui->subjectLabel->clear(); ui->datetimelabel->clear(); ui->filelabel->clear(); ui->newCommentLabel->hide(); @@ -207,7 +154,7 @@ void GxsChannelPostItem::setup() ui->warning_label->hide(); ui->titleLabel->setMinimumWidth(100); - ui->subjectLabel->setMinimumWidth(100); + //ui->subjectLabel->setMinimumWidth(100); ui->warning_label->setMinimumWidth(100); ui->mainFrame->setProperty("new", false); @@ -326,12 +273,14 @@ void GxsChannelPostItem::loadMessage(const uint32_t &token) if (posts.size() == 1) { + std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl; setPost(posts[0]); } else if (cmts.size() == 1) { RsGxsComment cmt = cmts[0]; + std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl; ui->newCommentLabel->show(); ui->commLabel->show(); ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str())); @@ -428,7 +377,7 @@ void GxsChannelPostItem::fill() ui->titleLabel->setText(title); 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)) { @@ -451,10 +400,10 @@ void GxsChannelPostItem::fill() /* subject */ 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 - 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)) ; @@ -522,7 +471,13 @@ void GxsChannelPostItem::fill() 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()) { fillExpandFrame(); } @@ -531,7 +486,7 @@ void GxsChannelPostItem::fill() if ( (mPost.mCount != 0) || (mPost.mSize != 0) ) { 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 { ui->filelabel->setVisible(false); } @@ -575,6 +530,7 @@ void GxsChannelPostItem::fill() void GxsChannelPostItem::fillExpandFrame() { ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + } QString GxsChannelPostItem::messageName() diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h index 8b9d21c57..9955002fa 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h @@ -53,7 +53,7 @@ public: //GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate); 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 setPost(const RsGxsChannelPost &post, bool doFill = true); @@ -66,6 +66,7 @@ public: bool isUnread() const ; + static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { return hash64("GxsChannelPostItem " + msgid.toStdString()) ; } protected: void init(const RsGxsMessageId& messageId,const std::set& older_versions); @@ -90,7 +91,7 @@ protected: private slots: /* default stuff */ - void toggle(); + void toggle() override; void readAndClearItem(); void download(); void play(); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui index 01d113665..0e15c0a4d 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui @@ -6,8 +6,8 @@ 0 0 - 1359 - 342 + 1433 + 541 @@ -50,26 +50,30 @@ - - - - 0 - 0 - - - - - - - :/images/thumb-default-video.png - - - false - - - Qt::AlignCenter - - + + + + + + 0 + 0 + + + + + + + :/images/thumb-default-video.png + + + false + + + Qt::AlignCenter + + + + @@ -114,40 +118,17 @@ + + + + New + + + - - - - - - 0 - 0 - - - - Short Description - - - true - - - true - - - - - - - fileLabel - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - - + @@ -234,13 +215,6 @@ - - - - New - - - @@ -335,19 +309,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -368,6 +329,16 @@ + + + + fileLabel + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -387,6 +358,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp index aa161cde4..7673c6d19 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp @@ -40,7 +40,7 @@ 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(); } @@ -172,22 +172,6 @@ uint64_t GxsCircleItem::uniqueIdentifier() const 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) { #ifdef ID_DEBUG diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.h b/retroshare-gui/src/gui/feeds/GxsCircleItem.h index a45114ed6..8c611c06b 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.h +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.h @@ -65,9 +65,6 @@ protected: private slots: - /* default stuff */ - void removeItem(); - void showCircleDetails(); void acceptCircleSubscription(); void grantCircleMembership() ; @@ -76,8 +73,6 @@ private slots: private: void setup(); - FeedHolder *mFeedHolder; - uint32_t mFeedId; uint32_t mType; RsGxsCircleId mCircleId; diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp index 1e430638a..8b97d73cf 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp @@ -158,7 +158,6 @@ void GxsForumGroupItem::fill() ui->clearButton->setEnabled(false); } } - void GxsForumGroupItem::toggle() { expand(ui->expandFrame->isHidden()); diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h index 87bffa022..3ac198630 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h @@ -46,6 +46,7 @@ public: protected: /* FeedItem */ virtual void doExpand(bool open); + void toggle() override; /* GxsGroupFeedItem */ virtual QString groupName(); @@ -53,9 +54,6 @@ protected: virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; } private slots: - /* default stuff */ - void toggle(); - void subscribeForum(); private: diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h index be275aa07..332d5877e 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h @@ -43,7 +43,7 @@ public: bool setGroup(const RsGxsForumGroup &group, 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: /* FeedItem */ virtual void doExpand(bool open); @@ -67,7 +67,7 @@ protected: private slots: /* default stuff */ - void toggle(); + void toggle() override; void readAndClearItem(); void unsubscribeForum(); diff --git a/retroshare-gui/src/gui/feeds/MsgItem.cpp b/retroshare-gui/src/gui/feeds/MsgItem.cpp index c0dd8768e..181774a00 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/MsgItem.cpp @@ -43,7 +43,7 @@ /** Constructor */ 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 */ setupUi(this); @@ -222,15 +222,10 @@ void MsgItem::updateItem() } } -void MsgItem::toggle() -{ - expand(expandFrame->isHidden()); -} - void MsgItem::doExpand(bool open) { - if (mParent) { - mParent->lockLayout(this, true); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, true); } if (open) @@ -252,8 +247,8 @@ void MsgItem::doExpand(bool open) emit sizeChanged(this); - if (mParent) { - mParent->lockLayout(this, false); + if (mFeedHolder) { + 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() { @@ -315,7 +293,7 @@ void MsgItem::replyMsg() std::cerr << "MsgItem::replyMsg()"; std::cerr << std::endl; #endif - if (mParent) + if (mFeedHolder) { //mParent->openMsg(FEEDHOLDER_MSG_MESSAGE, mPeerId, mMsgId); @@ -339,6 +317,11 @@ void MsgItem::playMedia() #endif } +void MsgItem::toggle() +{ + expand(expandFrame->isHidden()); +} + void MsgItem::checkMessageReadStatus() { if (!mCloseOnRead) { diff --git a/retroshare-gui/src/gui/feeds/MsgItem.h b/retroshare-gui/src/gui/feeds/MsgItem.h index 469f8cbb7..32824ca23 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.h +++ b/retroshare-gui/src/gui/feeds/MsgItem.h @@ -50,7 +50,6 @@ private: private slots: /* default stuff */ void gotoHome(); - void removeItem(); void toggle(); void playMedia(); @@ -62,9 +61,6 @@ private slots: void updateItem(); private: - FeedHolder *mParent; - uint32_t mFeedId; - std::string mMsgId; QString mMsg; diff --git a/retroshare-gui/src/gui/feeds/PeerItem.cpp b/retroshare-gui/src/gui/feeds/PeerItem.cpp index 87d510e4b..2a6f0b19d 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.cpp +++ b/retroshare-gui/src/gui/feeds/PeerItem.cpp @@ -41,7 +41,7 @@ /** Constructor */ 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) { /* Invoke the Qt Designer generated object setup routine */ @@ -50,12 +50,12 @@ PeerItem::PeerItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, sendmsgButton->setEnabled(false); /* general ones */ - connect( expandButton, SIGNAL( clicked( void ) ), this, SLOT( toggle ( void ) ) ); - connect( clearButton, SIGNAL( clicked( void ) ), this, SLOT( removeItem ( void ) ) ); + connect( expandButton, SIGNAL( clicked() ), this, SLOT( toggle() ) ); + connect( clearButton, SIGNAL( clicked() ), this, SLOT( removeItem() ) ); /* specific ones */ - connect( chatButton, SIGNAL( clicked( void ) ), this, SLOT( openChat ( void ) ) ); - connect( sendmsgButton, SIGNAL( clicked( ) ), this, SLOT( sendMsg() ) ); + connect( chatButton, SIGNAL( clicked() ), this, SLOT( openChat() ) ); + connect( sendmsgButton, SIGNAL( clicked() ), this, SLOT( sendMsg() ) ); connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()), this, SLOT(updateItem())); @@ -225,7 +225,7 @@ void PeerItem::updateItem() /* slow Tick */ int msec_rate = 10129; - QTimer::singleShot( msec_rate, this, SLOT(updateItem( void ) )); + QTimer::singleShot( msec_rate, this, SLOT(updateItem() )); return; } @@ -236,8 +236,8 @@ void PeerItem::toggle() void PeerItem::doExpand(bool open) { - if (mParent) { - mParent->lockLayout(this, true); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, true); } if (open) @@ -255,25 +255,8 @@ void PeerItem::doExpand(bool open) emit sizeChanged(this); - if (mParent) { - mParent->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); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, false); } } @@ -321,9 +304,9 @@ void PeerItem::openChat() std::cerr << "PeerItem::openChat()"; std::cerr << std::endl; #endif - if (mParent) + if (mFeedHolder) { - mParent->openChat(mPeerId); + mFeedHolder->openChat(mPeerId); } } diff --git a/retroshare-gui/src/gui/feeds/PeerItem.h b/retroshare-gui/src/gui/feeds/PeerItem.h index 6e17fbae3..22b9bbaf0 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.h +++ b/retroshare-gui/src/gui/feeds/PeerItem.h @@ -51,8 +51,7 @@ protected: private slots: /* default stuff */ - void removeItem(); - void toggle(); + void toggle() override; void addFriend(); void removeFriend(); @@ -63,8 +62,6 @@ private slots: private: - FeedHolder *mParent; - uint32_t mFeedId; RsPeerId mPeerId; uint32_t mType; diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.h b/retroshare-gui/src/gui/feeds/PostedGroupItem.h index 999abf652..88e1906dc 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.h +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.h @@ -54,9 +54,7 @@ protected: virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; } private slots: - /* default stuff */ - void toggle(); - + void toggle() override; void subscribePosted(); private: diff --git a/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp b/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp index 40914fc7e..590bd0588 100644 --- a/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp @@ -40,14 +40,14 @@ /** Constructor */ 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)) { setup(); } 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)) { setup(); @@ -192,8 +192,8 @@ void SecurityIpItem::toggle() void SecurityIpItem::doExpand(bool open) { - if (mParent) { - mParent->lockLayout(this, true); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, true); } if (open) @@ -211,25 +211,8 @@ void SecurityIpItem::doExpand(bool open) emit sizeChanged(this); - if (mParent) { - mParent->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); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, false); } } diff --git a/retroshare-gui/src/gui/feeds/SecurityIpItem.h b/retroshare-gui/src/gui/feeds/SecurityIpItem.h index d4648ab0a..bfef10634 100644 --- a/retroshare-gui/src/gui/feeds/SecurityIpItem.h +++ b/retroshare-gui/src/gui/feeds/SecurityIpItem.h @@ -54,16 +54,12 @@ private: private slots: /* default stuff */ - void removeItem(); - void toggle(); + void toggle() override; void peerDetails(); void updateItem(); void banIpListChanged(const QString &ipAddress); private: - FeedHolder *mParent; - uint32_t mFeedId; - uint32_t mType; RsPeerId mSslId; std::string mIpAddr; diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.cpp b/retroshare-gui/src/gui/feeds/SecurityItem.cpp index b5aa9d8a4..aedfd4e6c 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityItem.cpp @@ -44,7 +44,7 @@ /** 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) : - FeedItem(NULL), mParent(parent), mFeedId(feedId), + FeedItem(parent,feedId,NULL), mGpgId(gpgId), mSslId(sslId), mSslCn(sslCn), mIP(ip_address), mType(type), mIsHome(isHome) { /* Invoke the Qt Designer generated object setup routine */ @@ -288,8 +288,8 @@ void SecurityItem::toggle() void SecurityItem::doExpand(bool open) { - if (mParent) { - mParent->lockLayout(this, true); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, true); } if (open) @@ -307,25 +307,8 @@ void SecurityItem::doExpand(bool open) emit sizeChanged(this); - if (mParent) { - mParent->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); + if (mFeedHolder) { + mFeedHolder->lockLayout(this, false); } } @@ -413,8 +396,8 @@ void SecurityItem::openChat() std::cerr << "SecurityItem::openChat()"; std::cerr << std::endl; #endif - if (mParent) + if (mFeedHolder) { - mParent->openChat(mSslId); + mFeedHolder->openChat(mSslId); } } diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.h b/retroshare-gui/src/gui/feeds/SecurityItem.h index 1c9bbe054..7f99c8377 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.h +++ b/retroshare-gui/src/gui/feeds/SecurityItem.h @@ -50,8 +50,7 @@ protected: private slots: /* default stuff */ - void removeItem(); - void toggle(); + void toggle() override; void friendRequest(); void removeFriend(); @@ -62,9 +61,6 @@ private slots: void updateItem(); private: - FeedHolder *mParent; - uint32_t mFeedId; - RsPgpId mGpgId; RsPeerId mSslId; std::string mSslCn; diff --git a/retroshare-gui/src/gui/gxs/GxsFeedWidget.cpp b/retroshare-gui/src/gui/gxs/GxsFeedWidget.cpp index 9ccaa55fa..e714b5347 100644 --- a/retroshare-gui/src/gui/gxs/GxsFeedWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsFeedWidget.cpp @@ -46,8 +46,6 @@ void GxsFeedWidget::feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem) void GxsFeedWidget::feedRemoved(FeedItem *feedItem) { - RSFeedWidget::feedRemoved(feedItem); - GxsFeedItem *gxsFeedItem = dynamic_cast(feedItem); if (!gxsFeedItem) { return; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp index 59ff10056..1f5b09cb8 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp @@ -32,7 +32,7 @@ **/ 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 std::cerr << "GxsGroupFeedItem::GxsGroupFeedItem()"; @@ -40,8 +40,6 @@ GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, cons #endif /* this are just generally useful for all children */ - mFeedHolder = feedHolder; - mFeedId = feedId; mIsHome = isHome; /* load data if we can */ @@ -93,27 +91,6 @@ bool GxsGroupFeedItem::initLoadQueue() 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() { #ifdef DEBUG_ITEM diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h index ac851a97d..9696490d9 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h @@ -64,12 +64,9 @@ protected: protected slots: void subscribe(); void unsubscribe(); - void removeItem(); void copyGroupLink(); protected: - FeedHolder *mFeedHolder; - uint32_t mFeedId; bool mIsHome; RsGxsIfaceHelper *mGxsIface; TokenQueue *mLoadQueue; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index f346b3470..2e1b6dc7e 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -52,17 +52,15 @@ GxsChannelDialog::GxsChannelDialog(QWidget *parent) { mEventHandlerId = 0; // Needs to be asynced because this function is likely to be called by another thread! - rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + rsEvents->registerEventsHandler(RsEventType::GXS_CHANNELS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); } void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr event) { - if(event->mType == RsEventType::GXS_CHANNELS) - { - const RsGxsChannelEvent *e = dynamic_cast(event.get()); + const RsGxsChannelEvent *e = dynamic_cast(event.get()); - if(!e) - return; + if(!e) + return; switch(e->mChannelEventCode) { @@ -71,7 +69,6 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr ev default: break; } - } } GxsChannelDialog::~GxsChannelDialog() diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp index d463170af..7985d6489 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp @@ -132,17 +132,15 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid mEventHandlerId = 0; // Needs to be asynced because this function is likely to be called by another thread! - rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + rsEvents->registerEventsHandler(RsEventType::GXS_CHANNELS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); } void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr event) { - if(event->mType == RsEventType::GXS_CHANNELS) - { - const RsGxsChannelEvent *e = dynamic_cast(event.get()); + const RsGxsChannelEvent *e = dynamic_cast(event.get()); - if(!e) - return; + if(!e) + return; switch(e->mChannelEventCode) { @@ -156,7 +154,6 @@ void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptrfeedWidget->removeFeedItem(feedItem); } void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/) @@ -460,7 +461,7 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re 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(feedItem); if(item) @@ -476,7 +477,7 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re 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(feedItem); } if (item) { @@ -669,7 +670,7 @@ void GxsChannelPostsWidget::blank() bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId) { - FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(groupId(), msgId); + FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(msgId)); if (!feedItem) { return false; } @@ -718,17 +719,17 @@ void GxsChannelPostsWidget::toggleAutoDownload() return; } - RsQThreadUtils::postToObject( [=]() - { - /* 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 - * after a blocking call to RetroShare API complete, note that - * Qt::QueuedConnection is important! - */ - - std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI " - << "thread but was scheduled by async thread" << std::endl; - }, this ); +// RsQThreadUtils::postToObject( [=]() +// { +// /* 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 +// * after a blocking call to RetroShare API complete, note that +// * Qt::QueuedConnection is important! +// */ +// +// std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI " +// << "thread but was scheduled by async thread" << std::endl; +// }, this ); }); } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h index a4723c18f..6f27ed677 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h @@ -58,7 +58,7 @@ public: /* FeedHolder */ 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 openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &msg_versions, const RsGxsMessageId &msgId, const QString &title); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui index 59703a0d7..fb6845f26 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui @@ -6,8 +6,8 @@ 0 0 - 880 - 557 + 977 + 628 @@ -369,7 +369,7 @@ <!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"> 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> @@ -525,7 +525,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -572,22 +572,22 @@ p, li { white-space: pre-wrap; } QLineEdit
gui/common/LineEditClear.h
- - GxsFeedWidget - QWidget -
gui/gxs/GxsFeedWidget.h
- 1 -
GxsChannelFilesWidget QWidget
gui/gxschannels/GxsChannelFilesWidget.h
1
+ + RSFeedWidget + QWidget +
gui/common/RSFeedWidget.h
+ 1 +
- + diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index f1306f79b..f57d29119 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -436,7 +436,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget mEventHandlerId = 0; // Needs to be asynced because this function is likely to be called by another thread! - rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + rsEvents->registerEventsHandler(RsEventType::GXS_FORUMS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); } void GxsForumThreadWidget::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index aa4177a72..2282db1bb 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -45,7 +45,7 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) mEventHandlerId = 0; // Needs to be asynced because this function is likely to be called by another thread! - rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + rsEvents->registerEventsHandler(RsEventType::GXS_FORUMS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); } void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp index d8da057e6..08ecf18c6 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp @@ -19,6 +19,7 @@ *******************************************************************************/ #include "AspectRatioPixmapLabel.h" +#include AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : QLabel(parent) @@ -30,7 +31,8 @@ AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : void AspectRatioPixmapLabel::setPixmap ( const QPixmap & 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 @@ -40,8 +42,7 @@ int AspectRatioPixmapLabel::heightForWidth( int width ) const QSize AspectRatioPixmapLabel::sizeHint() const { - int w = this->width(); - return QSize( w, heightForWidth(w) ); + return QSize(pix.width(), pix.height()); } QPixmap AspectRatioPixmapLabel::scaledPixmap() const @@ -53,4 +54,6 @@ void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e) { if(!pix.isNull()) 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; } diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.h b/retroshare-gui/src/util/AspectRatioPixmapLabel.h index f04dc619a..ad7c40e4c 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.h +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.h @@ -29,15 +29,16 @@ class AspectRatioPixmapLabel : public QLabel { Q_OBJECT public: - explicit AspectRatioPixmapLabel(QWidget *parent = 0); - virtual int heightForWidth( int width ) const; - virtual QSize sizeHint() const; + explicit AspectRatioPixmapLabel(QWidget *parent = nullptr); + virtual int heightForWidth( int width ) const override; + virtual QSize sizeHint() const override; QPixmap scaledPixmap() const; public slots: void setPixmap ( const QPixmap & ); - void resizeEvent(QResizeEvent *); +protected: + void resizeEvent(QResizeEvent *event) override; private: QPixmap pix; }; -#endif // ASPECTRATIOPIXMAPLABEL_H \ No newline at end of file +#endif // ASPECTRATIOPIXMAPLABEL_H diff --git a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp index bd2d647f5..934226da4 100644 --- a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp +++ b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp @@ -39,11 +39,9 @@ RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl) : { mEventHandlerId = 0; // forces initialization in registerEventsHandler() - rsEvents->registerEventsHandler( [this](std::shared_ptr event) + rsEvents->registerEventsHandler(RsEventType::GXS_CHANGES, [this](std::shared_ptr event) { - if(event->mType == RsEventType::GXS_CHANGES) - onChangesReceived(*dynamic_cast(event.get())); - + onChangesReceived(*dynamic_cast(event.get())); }, mEventHandlerId ); }