From b8075d65bd716c76d793ec2eb0af57e59e62d290 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 10 Apr 2016 18:53:49 -0400 Subject: [PATCH 01/16] skip circle vetting when sending message posts with no author --- libretroshare/src/gxs/rsgxsnetservice.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 5947efee0..c5651e96e 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4602,11 +4602,13 @@ bool RsGxsNetService::canSendMsgIds(std::vector& msgMetas, co should_encrypt_id = circleId ; // For each message ID, check that the author is in the circle. If not, do not send the message, which means, remove it from the list. + // Unsigned messages are still transmitted. This is because in some groups (channels) the posts are not signed. Whether an unsigned post + // is allowed at this point is anyway already vetted by the RsGxsGenExchange service. if(mCircles->isLoaded(circleId)) { for(uint32_t i=0;iisRecipient(circleId, msgMetas[i]->mAuthorId)) + if( (!msgMetas[i]->mAuthorId.isNull()) && !mCircles->isRecipient(circleId, msgMetas[i]->mAuthorId)) { #ifdef NXS_NET_DEBUG_4 GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " deleting MsgMeta entry for msg ID " << msgMetas[i]->mMsgId << " signed by " << msgMetas[i]->mAuthorId << " who is not in group circle " << circleId << std::endl; From 0d5b9ae0d1f39de611f800992ecfdf2c7c5bf7fd Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 10 Apr 2016 18:55:05 -0400 Subject: [PATCH 02/16] fixed last commit --- libretroshare/src/gxs/rsgxsnetservice.cc | 110 ++++++++++------------- 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index c5651e96e..617b2d593 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4570,94 +4570,76 @@ void RsGxsNetService::locked_pushMsgRespFromList(std::list& itemL, c bool RsGxsNetService::canSendMsgIds(std::vector& msgMetas, const RsGxsGrpMetaData& grpMeta, const RsPeerId& sslId,RsGxsCircleId& should_encrypt_id) { #ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendMsgIds() CIRCLE VETTING" << std::endl; + GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendMsgIds() CIRCLE VETTING" << std::endl; #endif - // first do the simple checks - uint8_t circleType = grpMeta.mCircleType; + // first do the simple checks + uint8_t circleType = grpMeta.mCircleType; - if(circleType == GXS_CIRCLE_TYPE_LOCAL) - { + if(circleType == GXS_CIRCLE_TYPE_LOCAL) + { #ifdef NXS_NET_DEBUG_4 GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: LOCAL => returning false" << std::endl; #endif return false; - } + } - if(circleType == GXS_CIRCLE_TYPE_PUBLIC) - { + if(circleType == GXS_CIRCLE_TYPE_PUBLIC) + { #ifdef NXS_NET_DEBUG_4 GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: PUBLIC => returning true" << std::endl; #endif return true; - } + } - const RsGxsCircleId& circleId = grpMeta.mCircleId; + const RsGxsCircleId& circleId = grpMeta.mCircleId; - if(circleType == GXS_CIRCLE_TYPE_EXTERNAL) - { + if(circleType == GXS_CIRCLE_TYPE_EXTERNAL) + { #ifdef NXS_NET_DEBUG_4 GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs ids list will be encrypted." << std::endl; #endif should_encrypt_id = circleId ; - - // For each message ID, check that the author is in the circle. If not, do not send the message, which means, remove it from the list. - // Unsigned messages are still transmitted. This is because in some groups (channels) the posts are not signed. Whether an unsigned post - // is allowed at this point is anyway already vetted by the RsGxsGenExchange service. - - if(mCircles->isLoaded(circleId)) - { - for(uint32_t i=0;imAuthorId.isNull()) && !mCircles->isRecipient(circleId, msgMetas[i]->mAuthorId)) - { + + // For each message ID, check that the author is in the circle. If not, do not send the message, which means, remove it from the list. + // Unsigned messages are still transmitted. This is because in some groups (channels) the posts are not signed. Whether an unsigned post + // is allowed at this point is anyway already vetted by the RsGxsGenExchange service. + + // Messages that stay in the list will be sent. As a consequence true is always returned. + // Messages put in vetting list will be dealt with later + + std::vector toVet; + + for(uint32_t i=0;imAuthorId.isNull() ) // keep the message in this case + ++i ; + else + { + if(mCircles->isLoaded(circleId) && mCircles->isRecipient(circleId, msgMetas[i]->mAuthorId)) + { + ++i ; + continue ; + } + + MsgIdCircleVet mic(msgMetas[i]->mMsgId, msgMetas[i]->mAuthorId); + toVet.push_back(mic); #ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " deleting MsgMeta entry for msg ID " << msgMetas[i]->mMsgId << " signed by " << msgMetas[i]->mAuthorId << " who is not in group circle " << circleId << std::endl; + GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " deleting MsgMeta entry for msg ID " << msgMetas[i]->mMsgId << " signed by " << msgMetas[i]->mAuthorId << " who is not in group circle " << circleId << std::endl; #endif - delete msgMetas[i] ; - msgMetas[i] = msgMetas[msgMetas.size()-1] ; - msgMetas.pop_back() ; - } - else - ++i ; - - return true ; - } - -#ifdef TO_BE_REMOVED_OLD_VETTING_FOR_EXTERNAL_CIRCLES -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL. Circle Id: " << circleId << std::endl; -#endif - if(mCircles->isLoaded(circleId)) - { - const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId); - bool res = mCircles->canSend(circleId, pgpId); -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Answer from circle::canSend(): " << res << std::endl; -#endif - return res ; - } -#endif + delete msgMetas[i] ; + msgMetas[i] = msgMetas[msgMetas.size()-1] ; + msgMetas.pop_back() ; + } #ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle info not loaded. Putting in vetting list and returning false." << std::endl; + GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle info not loaded. Putting in vetting list and returning false." << std::endl; #endif - std::vector toVet; - std::vector::const_iterator vit = msgMetas.begin(); + if(!toVet.empty()) + mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils, toVet, grpMeta.mGroupId, sslId, grpMeta.mCircleId)); - for(; vit != msgMetas.end(); ++vit) - { - const RsGxsMsgMetaData* const& meta = *vit; - - MsgIdCircleVet mic(meta->mMsgId, meta->mAuthorId); - toVet.push_back(mic); - } - - if(!toVet.empty()) - mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils, toVet, grpMeta.mGroupId, sslId, grpMeta.mCircleId)); - - return false; - } + return true ; + } if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY) { @@ -4723,7 +4705,7 @@ bool RsGxsNetService::canSendMsgIds(std::vector& msgMetas, co } } - return true; + return false; } /** inherited methods **/ From c97f197b7e6e98740278d9192f92d11bf8dcece5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 10 Apr 2016 20:39:08 -0400 Subject: [PATCH 03/16] removed depth obfucation of search results and replaced by 0 always, effectively removing any information about search depth (idea by AC) --- libretroshare/src/turtle/p3turtle.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 6f991aa6d..6d0536b0e 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -1017,8 +1017,6 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item) // Is this result's target actually ours ? - ++(item->depth) ; // increase depth - if(it->second.origin == _own_id) returnSearchResult(item) ; // Yes, so send upward. else @@ -1032,7 +1030,7 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item) // of the files found can be further reached by a tunnel. fwd_item->PeerId(it->second.origin) ; - fwd_item->depth = 2 + (rand() % 256) ; // obfuscate the depth for non immediate friends. + fwd_item->depth = 0 ; // obfuscate the depth for non immediate friends. Result will always be 0. This effectively removes the information. sendItem(fwd_item) ; } From b148239e4f41a526407c7004696fd0c83c75d4aa Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 10 Apr 2016 21:09:47 -0400 Subject: [PATCH 04/16] always pass data accept test in distant chat when we are on the client side of the tunnel --- libretroshare/src/chat/distantchat.cc | 5 ++++- libretroshare/src/chat/distantchat.h | 2 +- libretroshare/src/gxstunnel/p3gxstunnel.cc | 5 ++++- libretroshare/src/retroshare/rsgxstunnel.h | 3 ++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/chat/distantchat.cc b/libretroshare/src/chat/distantchat.cc index 113dd21c5..03acb6ff8 100644 --- a/libretroshare/src/chat/distantchat.cc +++ b/libretroshare/src/chat/distantchat.cc @@ -124,10 +124,13 @@ void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs) std::cerr << "DistantChatService::handleRecvChatStatusItem(): received keep alive packet for inactive chat! peerId=" << cs->PeerId() << std::endl; } -bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id) +bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool is_client_side) { bool res = true ; + if(is_client_side) // always accept distant chat when we're the client side. + return true ; + if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS) res = (rsIdentity!=NULL) && rsIdentity->isARegularContact(gxs_id) ; diff --git a/libretroshare/src/chat/distantchat.h b/libretroshare/src/chat/distantchat.h index 8b159c56a..5dc21e1d6 100644 --- a/libretroshare/src/chat/distantchat.h +++ b/libretroshare/src/chat/distantchat.h @@ -89,7 +89,7 @@ public: virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ; private: - virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelService::RsGxsTunnelId& tunnel_id) ; + virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelService::RsGxsTunnelId& tunnel_id, bool is_client_side) ; virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ; virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ; diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 4539c0847..eb0c32812 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -349,6 +349,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id RsGxsTunnelClientService *service = NULL ; RsGxsId peer_from ; + bool is_client_side = false ; { RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ @@ -367,6 +368,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id { it2->second.client_services.insert(item->service_id) ; peer_from = it2->second.to_gxs_id ; + is_client_side = (it2->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT); } // Check if the item has already been received. This is necessary because we actually re-send items until an ACK is received. If the ACK gets lost (connection interrupted) the @@ -380,7 +382,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id it2->second.received_data_prints[item->unique_item_counter] = time(NULL) ; } - if(service->acceptDataFromPeer(peer_from,tunnel_id)) + if(service->acceptDataFromPeer(peer_from,tunnel_id,is_client_side)) service->receiveData(tunnel_id,item->data,item->data_size) ; item->data = NULL ; // avoids deletion, since the client has the memory now @@ -1474,6 +1476,7 @@ bool p3GxsTunnelService::getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelI info.tunnel_status = it->second.status; info.total_size_sent = it->second.total_sent; info.total_size_received= it->second.total_received; + info.is_client_side = (it->second.direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT); // Data packets diff --git a/libretroshare/src/retroshare/rsgxstunnel.h b/libretroshare/src/retroshare/rsgxstunnel.h index 94f4c79fe..4d3588c9f 100644 --- a/libretroshare/src/retroshare/rsgxstunnel.h +++ b/libretroshare/src/retroshare/rsgxstunnel.h @@ -66,7 +66,7 @@ public: // Gives feedback about type of data that is allowed in. For security reasons, this always needs to be re-derived (Clients can return true on default) - virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id) = 0 ; + virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool is_client_side) = 0 ; }; class GxsTunnelInfo @@ -80,6 +80,7 @@ public: uint32_t tunnel_status ; // active, requested, DH pending, etc. uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management). uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management). + bool is_client_side ; // specifiec wether we are client(managing the tunnel) or server. // Data packets From a52bd98d4bf1f6099964af5876d406689d931611 Mon Sep 17 00:00:00 2001 From: Cyril Soler Date: Mon, 11 Apr 2016 10:10:10 -0400 Subject: [PATCH 05/16] fixed potential div by 0 in speed estimations. To be tested. --- libretroshare/src/pqi/pqistreamer.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/pqi/pqistreamer.cc b/libretroshare/src/pqi/pqistreamer.cc index b4d2c1f40..f60e21d45 100644 --- a/libretroshare/src/pqi/pqistreamer.cc +++ b/libretroshare/src/pqi/pqistreamer.cc @@ -183,8 +183,10 @@ void pqistreamer::updateRates() if (t > mAvgLastUpdate + PQISTREAM_AVG_PERIOD) { - float avgReadpSec = getRate(true) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1000.0 * (t - mAvgLastUpdate)); - float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1000.0 * (t - mAvgLastUpdate)); + int64_t diff = int64_t(t) - int64_t(mAvgLastUpdate) ; + + float avgReadpSec = getRate(true) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1000.0 * float(diff)); + float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1000.0 * float(diff)); #ifdef DEBUG_PQISTREAMER std::cerr << "Peer " << PeerId() << ": Current speed estimates: " << avgReadpSec << " / " << avgSentpSec << std::endl; From 6b2de05e89c23697c4e82546c8e17a7038ba8e77 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 11 Apr 2016 22:42:02 -0400 Subject: [PATCH 06/16] added channel admin and distribution method in channel summary page --- .../gui/gxschannels/GxsChannelPostsWidget.cpp | 32 ++++++ .../gui/gxschannels/GxsChannelPostsWidget.ui | 104 +++++++++++++++--- 2 files changed, 120 insertions(+), 16 deletions(-) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp index 15cb71092..648de299e 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp @@ -22,6 +22,8 @@ #include #include +#include "retroshare/rsgxscircles.h" + #include "GxsChannelPostsWidget.h" #include "ui_GxsChannelPostsWidget.h" #include "gui/feeds/GxsChannelPostItem.h" @@ -265,6 +267,36 @@ void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group) } else { ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount)); ui->infoDescription->setText(QString::fromUtf8(group.mDescription.c_str())); + + ui->infoAdministrator->setId(group.mMeta.mAuthorId) ; + + QString distrib_string ( "[unknown]" ); + + switch(group.mMeta.mCircleType) + { + case GXS_CIRCLE_TYPE_PUBLIC: distrib_string = tr("Public") ; + break ; + case GXS_CIRCLE_TYPE_EXTERNAL: + { + RsGxsCircleDetails det ; + + // !! What we need here is some sort of CircleLabel, which loads the circle and updates the label when done. + + if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,det)) + distrib_string = tr("Restricted to members of circle \"")+QString::fromUtf8(det.mCircleName.c_str()) +"\""; + else + distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ; + } + break ; + case GXS_CIRCLE_TYPE_YOUREYESONLY: distrib_string = tr("Your eyes only"); + break ; + case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes"); + break ; + default: + std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl; + } + + ui->infoDistribution->setText(distrib_string); ui->infoWidget->show(); ui->feedWidget->hide(); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui index d91812fca..bdb6ca5d2 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui @@ -6,7 +6,7 @@ 0 0 - 681 + 793 465 @@ -14,7 +14,16 @@ 4 - + + 0 + + + 0 + + + 0 + + 0 @@ -26,7 +35,16 @@ QFrame::Sunken - + + 4 + + + 4 + + + 4 + + 4 @@ -289,7 +307,16 @@ - + + 3 + + + 3 + + + 3 + + 3 @@ -370,15 +397,8 @@ - - - - 0 - - - - + 75 @@ -386,7 +406,7 @@ - Description: + Administrator: @@ -409,14 +429,14 @@ - + <!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;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Description</p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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> Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse @@ -426,6 +446,53 @@ p, li { white-space: pre-wrap; } + + + + + 75 + true + + + + Description: + + + + + + + unknown + + + + + + + 0 + + + + + + + + 75 + true + + + + Distribution: + + + + + + + unknown + + + @@ -485,6 +552,11 @@ p, li { white-space: pre-wrap; } infoWidget + + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
StyledElidedLabel QLabel From 8f9028dc52cf8cadb5a9d6a5d5a664b3fe18953a Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 11 Apr 2016 23:30:42 -0400 Subject: [PATCH 07/16] fixed bug in GxsIdLabel due to not removign existing jobs for a given widget before setting it to a new ID --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 71 ++++++++++++++------- retroshare-gui/src/gui/gxs/GxsIdDetails.h | 3 +- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 5666a35b7..0a9736f6d 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -69,6 +69,7 @@ GxsIdDetails::GxsIdDetails() { mCheckTimerId = 0; mProcessDisableCount = 0; + mPendingDataIterator = mPendingData.end() ; connect(this, SIGNAL(startTimerFromThread()), this, SLOT(doStartTimer())); } @@ -106,16 +107,16 @@ void GxsIdDetails::objectDestroyed(QObject *object) /* Object is about to be destroyed, remove it from pending list */ QList::iterator dataIt; - for (dataIt = mPendingData.begin(); dataIt != mPendingData.end(); ) { - CallbackData &pendingData = *dataIt; - - if (pendingData.mObject == object) { - dataIt = mPendingData.erase(dataIt); - continue; - } - - ++dataIt; - } + + QMap::iterator it = mPendingData.find(object) ; + + if(it != mPendingData.end()) + { + if(it == mPendingDataIterator) + mPendingDataIterator = mPendingData.erase(it) ; + else + mPendingData.erase(it) ; + } } void GxsIdDetails::connectObject_locked(QObject *object, bool doConnect) @@ -125,13 +126,9 @@ void GxsIdDetails::connectObject_locked(QObject *object, bool doConnect) } /* Search Object in pending list */ - QList::iterator dataIt; - for (dataIt = mPendingData.begin(); dataIt != mPendingData.end(); ++dataIt) { - if (dataIt->mObject == object) { - /* Object still/already in pending list */ - return; - } - } + + if(mPendingData.find(object) != mPendingData.end()) + return ; if (doConnect) { connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*))); @@ -155,12 +152,16 @@ void GxsIdDetails::timerEvent(QTimerEvent *event) if (!mPendingData.empty()) { /* Check pending id's */ int processed = qMin(MAX_PROCESS_COUNT_PER_TIMER, mPendingData.size()); + while (!mPendingData.isEmpty()) { if (processed-- <= 0) { break; } + + if(mPendingDataIterator == mPendingData.end()) + mPendingDataIterator = mPendingData.begin() ; - CallbackData &pendingData = mPendingData.front(); + CallbackData &pendingData = *mPendingDataIterator; RsIdentityDetails details; if (rsIdentity->getIdDetails(pendingData.mId, details)) { @@ -168,7 +169,8 @@ void GxsIdDetails::timerEvent(QTimerEvent *event) pendingData.mCallback(GXS_ID_DETAILS_TYPE_DONE, details, pendingData.mObject, pendingData.mData); QObject *object = pendingData.mObject; - mPendingData.pop_front(); + mPendingDataIterator = mPendingData.erase(mPendingDataIterator); + connectObject_locked(object, false); continue; @@ -180,13 +182,16 @@ void GxsIdDetails::timerEvent(QTimerEvent *event) pendingData.mCallback(GXS_ID_DETAILS_TYPE_FAILED, details, pendingData.mObject, pendingData.mData); QObject *object = pendingData.mObject; - mPendingData.pop_front(); + mPendingDataIterator = mPendingData.erase(mPendingDataIterator); + connectObject_locked(object, false); continue; } - - mPendingData.move(0, mPendingData.size() - 1); + + ++mPendingDataIterator ; + + //mPendingData.move(0, mPendingData.size() - 1); } } } @@ -246,6 +251,22 @@ bool GxsIdDetails::process(const RsGxsId &id, GxsIdDetailsCallbackFunction callb return true; } + // remove any existing call for this object. This is needed for when the same widget is used to display IDs that vary in time. + { + QMutexLocker lock(&mInstance->mMutex); + + // check if a pending request is not already on its way. If so, replace it. + + QMap::iterator it = mInstance->mPendingData.find(object) ; + + if(it != mInstance->mPendingData.end()) + { + mInstance->connectObject_locked(object, false); + mInstance->mPendingData.erase(it) ; + } + + /* Connect signal "destroy" */ + } /* Try to get the information */ // the idea behind this was, to call the callback directly when the identity is already loaded in librs // without one timer tick, but it causes the use of Pixmap in avatars within a threat that is different than @@ -277,10 +298,12 @@ bool GxsIdDetails::process(const RsGxsId &id, GxsIdDetailsCallbackFunction callb { QMutexLocker lock(&mInstance->mMutex); + // check if a pending request is not already on its way. If so, replace it. + + mInstance->mPendingData[object] = pendingData; + /* Connect signal "destroy" */ mInstance->connectObject_locked(object, true); - - mInstance->mPendingData.push_back(pendingData); } /* Start timer */ diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h index 3c9259ff3..ef15c5fdd 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h @@ -132,7 +132,8 @@ protected: static GxsIdDetails *mInstance; /* Pending data */ - QList mPendingData; + QMap mPendingData; + QMap::iterator mPendingDataIterator; int mCheckTimerId; int mProcessDisableCount; From d5ed84ec9de3652c2d11ab69afc8953eb57a2006 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 11 Apr 2016 23:43:18 -0400 Subject: [PATCH 08/16] allow one to change the contact author of a circle --- retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp index 2fc458752..0918c898e 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp @@ -624,12 +624,12 @@ void CreateCircleDialog::updateCircleGUI() } else { - std::set ids ; - ids.insert(mCircleGroup.mMeta.mAuthorId) ; + //std::set ids ; + //ids.insert(mCircleGroup.mMeta.mAuthorId) ; ui.idChooser->setDefaultId(mCircleGroup.mMeta.mAuthorId) ; ui.idChooser->setChosenId(mCircleGroup.mMeta.mAuthorId) ; - ui.idChooser->setIdConstraintSet(ids) ; - ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE) ; + //ui.idChooser->setIdConstraintSet(ids) ; + ui.idChooser->setFlags(IDCHOOSER_NO_CREATE) ; ui.circleAdminLabel->setVisible(false) ; } } From cf746f160c610a41418c591b0e2896a286938c7d Mon Sep 17 00:00:00 2001 From: Cyril Soler Date: Tue, 12 Apr 2016 10:06:01 -0400 Subject: [PATCH 09/16] fixed possible crash in GxsIdDetails --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 0a9736f6d..8fa66df62 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -127,8 +127,8 @@ void GxsIdDetails::connectObject_locked(QObject *object, bool doConnect) /* Search Object in pending list */ - if(mPendingData.find(object) != mPendingData.end()) - return ; + if(mPendingData.find(object) == mPendingData.end()) // force disconnect when not in the list + doConnect = false ; if (doConnect) { connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*))); @@ -169,10 +169,10 @@ void GxsIdDetails::timerEvent(QTimerEvent *event) pendingData.mCallback(GXS_ID_DETAILS_TYPE_DONE, details, pendingData.mObject, pendingData.mData); QObject *object = pendingData.mObject; - mPendingDataIterator = mPendingData.erase(mPendingDataIterator); - connectObject_locked(object, false); + mPendingDataIterator = mPendingData.erase(mPendingDataIterator); + continue; } @@ -182,10 +182,10 @@ void GxsIdDetails::timerEvent(QTimerEvent *event) pendingData.mCallback(GXS_ID_DETAILS_TYPE_FAILED, details, pendingData.mObject, pendingData.mData); QObject *object = pendingData.mObject; - mPendingDataIterator = mPendingData.erase(mPendingDataIterator); - connectObject_locked(object, false); + mPendingDataIterator = mPendingData.erase(mPendingDataIterator); + continue; } From d512c4a35ac2525f60acf4e60d285a5c55c85775 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 12 Apr 2016 22:59:12 -0400 Subject: [PATCH 10/16] enabled new link type for posted (patch from Fanch) --- retroshare-gui/src/gui/Posted/PostedDialog.h | 2 +- retroshare-gui/src/gui/RetroShareLink.cpp | 91 ++++++++++++++++++- retroshare-gui/src/gui/RetroShareLink.h | 3 +- .../src/gui/feeds/PostedGroupItem.cpp | 10 +- retroshare-gui/src/util/HandleRichText.cpp | 2 + 5 files changed, 98 insertions(+), 10 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index c0744723b..a90ac6ea7 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -46,7 +46,7 @@ public: protected: virtual QString getHelpString() const ; - virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; } + virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_POSTED; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Posted; } virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata); diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 384976bef..0f1902b6f 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -38,6 +38,7 @@ #include "MainWindow.h" #include "gui/gxsforums/GxsForumsDialog.h" #include "gui/gxschannels/GxsChannelDialog.h" +#include "gui/Posted/PostedDialog.h" #include "gui/FileTransfer/SearchDialog.h" #include "msgs/MessageComposer.h" #include "util/misc.h" @@ -61,11 +62,12 @@ #define HOST_PERSON "person" #define HOST_FORUM "forum" #define HOST_CHANNEL "channel" +#define HOST_POSTED "posted" #define HOST_MESSAGE "message" #define HOST_SEARCH "search" #define HOST_CERTIFICATE "certificate" #define HOST_PUBLIC_MSG "public_msg" -#define HOST_REGEXP "file|extra|person|forum|channel|search|message|certificate|private_chat|public_msg" +#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg" #define FILE_NAME "name" #define FILE_SIZE "size" @@ -83,6 +85,11 @@ #define CHANNEL_ID "id" #define CHANNEL_MSGID "msgid" +#define POSTED_NAME "name" +#define POSTED_ID "id" +#define POSTED_MSGID "msgid" + + #define MESSAGE_ID "id" #define MESSAGE_SUBJECT "subject" @@ -280,6 +287,15 @@ void RetroShareLink::fromUrl(const QUrl& url) return; } + if (url.host() == HOST_POSTED) { + _type = TYPE_POSTED; + _name = decodedQueryItemValue(urlQuery, POSTED_NAME); + _hash = urlQuery.queryItemValue(POSTED_ID); + _msgId = urlQuery.queryItemValue(POSTED_MSGID); + check(); + return; + } + if (url.host() == HOST_SEARCH) { _type = TYPE_SEARCH; _name = decodedQueryItemValue(urlQuery, SEARCH_KEYWORDS); @@ -579,6 +595,16 @@ void RetroShareLink::check() if(_hash.isEmpty()) _valid = false; break; + case TYPE_POSTED: + if(_size != 0) + _valid = false; + + if(_name.isEmpty()) + _valid = false; + + if(_hash.isEmpty()) + _valid = false; + break; case TYPE_SEARCH: if(_size != 0) _valid = false; @@ -629,6 +655,7 @@ QString RetroShareLink::title() const return PeerDefs::rsidFromId(RsPgpId(hash().toStdString())); case TYPE_FORUM: case TYPE_CHANNEL: + case TYPE_POSTED: case TYPE_SEARCH: break; case TYPE_MESSAGE: @@ -724,6 +751,17 @@ QString RetroShareLink::toString() const break; + case TYPE_POSTED: + url.setScheme(RSLINK_SCHEME); + url.setHost(HOST_POSTED); + urlQuery.addQueryItem(POSTED_NAME, encodeItem(_name)); + urlQuery.addQueryItem(POSTED_ID, _hash); + if (!_msgId.isEmpty()) { + urlQuery.addQueryItem(POSTED_MSGID, _msgId); + } + + break; + case TYPE_SEARCH: url.setScheme(RSLINK_SCHEME); url.setHost(HOST_SEARCH); @@ -969,6 +1007,7 @@ static void processList(const QStringList &list, const QString &textSingular, co case TYPE_UNKNOWN: case TYPE_FORUM: case TYPE_CHANNEL: + case TYPE_POSTED: case TYPE_SEARCH: case TYPE_MESSAGE: case TYPE_CERTIFICATE: @@ -1040,6 +1079,12 @@ static void processList(const QStringList &list, const QString &textSingular, co QStringList channelUnknown; QStringList channelMsgUnknown; + // forum + QStringList postedFound; + QStringList postedMsgFound; + QStringList postedUnknown; + QStringList postedMsgUnknown; + // search QStringList searchStarted; @@ -1056,8 +1101,8 @@ static void processList(const QStringList &list, const QString &textSingular, co QList processedList; QList errorList; - processedList << &fileAdded << &personAdded << &forumFound << &channelFound << &searchStarted << &messageStarted; - errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown; + processedList << &fileAdded << &personAdded << &forumFound << &channelFound << &postedFound << &searchStarted << &messageStarted; + errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &postedUnknown << &postedMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown; // not needed: forumFound, channelFound, messageStarted for (linkIt = links.begin(); linkIt != links.end(); ++linkIt) { @@ -1289,6 +1334,36 @@ static void processList(const QStringList &list, const QString &textSingular, co } break; + + case TYPE_POSTED: + { +#ifdef DEBUG_RSLINK + std::cerr << " RetroShareLink::process PostedRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl; +#endif + + MainWindow::showWindow(MainWindow::Posted); + PostedDialog *postedDialog = dynamic_cast(MainWindow::getPage(MainWindow::Posted)); + + if (!postedDialog) { + return false; + } + + if (postedDialog->navigate(RsGxsGroupId(link.id().toStdString()), RsGxsMessageId(link.msgId().toStdString()))) { + if (link.msgId().isEmpty()) { + postedFound.append(link.name()); + } else { + postedMsgFound.append(link.name()); + } + } else { + if (link.msgId().isEmpty()) { + postedUnknown.append(link.name()); + } else { + postedMsgUnknown.append(link.name()); + } + } + } + break; + case TYPE_SEARCH: { #ifdef DEBUG_RSLINK @@ -1438,6 +1513,16 @@ static void processList(const QStringList &list, const QString &textSingular, co } } + // posted + if (flag & RSLINK_PROCESS_NOTIFY_ERROR) { + if (!postedUnknown.isEmpty()) { + processList(postedUnknown, QObject::tr("Posted not found"), QObject::tr("Posted not found"), result); + } + if (!postedMsgUnknown.isEmpty()) { + processList(postedMsgUnknown, QObject::tr("Posted message not found"), QObject::tr("Posted messages not found"), result); + } + } + // message if (flag & RSLINK_PROCESS_NOTIFY_ERROR) { if (!messageReceipientNotAccepted.isEmpty()) { diff --git a/retroshare-gui/src/gui/RetroShareLink.h b/retroshare-gui/src/gui/RetroShareLink.h index c36b9ff4d..4020f8fcd 100644 --- a/retroshare-gui/src/gui/RetroShareLink.h +++ b/retroshare-gui/src/gui/RetroShareLink.h @@ -67,7 +67,8 @@ class RetroShareLink TYPE_CERTIFICATE = 0x07, TYPE_EXTRAFILE = 0x08, TYPE_PRIVATE_CHAT = 0x09, - TYPE_PUBLIC_MSG = 0x0a + TYPE_PUBLIC_MSG = 0x0a, + TYPE_POSTED = 0x0b }; public: diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp index 421566fa5..336073317 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp @@ -71,7 +71,7 @@ void PostedGroupItem::setup() connect(ui->subscribeButton, SIGNAL(clicked()), this, SLOT(subscribePosted())); connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyGroupLink())); - ui->copyLinkButton->hide(); // No link type at this moment + //ui->copyLinkButton->hide(); // No link type at this moment ui->expandFrame->hide(); } @@ -130,10 +130,10 @@ void PostedGroupItem::fill() #endif // No link type at this moment -// RetroShareLink link; -// link.createGxsGroupLink(RetroShareLink::TYPE_POSTED, mGroup.mMeta.mGroupId, groupName()); -// ui->nameLabel->setText(link.toHtml()); - ui->nameLabel->setText(groupName()); + RetroShareLink link; + link.createGxsGroupLink(RetroShareLink::TYPE_POSTED, mGroup.mMeta.mGroupId, groupName()); + ui->nameLabel->setText(link.toHtml()); +// ui->nameLabel->setText(groupName()); ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str())); diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index d3adda36b..0c059f048 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -145,6 +145,7 @@ bool RsHtml::canReplaceAnchor(QDomDocument &/*doc*/, QDomElement &/*element*/, c case RetroShareLink::TYPE_PERSON: case RetroShareLink::TYPE_FORUM: case RetroShareLink::TYPE_CHANNEL: + case RetroShareLink::TYPE_POSTED: case RetroShareLink::TYPE_SEARCH: case RetroShareLink::TYPE_MESSAGE: case RetroShareLink::TYPE_EXTRAFILE: @@ -173,6 +174,7 @@ void RsHtml::anchorStylesheetForImg(QDomDocument &/*doc*/, QDomElement &/*elemen case RetroShareLink::TYPE_PERSON: case RetroShareLink::TYPE_FORUM: case RetroShareLink::TYPE_CHANNEL: + case RetroShareLink::TYPE_POSTED: case RetroShareLink::TYPE_SEARCH: case RetroShareLink::TYPE_MESSAGE: case RetroShareLink::TYPE_EXTRAFILE: From c5873f32166e9bf193c1eb8dd7c2e5c977f11aaa Mon Sep 17 00:00:00 2001 From: Phenom Date: Sun, 10 Apr 2016 16:42:15 +0200 Subject: [PATCH 11/16] Move Chat notify button from search bar to tool bar. As search bar is hidden by default. --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 28 +++--- retroshare-gui/src/gui/chat/ChatWidget.ui | 108 ++++++++++----------- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 5874e8243..ea6469052 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -218,7 +218,7 @@ void ChatWidget::setDefaultExtraFileFlags(TransferRequestFlags fl) void ChatWidget::addChatHorizontalWidget(QWidget *w) { - ui->vl_Plugins->addWidget(w) ; + ui->pluginsVLayout->addWidget(w) ; update() ; } @@ -234,8 +234,8 @@ void ChatWidget::addTitleBarWidget(QWidget *w) void ChatWidget::hideChatText(bool hidden) { - ui->frame_ChatText->setHidden(hidden); ; - ui->searchframe->setVisible(ui->actionSearch_History->isChecked() && !hidden); ; + ui->chatTextFrame->setHidden(hidden); ; + ui->searchFrame->setVisible(ui->actionSearch_History->isChecked() && !hidden); ; } RSButtonOnText* ChatWidget::getNewButtonOnTextBrowser() @@ -400,12 +400,12 @@ void ChatWidget::processSettings(bool load) // load settings // state of splitter - ui->chatsplitter->restoreState(Settings->value("ChatSplitter").toByteArray()); + ui->chatVSplitter->restoreState(Settings->value("ChatSplitter").toByteArray()); } else { // save settings // state of splitter - Settings->setValue("ChatSplitter", ui->chatsplitter->saveState()); + Settings->setValue("ChatSplitter", ui->chatVSplitter->saveState()); } Settings->endGroup(); @@ -835,7 +835,7 @@ void ChatWidget::on_notifyButton_clicked() QIcon icoLobby=(ui->notifyButton->icon()); notify->makeSubMenu(menu, icoLobby, title, chatId.toLobbyId()); - menu->exec(ui->notifyButton->mapToGlobal(ui->notifyButton->geometry().bottomLeft())); + menu->exec(ui->notifyButton->mapToGlobal(QPoint(0,ui->notifyButton->geometry().height()))); } @@ -1031,7 +1031,7 @@ void ChatWidget::chatCharFormatChanged() void ChatWidget::resetStatusBar() { ui->typingLabel->clear(); - ui->typingpixmapLabel->clear(); + ui->typingPixmapLabel->clear(); typing = false; @@ -1430,11 +1430,11 @@ void ChatWidget::messageHistory() void ChatWidget::searchHistory() { if(ui->actionSearch_History->isChecked()){ - ui->searchframe->show(); - }else { - ui->searchframe->hide(); - } - + ui->searchFrame->show(); + }else { + ui->searchFrame->hide(); + } + } void ChatWidget::addExtraFile() @@ -1660,8 +1660,8 @@ void ChatWidget::updatePeersCustomStateString(const QString& /*peer_id*/, const void ChatWidget::updateStatusString(const QString &statusMask, const QString &statusString, bool permanent) { - ui->typingLabel->setText(QString(statusMask).arg(tr(statusString.toUtf8()))); // displays info for 5 secs. - ui->typingpixmapLabel->setPixmap(QPixmap(":images/typing.png") ); + ui->typingLabel->setText(QString(statusMask).arg(tr(statusString.toUtf8()))); // displays info for 5 secs. + ui->typingPixmapLabel->setPixmap(QPixmap(":images/typing.png") ); if (statusString == "is typing...") { typing = true; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index c2f4e2504..5ccfacae3 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -10,7 +10,7 @@ 323 - + 0 @@ -27,12 +27,12 @@ 2 - + 2 - + 20 @@ -45,7 +45,7 @@ QFrame::Raised - + 0 @@ -130,7 +130,7 @@ QFrame::Box - + 6 @@ -207,7 +207,7 @@ border-image: url(:/images/closepressed.png) - + Qt::Vertical @@ -235,14 +235,14 @@ border-image: url(:/images/closepressed.png) - + 0 - + - + 18 @@ -280,7 +280,7 @@ border-image: url(:/images/closepressed.png) - + Qt::Horizontal @@ -308,7 +308,7 @@ border-image: url(:/images/closepressed.png) 30 - + Type a message here @@ -325,7 +325,7 @@ border-image: url(:/images/closepressed.png) QFrame::Sunken - + 2 @@ -521,7 +521,7 @@ border-image: url(:/images/closepressed.png) QFrame::Plain - + 2 @@ -538,7 +538,39 @@ border-image: url(:/images/closepressed.png) - + + + + 28 + 28 + + + + + 28 + 28 + + + + Qt::NoFocus + + + + :/images/chat_red24.png:/images/chat_red24.png + + + + 24 + 24 + + + + true + + + + + Qt::Horizontal @@ -571,12 +603,12 @@ border-image: url(:/images/closepressed.png) - + - + QLayout::SetMaximumSize @@ -600,7 +632,7 @@ border-image: url(:/images/closepressed.png) QFrame::Sunken - + 2 @@ -670,7 +702,7 @@ border-image: url(:/images/closepressed.png) - + Qt::Horizontal @@ -690,7 +722,7 @@ border-image: url(:/images/closepressed.png) QFrame::Plain - + 2 @@ -707,14 +739,14 @@ border-image: url(:/images/closepressed.png) - + QFrame::StyledPanel QFrame::Raised - + 0 @@ -771,38 +803,6 @@ border-image: url(:/images/closepressed.png) - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - - :/images/chat_red24.png:/images/chat_red24.png - - - - 24 - 24 - - - - true - - - @@ -1099,8 +1099,8 @@ border-image: url(:/images/closepressed.png)
- + From 42a2b37abb3063f80a3fad8f61bbf038652c78be Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 13 Apr 2016 19:21:18 +0200 Subject: [PATCH 12/16] Move SearchBar to Tool Bar and remove Show/Hide action. As asked by Cyril in PR#346 --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 17 - retroshare-gui/src/gui/chat/ChatWidget.h | 2 - retroshare-gui/src/gui/chat/ChatWidget.ui | 315 ++++++++---------- retroshare-gui/src/gui/settings/ChatPage.cpp | 2 - .../src/gui/settings/rsharesettings.cpp | 10 - .../src/gui/settings/rsharesettings.h | 3 - 6 files changed, 140 insertions(+), 209 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index ea6469052..2bc545362 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -107,7 +107,6 @@ ChatWidget::ChatWidget(QWidget *parent) : connect(ui->actionMoveToCursor, SIGNAL(triggered()), this, SLOT(toogle_MoveToCursor())); connect(ui->actionSearchWithoutLimit, SIGNAL(triggered()), this, SLOT(toogle_SeachWithoutLimit())); connect(ui->searchButton, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuSearchButton(QPoint))); - connect(ui->actionSearch_History, SIGNAL(triggered()), this, SLOT(searchHistory())); notify=NULL; ui->notifyButton->setVisible(false); @@ -146,9 +145,6 @@ ChatWidget::ChatWidget(QWidget *parent) : ui->infoFrame->setVisible(false); ui->statusMessageLabel->hide(); - ui->actionSearch_History->setChecked(Settings->getChatSearchShowBarByDefault()); - searchHistory(); - setAcceptDrops(true); ui->chatTextEdit->setAcceptDrops(false); ui->hashBox->setDropWidget(this); @@ -165,7 +161,6 @@ ChatWidget::ChatWidget(QWidget *parent) : menu->addAction(ui->actionDeleteChatHistory); menu->addAction(ui->actionSaveChatHistory); menu->addAction(ui->actionMessageHistory); - menu->addAction(ui->actionSearch_History); ui->pushtoolsButton->setMenu(menu); ui->textBrowser->installEventFilter(this); @@ -235,7 +230,6 @@ void ChatWidget::addTitleBarWidget(QWidget *w) void ChatWidget::hideChatText(bool hidden) { ui->chatTextFrame->setHidden(hidden); ; - ui->searchFrame->setVisible(ui->actionSearch_History->isChecked() && !hidden); ; } RSButtonOnText* ChatWidget::getNewButtonOnTextBrowser() @@ -316,7 +310,6 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) messageCount = Settings->getPublicChatHistoryCount(); ui->titleBarFrame->setVisible(false); - ui->actionSearch_History->setVisible(false); } if (rsHistory->getEnable(hist_chat_type)) @@ -1427,16 +1420,6 @@ void ChatWidget::messageHistory() imBrowser.exec(); } -void ChatWidget::searchHistory() -{ - if(ui->actionSearch_History->isChecked()){ - ui->searchFrame->show(); - }else { - ui->searchFrame->hide(); - } - -} - void ChatWidget::addExtraFile() { QStringList files; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index 1aa2d9e4a..af4dab505 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -132,8 +132,6 @@ private slots: void deleteChatHistory(); void messageHistory(); void resetStatusBar() ; - void searchHistory(); - signals: void infoChanged(ChatWidget*); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index 5ccfacae3..4ac16a057 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -569,6 +569,146 @@ border-image: url(:/images/closepressed.png) + + + + + 0 + 0 + + + + + 28 + 28 + + + + + 28 + 28 + + + + Qt::NoFocus + + + + :/images/highlight.png:/images/highlight.png + + + + 24 + 24 + + + + true + + + true + + + + + + + + + + + 14 + 28 + + + + + 14 + 28 + + + + Qt::NoFocus + + + + :/images/arrow-left.png:/images/arrow-left.png + + + true + + + + + + + + 14 + 28 + + + + + 14 + 28 + + + + Qt::NoFocus + + + + :/images/arrow-right.png:/images/arrow-right.png + + + true + + + + + + + + 0 + 0 + + + + + 28 + 28 + + + + + 28 + 28 + + + + Qt::NoFocus + + + Qt::CustomContextMenu + + + + :/images/find.png:/images/find.png + + + + 24 + 24 + + + + true + + + true + + + @@ -738,170 +878,6 @@ border-image: url(:/images/closepressed.png) - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - Qt::CustomContextMenu - - - - :/images/find.png:/images/find.png - - - - 24 - 24 - - - - true - - - true - - - - - - - - 14 - 28 - - - - - 14 - 28 - - - - Qt::NoFocus - - - - :/images/arrow-right.png:/images/arrow-right.png - - - true - - - - - - - - - - - 14 - 28 - - - - - 14 - 28 - - - - Qt::NoFocus - - - - :/images/arrow-left.png:/images/arrow-left.png - - - true - - - - - - - - 0 - 0 - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - - :/images/highlight.png:/images/highlight.png - - - - 24 - 24 - - - - true - - - true - - - - - - @@ -1033,17 +1009,6 @@ border-image: url(:/images/closepressed.png) Choose color - - - true - - - Display Search Box - - - Search Box - - Quote diff --git a/retroshare-gui/src/gui/settings/ChatPage.cpp b/retroshare-gui/src/gui/settings/ChatPage.cpp index da7168f7d..3c515be49 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.cpp +++ b/retroshare-gui/src/gui/settings/ChatPage.cpp @@ -130,7 +130,6 @@ ChatPage::save(QString &/*errmsg*/) Settings->setChatSendMessageWithCtrlReturn(ui.sendMessageWithCtrlReturn->isChecked()); - Settings->setChatSearchShowBarByDefault(ui.cbSearch_ShowBar->isChecked()); Settings->setChatSearchCharToStartSearch(ui.sbSearch_CharToStart->value()); Settings->setChatSearchCaseSensitively(ui.cbSearch_CaseSensitively->isChecked()); Settings->setChatSearchWholeWords(ui.cbSearch_WholeWords->isChecked()); @@ -238,7 +237,6 @@ ChatPage::load() ui.sendMessageWithCtrlReturn->setChecked(Settings->getChatSendMessageWithCtrlReturn()); - ui.cbSearch_ShowBar->setChecked(Settings->getChatSearchShowBarByDefault()); ui.sbSearch_CharToStart->setValue(Settings->getChatSearchCharToStartSearch()); ui.cbSearch_CaseSensitively->setChecked(Settings->getChatSearchCaseSensitively()); ui.cbSearch_WholeWords->setChecked(Settings->getChatSearchWholeWords()); diff --git a/retroshare-gui/src/gui/settings/rsharesettings.cpp b/retroshare-gui/src/gui/settings/rsharesettings.cpp index 0dfc713f9..8c7220186 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.cpp +++ b/retroshare-gui/src/gui/settings/rsharesettings.cpp @@ -512,16 +512,6 @@ void RshareSettings::setChatSendMessageWithCtrlReturn(bool bValue) setValueToGroup("Chat", "SendMessageWithCtrlReturn", bValue); } -bool RshareSettings::getChatSearchShowBarByDefault() -{ - return valueFromGroup("Chat", "SearchShowBarByDefault", false).toBool(); -} - -void RshareSettings::setChatSearchShowBarByDefault(bool bValue) -{ - setValueToGroup("Chat", "SearchShowBarByDefault", bValue); -} - void RshareSettings::setChatSearchCharToStartSearch(int iValue) { setValueToGroup("Chat", "SearchCharToStartSearch", iValue); diff --git a/retroshare-gui/src/gui/settings/rsharesettings.h b/retroshare-gui/src/gui/settings/rsharesettings.h index 52963ce92..2f344b3a9 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.h +++ b/retroshare-gui/src/gui/settings/rsharesettings.h @@ -209,9 +209,6 @@ public: bool getChatSendMessageWithCtrlReturn(); void setChatSendMessageWithCtrlReturn(bool bValue); - bool getChatSearchShowBarByDefault(); - void setChatSearchShowBarByDefault(bool bValue); - void setChatSearchCharToStartSearch(int iValue); int getChatSearchCharToStartSearch(); From 718d6f9b19bcafcd0949f8291ef9ba8f71c12253 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 13 Apr 2016 20:26:36 +0200 Subject: [PATCH 13/16] Resize Chat Tool Bar Button for Hight DPI screen. --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 43 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 2bc545362..c2052365d 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -62,6 +62,8 @@ #include +#define FMM 2//fontMetricsMultiplicator + /***** * #define CHAT_DEBUG 1 *****/ @@ -71,6 +73,10 @@ ChatWidget::ChatWidget(QWidget *parent) : { ui->setupUi(this); + int iconHeight = FMM*QFontMetricsF(font()).height() ; + QSize iconSize = QSize(iconHeight,iconHeight); + QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); + newMessages = false; typing = false; peerStatus = 0; @@ -82,6 +88,29 @@ ChatWidget::ChatWidget(QWidget *parent) : lastStatusSendTime = 0 ; + //Resize Tool buttons + ui->emoteiconButton->setFixedSize(buttonSize); + ui->emoteiconButton->setIconSize(iconSize); + ui->fontButton->setFixedSize(buttonSize); + ui->fontButton->setIconSize(iconSize); + ui->attachPictureButton->setFixedSize(buttonSize); + ui->attachPictureButton->setIconSize(iconSize); + ui->addFileButton->setFixedSize(buttonSize); + ui->addFileButton->setIconSize(iconSize); + ui->pushtoolsButton->setFixedSize(buttonSize); + ui->pushtoolsButton->setIconSize(iconSize); + ui->notifyButton->setFixedSize(buttonSize); + ui->notifyButton->setIconSize(iconSize); + ui->markButton->setFixedSize(buttonSize); + ui->markButton->setIconSize(iconSize); + ui->leSearch->setFixedHeight(iconHeight); + ui->searchBefore->setFixedHeight(iconHeight); + ui->searchAfter->setFixedHeight(iconHeight); + ui->searchButton->setFixedSize(buttonSize); + ui->searchButton->setIconSize(iconSize); + ui->sendButton->setFixedHeight(iconHeight); + + //Initialize search iCharToStartSearch=Settings->getChatSearchCharToStartSearch(); bFindCaseSensitively=Settings->getChatSearchCaseSensitively(); bFindWholeWords=Settings->getChatSearchWholeWords(); @@ -90,7 +119,6 @@ ChatWidget::ChatWidget(QWidget *parent) : uiMaxSearchLimitColor=Settings->getChatSearchMaxSearchLimitColor(); cFoundColor=Settings->getChatSearchFoundColor(); - ui->actionSearchWithoutLimit->setText(tr("Don't stop to color after")+" "+QString::number(uiMaxSearchLimitColor)+" "+tr("items found (need more CPU)")); ui->leSearch->setVisible(false); @@ -102,6 +130,7 @@ ChatWidget::ChatWidget(QWidget *parent) : ui->searchButton->setChecked(false); ui->searchButton->setToolTip(tr("Find
Ctrl+F")); ui->leSearch->installEventFilter(this); + connect(ui->actionFindCaseSensitively, SIGNAL(triggered()), this, SLOT(toogle_FindCaseSensitively())); connect(ui->actionFindWholeWords, SIGNAL(triggered()), this, SLOT(toogle_FindWholeWords())); connect(ui->actionMoveToCursor, SIGNAL(triggered()), this, SLOT(toogle_MoveToCursor())); @@ -113,11 +142,11 @@ ChatWidget::ChatWidget(QWidget *parent) : ui->markButton->setToolTip(tr("Mark this selected text
Ctrl+M")); - connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendChat())); - connect(ui->addFileButton, SIGNAL(clicked()), this , SLOT(addExtraFile())); - - connect(ui->attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture())); connect(ui->emoteiconButton, SIGNAL(clicked()), this, SLOT(smileyWidget())); + connect(ui->attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture())); + connect(ui->addFileButton, SIGNAL(clicked()), this , SLOT(addExtraFile())); + connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendChat())); + connect(ui->actionSaveChatHistory, SIGNAL(triggered()), this, SLOT(fileSaveAs())); connect(ui->actionClearChatHistory, SIGNAL(triggered()), this, SLOT(clearChatHistory())); connect(ui->actionDeleteChatHistory, SIGNAL(triggered()), this, SLOT(deleteChatHistory())); @@ -219,6 +248,10 @@ void ChatWidget::addChatHorizontalWidget(QWidget *w) void ChatWidget::addChatBarWidget(QWidget *w) { + int iconHeight = FMM*QFontMetricsF(font()).height() ; + QSize iconSize = QSize(iconHeight,iconHeight); + QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); + w->setFixedSize(buttonSize); ui->pluginButtonFrame->layout()->addWidget(w) ; } From 45f77def2baf30f567cf233c0dc6bda60d2c451b Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 13 Apr 2016 20:42:12 +0200 Subject: [PATCH 14/16] Change Lobby Send button tooltip. --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index c2052365d..d3613a3c5 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -1102,15 +1102,21 @@ void ChatWidget::updateLenOfChatTextEdit() break; } - bool msgToLarge = false; + int charRemains = 0; if (maxMessageSize > 0) { - msgToLarge = (msg.length() >= maxMessageSize); + charRemains = maxMessageSize - msg.length(); } - ui->sendButton->setEnabled(!msgToLarge); - text = tr("%1This message consists of %2 characters.").arg(msgToLarge ? tr("Warning:")+" " : "").arg(msg.length()); + ui->sendButton->setEnabled(charRemains>=0); + if (charRemains>0) + text = tr("It remains %1 characters\nafter HTML conversion.").arg(charRemains); + else if(charRemains<0) + text = tr("Warning: This message is too big of %1 characters\nafter HTML conversion.").arg((0-charRemains)); + else + text = ""; + ui->sendButton->setToolTip(text); - ui->chatTextEdit->setToolTip(msgToLarge?text:""); + ui->chatTextEdit->setToolTip(text); } void ChatWidget::sendChat() From aad295dafb5f06b2053a85c46c2ce69dd7086245 Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 13 Apr 2016 21:00:07 +0200 Subject: [PATCH 15/16] Fixed layout margin --- retroshare-gui/src/gui/Identity/IdDialog.ui | 58 +++++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index cff96f3cd..01ec60018 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -20,7 +20,16 @@
- + + 0 + + + 0 + + + 0 + + 0 @@ -38,7 +47,16 @@ QFrame::Sunken - + + 2 + + + 2 + + + 2 + + 2 @@ -129,6 +147,18 @@ QFrame::Sunken + + 1 + + + 1 + + + 1 + + + 1 + @@ -254,7 +284,7 @@ Reputation - AlignLeft|AlignVCenter + AlignLeading|AlignVCenter @@ -331,7 +361,16 @@ - + + 6 + + + 6 + + + 6 + + 6 @@ -505,7 +544,16 @@ - + + 6 + + + 6 + + + 6 + + 6 From 971f8e0c1271bbdca498c9f615719ec538437566 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 13 Apr 2016 18:41:49 -0400 Subject: [PATCH 16/16] fixed potential crash due to not updating mPendingDataIterator after deleting map entry --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 8fa66df62..7458e0406 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -262,7 +262,11 @@ bool GxsIdDetails::process(const RsGxsId &id, GxsIdDetailsCallbackFunction callb if(it != mInstance->mPendingData.end()) { mInstance->connectObject_locked(object, false); - mInstance->mPendingData.erase(it) ; + + if(mInstance->mPendingDataIterator == it) + mInstance->mPendingDataIterator = mInstance->mPendingData.erase(it) ; + else + mInstance->mPendingData.erase(it) ; } /* Connect signal "destroy" */