fixed hierarchical info

This commit is contained in:
csoler 2019-06-29 23:55:38 +02:00
parent 88ce3e4274
commit 49c450890e
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
2 changed files with 116 additions and 103 deletions

View File

@ -87,7 +87,10 @@ int RsFriendListModel::rowCount(const QModelIndex& parent) const
return 0; return 0;
if(index.type == ENTRY_TYPE_GROUP) if(index.type == ENTRY_TYPE_GROUP)
return mGroups[index.ind].peerIds.size(); return mGroups[index.ind].child_indices.size();
if(index.type == ENTRY_TYPE_PROFILE)
return mProfiles[index.ind].child_indices.size();
return 0; return 0;
} }
@ -122,9 +125,9 @@ bool RsFriendListModel::hasChildren(const QModelIndex &parent) const
if(parent_index.type == ENTRY_TYPE_NODE) if(parent_index.type == ENTRY_TYPE_NODE)
return false; return false;
if(parent_index.type == ENTRY_TYPE_PROFILE) if(parent_index.type == ENTRY_TYPE_PROFILE)
return false; // TODO return !mProfiles[parent_index.ind].child_indices.empty();
if(parent_index.type == ENTRY_TYPE_GROUP) if(parent_index.type == ENTRY_TYPE_GROUP)
return !mGroups[parent_index.ind].peerIds.empty(); return !mGroups[parent_index.ind].child_indices.empty();
return false; return false;
} }
@ -218,28 +221,20 @@ QModelIndex RsFriendListModel::parent(const QModelIndex& index) const
return QModelIndex(); return QModelIndex();
if(I.type == ENTRY_TYPE_PROFILE) if(I.type == ENTRY_TYPE_PROFILE)
if(mDisplayGroups)
{ {
for(int i=0;i<mGroups.size();++i) quintptr ref=0;
if(mGroups[i].peerIds.find(mProfiles[I.ind].gpg_id) != mGroups[i].peerIds.end()) // this is costly. We should store indices convertIndexToInternalId( EntryIndex( ENTRY_TYPE_GROUP, mProfiles[I.ind].parent_group_index ), ref);
return createIndex( mProfiles[I.ind].parent_row,0,ref);
}
if(I.type == ENTRY_TYPE_NODE)
{ {
quintptr ref ; quintptr ref=0 ;
EntryIndex parent_index(ENTRY_TYPE_GROUP,i); convertIndexToInternalId(EntryIndex( ENTRY_TYPE_PROFILE,mLocations[I.ind].parent_profile_index),ref);
convertIndexToInternalId(parent_index,ref);
return createIndex(i,0,ref); return createIndex( mLocations[I.ind].parent_row,0,ref);
} }
}
else
return QModelIndex();
// if(i.type == ENTRY_TYPE_NODE)
// {
// quintptr ref ;
// convertIndexToInternalId(parent_index,ref);
//
// return createIndex(parent_row,0,ref);
// }
return QModelIndex(); return QModelIndex();
} }
@ -489,7 +484,7 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
switch(col) switch(col)
{ {
case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(mGroups[e.ind].name.c_str())); case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(mGroups[e.ind].group.name.c_str()));
default: default:
return QVariant(); return QVariant();
@ -501,8 +496,8 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
switch(col) switch(col)
{ {
case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(mProfiles[e.ind].name.c_str())); case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(mProfileDetails[mProfiles[e.ind].profile_index].name.c_str()));
case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(mProfiles[e.ind].gpg_id.toStdString()) ); case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(mProfileDetails[mProfiles[e.ind].profile_index].gpg_id.toStdString()) );
default: default:
return QVariant(); return QVariant();
@ -514,10 +509,10 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
switch(col) switch(col)
{ {
case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(mLocations[e.ind].location.c_str())); case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(mNodeDetails[mLocations[e.ind].node_index].location.c_str()));
case COLUMN_THREAD_LAST_CONTACT: return QVariant(QDateTime::fromTime_t(mLocations[e.ind].lastConnect).toString()); case COLUMN_THREAD_LAST_CONTACT: return QVariant(QDateTime::fromTime_t(mNodeDetails[mLocations[e.ind].node_index].lastConnect).toString());
case COLUMN_THREAD_IP: return QVariant( (mLocations[e.ind].state & RS_PEER_STATE_CONNECTED) ? StatusDefs::connectStateIpString(mLocations[e.ind]) : QString("---")); case COLUMN_THREAD_IP: return QVariant( (mNodeDetails[mLocations[e.ind].node_index].state & RS_PEER_STATE_CONNECTED) ? StatusDefs::connectStateIpString(mNodeDetails[mLocations[e.ind].node_index]) : QString("---"));
case COLUMN_THREAD_ID: return QVariant( QString::fromStdString(mLocations[e.ind].id.toStdString()) ); case COLUMN_THREAD_ID: return QVariant( QString::fromStdString(mNodeDetails[mLocations[e.ind].node_index].id.toStdString()) );
default: default:
return QVariant(); return QVariant();
@ -640,7 +635,9 @@ static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,cons
void RsFriendListModel::debug_dump() const void RsFriendListModel::debug_dump() const
{ {
for(auto it(mGroups.begin());it!=mGroups.end();++it) for(auto it(mGroups.begin());it!=mGroups.end();++it)
std::cerr << "Group: " << *it << std::endl; {
std::cerr << "Group: " << (*it).group.name << std::endl;
}
} }
bool RsFriendListModel::getGroupData (const QModelIndex& i,RsGroupInfo & data) const bool RsFriendListModel::getGroupData (const QModelIndex& i,RsGroupInfo & data) const
@ -652,7 +649,7 @@ bool RsFriendListModel::getGroupData (const QModelIndex& i,RsGroupInfo & da
if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_GROUP || e.ind >= mGroups.size()) if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_GROUP || e.ind >= mGroups.size())
return false; return false;
data = mGroups[e.ind]; data = mGroups[e.ind].group;
return true; return true;
} }
bool RsFriendListModel::getProfileData(const QModelIndex& i,RsProfileDetails& data) const bool RsFriendListModel::getProfileData(const QModelIndex& i,RsProfileDetails& data) const
@ -664,7 +661,7 @@ bool RsFriendListModel::getProfileData(const QModelIndex& i,RsProfileDetails& da
if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_PROFILE || e.ind >= mProfiles.size()) if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_PROFILE || e.ind >= mProfiles.size())
return false; return false;
data = mProfiles[e.ind]; data = mProfileDetails[mProfiles[e.ind].profile_index];
return true; return true;
} }
bool RsFriendListModel::getNodeData (const QModelIndex& i,RsNodeDetails & data) const bool RsFriendListModel::getNodeData (const QModelIndex& i,RsNodeDetails & data) const
@ -676,7 +673,7 @@ bool RsFriendListModel::getNodeData (const QModelIndex& i,RsNodeDetails & da
if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_NODE || e.ind >= mLocations.size()) if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_NODE || e.ind >= mLocations.size())
return false; return false;
data = mLocations[e.ind]; data = mNodeDetails[mLocations[e.ind].node_index];
return true; return true;
} }
@ -700,80 +697,95 @@ void RsFriendListModel::updateInternalData()
mLocations.clear(); mLocations.clear();
mProfiles.clear(); mProfiles.clear();
mHG.clear(); mNodeDetails.clear();
mHL.clear(); mProfileDetails.clear();
mHP.clear();
// create a map of profiles and groups // create a map of profiles and groups
std::map<RsPgpId,uint32_t> pgp_indexes; std::map<RsPgpId,uint32_t> pgp_indexes;
std::map<RsPeerId,uint32_t> ssl_indexes; std::map<RsPeerId,uint32_t> ssl_indexes;
std::map<RsNodeGroupId,uint32_t> grp_indexes; std::map<RsNodeGroupId,uint32_t> grp_indexes;
// we start from the top and fill in the blanks as needed
// groups // groups
std::list<RsGroupInfo> groupInfoList; std::list<RsGroupInfo> groupInfoList;
rsPeers->getGroupInfoList(groupInfoList) ; rsPeers->getGroupInfoList(groupInfoList) ;
uint32_t group_row = 0;
for(auto it(groupInfoList.begin());it!=groupInfoList.end();++it) for(auto it(groupInfoList.begin());it!=groupInfoList.end();++it,++group_row)
{ {
grp_indexes[it->group_id] = mGroups.size(); // first, fill the group hierarchical info
mGroups.push_back(*it);
HierarchicalGroupInformation groupinfo;
groupinfo.group = *it;
groupinfo.parent_row = group_row;
uint32_t profile_row = 0;
for(auto it2((*it).peerIds.begin());it2!=(*it).peerIds.end();++it2,++profile_row)
{
// Then for each peer in this group, make sure that the peer is already known, and if not create it
auto it3 = pgp_indexes.find(*it2);
if(it3 == pgp_indexes.end())// not found
{
RsProfileDetails profdet;
rsPeers->getGPGDetails(*it2,profdet);
pgp_indexes[*it2] = mProfileDetails.size();
mProfileDetails.push_back(profdet);
it3 = pgp_indexes.find(*it2);
} }
// profiles // ...and also fill the hierarchical profile info
std::list<RsPgpId> gpg_ids; HierarchicalProfileInformation profinfo;
rsPeers->getGPGAcceptedList(gpg_ids);
for(auto it(gpg_ids.begin());it!=gpg_ids.end();++it) profinfo.parent_row = profile_row;
profinfo.parent_group_index = mGroups.size();
profinfo.profile_index = it3->second;
// now fill the children nodes of the profile
std::list<RsPeerId> ssl_ids ;
rsPeers->getAssociatedSSLIds(*it2, ssl_ids);
uint32_t node_row = 0;
for(auto it4(ssl_ids.begin());it4!=ssl_ids.end();++it4,++node_row)
{ {
RsProfileDetails det; auto it5 = ssl_indexes.find(*it4);
if(it5 == ssl_indexes.end())
{
RsNodeDetails nodedet;
if(!rsPeers->getGPGDetails(*it,det)) rsPeers->getPeerDetails(*it4,nodedet);
continue;
pgp_indexes[det.gpg_id] = mProfiles.size(); ssl_indexes[*it4] = mNodeDetails.size();
mProfiles.push_back(det); mNodeDetails.push_back(nodedet);
it5 = ssl_indexes.find(*it4);
} }
// locations HierarchicalNodeInformation nodeinfo;
nodeinfo.parent_row = node_row;
nodeinfo.node_index = it5->second;
nodeinfo.parent_profile_index = mProfiles.size();
std::list<RsPeerId> peer_ids; profinfo.child_indices.push_back(mLocations.size());
rsPeers->getFriendList(peer_ids);
for(auto it(peer_ids.begin());it!=peer_ids.end();++it) mLocations.push_back(nodeinfo);
{
RsNodeDetails det;
if(!rsPeers->getPeerDetails(*it,det))
continue;
ssl_indexes[det.id] = mLocations.size();
mLocations.push_back(det);
} }
// now build the hierarchy information for the model mProfiles.push_back(profinfo);
for(uint32_t i=0;i<mGroups.size();++i)
{
HierarchicalGroupInformation inf;
inf.group_index = i;
for(auto it(mGroups[i].peerIds.begin());it!=mGroups[i].peerIds.end();++ii)
{
auto it2 = pgp_indexes.find(*it);
if(it2 == pgp_indexes.end())
RsErr() << "Cannot find pgp entry for peer " << *it << " in precomputed map. This is very unexpected." << std::endl;
else
inf.child_indices.push_back(it2->second);
} }
mHG.push_back(inf); mGroups.push_back(groupinfo);
} }
#warning Missing code here !!!
postMods(); postMods();
} }

