mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
fixing some bugs in circles backend
This commit is contained in:
parent
d7dab2ae88
commit
0c3b8641af
@ -61,7 +61,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key
|
|||||||
|
|
||||||
#define GXS_MASK "GXS_MASK_HACK"
|
#define GXS_MASK "GXS_MASK_HACK"
|
||||||
|
|
||||||
//#define GEN_EXCH_DEBUG 1
|
#define GEN_EXCH_DEBUG 1
|
||||||
|
|
||||||
static const uint32_t MSG_CLEANUP_PERIOD = 60*59; // 59 minutes
|
static const uint32_t MSG_CLEANUP_PERIOD = 60*59; // 59 minutes
|
||||||
static const uint32_t INTEGRITY_CHECK_PERIOD = 60*31; // 31 minutes
|
static const uint32_t INTEGRITY_CHECK_PERIOD = 60*31; // 31 minutes
|
||||||
@ -937,7 +937,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
|
|||||||
RsReputationLevel::LOCALLY_NEGATIVE )
|
RsReputationLevel::LOCALLY_NEGATIVE )
|
||||||
{
|
{
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << details.mReputation.mOverallReputationLevel <<") indicate that you banned this ID." << std::endl;
|
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << static_cast<int>(details.mReputation.mOverallReputationLevel) <<") indicate that you banned this ID." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
idValidate = false ;
|
idValidate = false ;
|
||||||
}
|
}
|
||||||
|
@ -274,12 +274,12 @@
|
|||||||
NXS_NET_DEBUG_8 gxs distant sync
|
NXS_NET_DEBUG_8 gxs distant sync
|
||||||
|
|
||||||
***/
|
***/
|
||||||
//#define NXS_NET_DEBUG_0 1
|
#define NXS_NET_DEBUG_0 1
|
||||||
//#define NXS_NET_DEBUG_1 1
|
#define NXS_NET_DEBUG_1 1
|
||||||
//#define NXS_NET_DEBUG_2 1
|
//#define NXS_NET_DEBUG_2 1
|
||||||
//#define NXS_NET_DEBUG_3 1
|
//#define NXS_NET_DEBUG_3 1
|
||||||
//#define NXS_NET_DEBUG_4 1
|
#define NXS_NET_DEBUG_4 1
|
||||||
//#define NXS_NET_DEBUG_5 1
|
#define NXS_NET_DEBUG_5 1
|
||||||
//#define NXS_NET_DEBUG_6 1
|
//#define NXS_NET_DEBUG_6 1
|
||||||
//#define NXS_NET_DEBUG_7 1
|
//#define NXS_NET_DEBUG_7 1
|
||||||
//#define NXS_NET_DEBUG_8 1
|
//#define NXS_NET_DEBUG_8 1
|
||||||
@ -320,9 +320,9 @@ static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
|
|||||||
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|
||||||
|| defined(NXS_NET_DEBUG_8)
|
|| defined(NXS_NET_DEBUG_8)
|
||||||
|
|
||||||
static const RsPeerId peer_to_print = RsPeerId(std::string("")) ;
|
static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ;
|
||||||
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("")) ; // use this to allow to this group id only, or "" for all IDs
|
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs
|
||||||
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_CHANNELS ; // use this to allow to this service id only, or 0 for all services
|
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_GXSCIRCLE; // use this to allow to this service id only, or 0 for all services
|
||||||
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
|
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
|
||||||
|
|
||||||
class nullstream: public std::ostream {};
|
class nullstream: public std::ostream {};
|
||||||
@ -3598,6 +3598,10 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
|||||||
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
|
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
|
||||||
msg->pos = 0;
|
msg->pos = 0;
|
||||||
|
|
||||||
|
#ifdef NXS_NET_DEBUG_0
|
||||||
|
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " sending msg Id " << msg->msgId << " in Group " << msg->grpId << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
newTr->mItems.push_back(msg);
|
newTr->mItems.push_back(msg);
|
||||||
msgSize++;
|
msgSize++;
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,7 +126,7 @@ p3GxsCircles::p3GxsCircles( RsGeneralDataService *gds, RsNetworkExchangeService
|
|||||||
RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
|
RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
|
||||||
RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils),
|
RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils),
|
||||||
mCircleMtx("p3GxsCircles"),
|
mCircleMtx("p3GxsCircles"),
|
||||||
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ),
|
// mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ),
|
||||||
mShouldSendCacheUpdateNotification(false)
|
mShouldSendCacheUpdateNotification(false)
|
||||||
{
|
{
|
||||||
// Kick off Cache Testing, + Others.
|
// Kick off Cache Testing, + Others.
|
||||||
@ -1071,6 +1071,10 @@ RsGxsCircleCache::RsGxsCircleCache()
|
|||||||
|
|
||||||
bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle)
|
bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_CIRCLES
|
||||||
|
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << "):" << std::endl;
|
||||||
|
#endif // DEBUG_CIRCLES
|
||||||
|
|
||||||
mCircleId = RsGxsCircleId(circle.mMeta.mGroupId);
|
mCircleId = RsGxsCircleId(circle.mMeta.mGroupId);
|
||||||
mCircleName = circle.mMeta.mGroupName;
|
mCircleName = circle.mMeta.mGroupName;
|
||||||
// mProcessedCircles.insert(mCircleId);
|
// mProcessedCircles.insert(mCircleId);
|
||||||
@ -1084,19 +1088,23 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle)
|
|||||||
mAllowedNodes = circle.mLocalFriends ;
|
mAllowedNodes = circle.mLocalFriends ;
|
||||||
mRestrictedCircleId = circle.mMeta.mCircleId ;
|
mRestrictedCircleId = circle.mMeta.mCircleId ;
|
||||||
|
|
||||||
mMembershipStatus.clear() ;
|
// We do not clear mMembershipStatus because this might be an update and if we do, it will clear membership requests
|
||||||
|
// that are not in the invited list!
|
||||||
|
|
||||||
for(std::set<RsGxsId>::const_iterator it(circle.mInvitedMembers.begin());it!=circle.mInvitedMembers.end();++it)
|
for(std::set<RsGxsId>::const_iterator it(circle.mInvitedMembers.begin());it!=circle.mInvitedMembers.end();++it)
|
||||||
{
|
{
|
||||||
RsGxsCircleMembershipStatus& s(mMembershipStatus[*it]) ;
|
RsGxsCircleMembershipStatus& s(mMembershipStatus[*it]) ;
|
||||||
|
s.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ;
|
||||||
|
|
||||||
|
// This one can be cleared because it will anyway be updated to the latest when loading subscription request messages and it wil only
|
||||||
|
// be used there as well.
|
||||||
|
|
||||||
s.last_subscription_TS = 0 ;
|
s.last_subscription_TS = 0 ;
|
||||||
s.subscription_flags = GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_CIRCLES
|
#ifdef DEBUG_CIRCLES
|
||||||
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")";
|
std::cerr << " Invited member " << *it << " Initializing/updating membership status to " << std::hex << s.subscription_flags << std::dec << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif // DEBUG_CIRCLES
|
#endif // DEBUG_CIRCLES
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1251,7 +1259,6 @@ bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id)
|
|||||||
cache.mStatus = CircleEntryCacheStatus::LOADING;
|
cache.mStatus = CircleEntryCacheStatus::LOADING;
|
||||||
|
|
||||||
mCirclesToLoad.insert(id);
|
mCirclesToLoad.insert(id);
|
||||||
mShouldSendCacheUpdateNotification = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RsTickEvent::event_count(CIRCLE_EVENT_CACHELOAD) > 0) /* its already scheduled */
|
if (RsTickEvent::event_count(CIRCLE_EVENT_CACHELOAD) > 0) /* its already scheduled */
|
||||||
@ -1480,9 +1487,6 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
|
|||||||
cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP;
|
cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP;
|
||||||
locked_checkCircleCacheForMembershipUpdate(cache);
|
locked_checkCircleCacheForMembershipUpdate(cache);
|
||||||
|
|
||||||
/* move straight into the cache */
|
|
||||||
mCircleCache.resize();
|
|
||||||
|
|
||||||
std::cerr << " Loading complete." << std::endl;
|
std::cerr << " Loading complete." << std::endl;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@ -1923,6 +1927,7 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
|
|||||||
|
|
||||||
RsGxsCircleId circle_id(it->first);
|
RsGxsCircleId circle_id(it->first);
|
||||||
RsGxsCircleCache& cache( mCircleCache[circle_id] );
|
RsGxsCircleCache& cache( mCircleCache[circle_id] );
|
||||||
|
|
||||||
#ifdef DEBUG_CIRCLES
|
#ifdef DEBUG_CIRCLES
|
||||||
std::cerr << " Circle found in cache!" << std::endl;
|
std::cerr << " Circle found in cache!" << std::endl;
|
||||||
std::cerr << " Retrieving messages..." << std::endl;
|
std::cerr << " Retrieving messages..." << std::endl;
|
||||||
@ -1931,24 +1936,26 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
|
|||||||
for(uint32_t i=0;i<it->second.size();++i)
|
for(uint32_t i=0;i<it->second.size();++i)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_CIRCLES
|
#ifdef DEBUG_CIRCLES
|
||||||
std::cerr << " Group ID: " << it->second[i]->meta.mGroupId << ", Message ID: " << it->second[i]->meta.mMsgId << ": " ;
|
std::cerr << " Group ID: " << it->second[i]->meta.mGroupId << ", Message ID: " << it->second[i]->meta.mMsgId << ", thread ID: " << it->second[i]->meta.mThreadId << ", author: " << it->second[i]->meta.mAuthorId << ": " ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
|
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
|
||||||
|
|
||||||
if(item == NULL)
|
if(item == NULL)
|
||||||
{
|
{
|
||||||
std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird." << std::endl;
|
std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird. Scheduling for deletion." << std::endl;
|
||||||
|
|
||||||
|
messages_to_delete[RsGxsGroupId(circle_id)].insert(it->second[i]->meta.mMsgId);
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ;
|
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ;
|
||||||
|
|
||||||
#ifdef DEBUG_CIRCLES
|
#ifdef DEBUG_CIRCLES
|
||||||
std::cerr << " is from id " << item->meta.mAuthorId << " " << time(NULL) - item->time_stamp << " seconds ago, " ;
|
std::cerr << " " << time(NULL) - item->time_stamp << " seconds ago, " ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(info.last_subscription_TS < item->time_stamp)
|
if(info.last_subscription_TS <= item->time_stamp) // the <= here allows to make sure we update the flags is something happenned
|
||||||
{
|
{
|
||||||
info.last_subscription_TS = item->time_stamp ;
|
info.last_subscription_TS = item->time_stamp ;
|
||||||
|
|
||||||
@ -1961,15 +1968,28 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
|
|||||||
|
|
||||||
mShouldSendCacheUpdateNotification = true;
|
mShouldSendCacheUpdateNotification = true;
|
||||||
#ifdef DEBUG_CIRCLES
|
#ifdef DEBUG_CIRCLES
|
||||||
std::cerr << " UPDATING" << std::endl;
|
std::cerr << " UPDATING status to " << std::hex << info.subscription_flags << std::dec << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if(info.last_subscription_TS > item->time_stamp)
|
else if(info.last_subscription_TS > item->time_stamp)
|
||||||
|
std::cerr << " Too old: item->TS=" << item->time_stamp << ", last_subscription_TS=" << info.last_subscription_TS << ". IGNORING." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now do another sweep and remove all msgs that are older than the latest
|
||||||
|
|
||||||
|
std::cerr << " Cleaning old messages..." << std::endl;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<it->second.size();++i)
|
||||||
|
{
|
||||||
|
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[it->second[i]->meta.mAuthorId]) ;
|
||||||
|
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
|
||||||
|
|
||||||
|
if(item && info.last_subscription_TS > item->time_stamp)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_CIRCLES
|
#ifdef DEBUG_CIRCLES
|
||||||
std::cerr << " Older than last known (" << time(NULL)-info.last_subscription_TS << " seconds ago): deleting." << std::endl;
|
std::cerr << " " << item->meta.mMsgId << ": Older than last known (" << (long int)info.last_subscription_TS - (long int)item->time_stamp << " seconds before): deleting." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
messages_to_delete[RsGxsGroupId(circle_id)].insert(it->second[i]->meta.mMsgId) ;
|
messages_to_delete[RsGxsGroupId(circle_id)].insert(item->meta.mMsgId) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2002,7 +2022,7 @@ void p3GxsCircles::debug_dumpCache()
|
|||||||
{
|
{
|
||||||
std::cerr << "Debug dump of CircleCache:" << std::endl;
|
std::cerr << "Debug dump of CircleCache:" << std::endl;
|
||||||
|
|
||||||
mCircleCache.printStats(std::cerr);
|
mCircleCache.printStats();
|
||||||
mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::debug_dumpCacheEntry);
|
mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::debug_dumpCacheEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ public:
|
|||||||
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
|
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum CircleEntryCacheStatus: uint8_t {
|
enum CircleEntryCacheStatus: uint8_t {
|
||||||
UNKNOWN = 0x00, // Used to detect uninitialized memory
|
UNKNOWN = 0x00, // Used to detect uninitialized memory
|
||||||
NO_DATA_YET = 0x01, // Used in the constuctor
|
NO_DATA_YET = 0x01, // Used in the constuctor
|
||||||
LOADING = 0x02, // When the token request to load cache has been sent and no data is present
|
LOADING = 0x02, // When the token request to load cache has been sent and no data is present
|
||||||
@ -185,6 +185,28 @@ public:
|
|||||||
|
|
||||||
class PgpAuxUtils;
|
class PgpAuxUtils;
|
||||||
|
|
||||||
|
class RsCirclesMemCache : public std::map<RsGxsCircleId,RsGxsCircleCache>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsCirclesMemCache() : std::map<RsGxsCircleId,RsGxsCircleCache>(){}
|
||||||
|
|
||||||
|
bool is_cached(const RsGxsCircleId& id) { return end() != find(id) ; }
|
||||||
|
RsGxsCircleCache& ref(const RsGxsCircleId& id) { return operator[](id) ; }
|
||||||
|
|
||||||
|
void printStats() { std::cerr << "CircleMemCache: " << size() << " elements." << std::endl; }
|
||||||
|
|
||||||
|
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(RsGxsCircleCache&))
|
||||||
|
{
|
||||||
|
for(auto& it:*this)
|
||||||
|
(c.*method)(it.second);
|
||||||
|
}
|
||||||
|
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(const RsGxsCircleCache&))
|
||||||
|
{
|
||||||
|
for(const auto& it:*this)
|
||||||
|
(c.*method)(it.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
|
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
|
||||||
public GxsTokenQueue, public RsTickEvent
|
public GxsTokenQueue, public RsTickEvent
|
||||||
{
|
{
|
||||||
@ -341,7 +363,8 @@ public:
|
|||||||
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
|
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
|
||||||
|
|
||||||
std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups.
|
std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups.
|
||||||
RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data
|
RsCirclesMemCache mCircleCache;
|
||||||
|
//RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data
|
||||||
|
|
||||||
void debug_dumpCache(); // debug method to overview what's going on
|
void debug_dumpCache(); // debug method to overview what's going on
|
||||||
bool debug_dumpCacheEntry(RsGxsCircleCache &cache);
|
bool debug_dumpCacheEntry(RsGxsCircleCache &cache);
|
||||||
|
@ -120,7 +120,7 @@
|
|||||||
<enum>Qt::NoFocus</enum>
|
<enum>Qt::NoFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../icons.qrc">
|
||||||
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
@ -268,7 +268,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="rightTabWidget">
|
<widget class="QTabWidget" name="rightTabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="personTab">
|
<widget class="QWidget" name="personTab">
|
||||||
<attribute name="icon">
|
<attribute name="icon">
|
||||||
@ -289,8 +289,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>634</width>
|
<width>1372</width>
|
||||||
<height>523</height>
|
<height>719</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||||
@ -1052,7 +1052,7 @@ border-image: url(:/images/closepressed.png)
|
|||||||
</action>
|
</action>
|
||||||
<action name="chatIdentity">
|
<action name="chatIdentity">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset>
|
||||||
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
|
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -1094,8 +1094,8 @@ border-image: url(:/images/closepressed.png)
|
|||||||
<tabstop>idTreeWidget</tabstop>
|
<tabstop>idTreeWidget</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
Loading…
Reference in New Issue
Block a user