View File

@ -49,22 +49,24 @@ public:
struct HierarchicalGroupInformation struct HierarchicalGroupInformation
{ {
uint32_t group_index; RsGroupInfo group;
std::vector<uint32_t> child_indices; std::vector<uint32_t> child_indices; // index in the array of hierarchical profiles
uint32_t parent_row;
}; };
struct HierarchicalProfileInformation struct HierarchicalProfileInformation
{ {
uint32_t profile_index; uint32_t profile_index; // index in the array of profiles. We cannot store the profile here because of duplication
std::vector<uint32_t> child_indices; uint32_t parent_group_index; // index in the array of hierarchical groups
uint32_t parent_group_index; std::vector<uint32_t> child_indices; // index in the array of hierarchical nodes
uint32_t parent_row;
}; };
struct HierarchicalNodeInformation struct HierarchicalNodeInformation
{ {
uint32_t node_index; uint32_t node_index; // index in the array of nodes
uint32_t parent_profile_index; uint32_t parent_profile_index; // index in the array of hierarchical profiles
uint32_t parent_row;
}; };
enum Columns { enum Columns {
COLUMN_THREAD_NAME = 0x00, COLUMN_THREAD_NAME = 0x00,
COLUMN_THREAD_LAST_CONTACT = 0x01, COLUMN_THREAD_LAST_CONTACT = 0x01,
@ -184,12 +186,11 @@ private:
// A given profile may belong to multiple groups, so the hierarchy is stored using the 3 variables below. // A given profile may belong to multiple groups, so the hierarchy is stored using the 3 variables below.
std::vector<HierarchicalGroupInformation> mHG; std::vector<HierarchicalGroupInformation> mGroups;
std::vector<HierarchicalProfileInformation> mHP; std::vector<HierarchicalProfileInformation> mProfiles;
std::vector<HierarchicalNodeInformation> mHL; std::vector<HierarchicalNodeInformation> mLocations;
std::vector<RsGroupInfo> mGroups; std::vector<RsProfileDetails> mProfileDetails;
std::vector<RsProfileDetails> mProfiles; std::vector<RsNodeDetails> mNodeDetails;
std::vector<RsNodeDetails> mLocations;
}; };