mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
using vectors instead of maps for mCollectionModel data.
This commit is contained in:
parent
f375912bc5
commit
67ff37a0d4
@ -16,7 +16,6 @@ RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent)
|
|||||||
postMods();
|
postMods();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_COLLECTION_MODEL
|
|
||||||
static std::ostream& operator<<(std::ostream& o,const RsCollectionModel::EntryIndex& i)
|
static std::ostream& operator<<(std::ostream& o,const RsCollectionModel::EntryIndex& i)
|
||||||
{
|
{
|
||||||
return o << ((i.is_file)?("File"):"Dir") << " with index " << (int)i.index ;
|
return o << ((i.is_file)?("File"):"Dir") << " with index " << (int)i.index ;
|
||||||
@ -25,6 +24,7 @@ static std::ostream& operator<<(std::ostream& o,const QModelIndex& i)
|
|||||||
{
|
{
|
||||||
return o << "QModelIndex (row " << i.row() << ", of ref " << i.internalId() << ")" ;
|
return o << "QModelIndex (row " << i.row() << ", of ref " << i.internalId() << ")" ;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Indernal Id is always a quintptr_t (basically a uint with the size of a pointer). Depending on the
|
// Indernal Id is always a quintptr_t (basically a uint with the size of a pointer). Depending on the
|
||||||
@ -179,9 +179,19 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||||||
Qt::ItemFlags RsCollectionModel::flags ( const QModelIndex & index ) const
|
Qt::ItemFlags RsCollectionModel::flags ( const QModelIndex & index ) const
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.column() == COLLECTION_MODEL_FILENAME)
|
if(index.isValid() && index.column() == COLLECTION_MODEL_FILENAME)
|
||||||
return QAbstractItemModel::flags(index) | Qt::ItemIsUserTristate;
|
{
|
||||||
|
EntryIndex e;
|
||||||
|
|
||||||
return QAbstractItemModel::flags(index) & ~Qt::ItemIsUserTristate;
|
if(!convertInternalIdToIndex(index.internalId(),e))
|
||||||
|
return QAbstractItemModel::flags(index) ;
|
||||||
|
|
||||||
|
if(e.is_file)
|
||||||
|
return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
|
||||||
|
else
|
||||||
|
return QAbstractItemModel::flags(index) | Qt::ItemIsAutoTristate | Qt::ItemIsUserCheckable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QAbstractItemModel::flags(index) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
||||||
@ -199,25 +209,13 @@ QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
|||||||
|
|
||||||
if(i.is_file)
|
if(i.is_file)
|
||||||
{
|
{
|
||||||
const auto it = mFileInfos.find(i.index);
|
p.index = mFileInfos[i.index].parent_index;
|
||||||
if(it == mFileInfos.end())
|
row = mFileInfos[i.index].parent_row;
|
||||||
{
|
|
||||||
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
p.index = it->second.parent_index;
|
|
||||||
row = it->second.parent_row;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto it = mDirInfos.find(i.index);
|
p.index = mDirInfos[i.index].parent_index;
|
||||||
if(it == mDirInfos.end())
|
row = mDirInfos[i.index].parent_row;
|
||||||
{
|
|
||||||
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
p.index = it->second.parent_index;
|
|
||||||
row = it->second.parent_row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quintptr ref;
|
quintptr ref;
|
||||||
@ -237,8 +235,7 @@ QVariant RsCollectionModel::data(const QModelIndex& index, int role) const
|
|||||||
#endif
|
#endif
|
||||||
switch(role)
|
switch(role)
|
||||||
{
|
{
|
||||||
case Qt::DisplayRole: return displayRole(i,index.column());
|
case Qt::DisplayRole: return displayRole(i,index.column());
|
||||||
//case Qt::SortRole: return SortRole(i,index.column());
|
|
||||||
case Qt::DecorationRole: return decorationRole(i,index.column());
|
case Qt::DecorationRole: return decorationRole(i,index.column());
|
||||||
case Qt::CheckStateRole: return checkStateRole(i,index.column());
|
case Qt::CheckStateRole: return checkStateRole(i,index.column());
|
||||||
default:
|
default:
|
||||||
@ -251,15 +248,94 @@ bool RsCollectionModel::setData(const QModelIndex& index,const QVariant& value,i
|
|||||||
if(!index.isValid())
|
if(!index.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (role==Qt::CheckStateRole)
|
EntryIndex e;
|
||||||
|
|
||||||
|
if(role==Qt::CheckStateRole && convertInternalIdToIndex(index.internalId(), e))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_COLLECTION_MODEL
|
//#ifdef DEBUG_COLLECTION_MODEL
|
||||||
std::cerr << "Setting check state of item " << index << " to " << value.toBool() << std::endl;
|
std::cerr << "Setting check state of item " << index << " to " << value.toBool() << std::endl;
|
||||||
#endif
|
//#endif
|
||||||
|
RsFileTree::DirIndex dir_index ;
|
||||||
|
|
||||||
|
if(e.is_file)
|
||||||
|
{
|
||||||
|
mFileInfos[e.index].is_checked = value.toBool();
|
||||||
|
dir_index = mFileInfos[e.index].parent_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::function<void(RsFileTree::DirIndex i,bool s)> recursSetCheckFlag = [&](RsFileTree::DirIndex i,bool s) -> void
|
||||||
|
{
|
||||||
|
mDirInfos[i].check_state = (s)?SELECTED:UNSELECTED;
|
||||||
|
auto& dir_data(mCollection.fileTree().directoryData(i));
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subdirs.size();++i)
|
||||||
|
recursSetCheckFlag(dir_data.subdirs[i],s);
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subfiles.size();++i)
|
||||||
|
mFileInfos[dir_data.subfiles[i]].is_checked = s;
|
||||||
|
};
|
||||||
|
recursSetCheckFlag(e.index,value.toBool());
|
||||||
|
dir_index = mDirInfos[e.index].parent_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now go up the directories and update the check tristate flag, depending on whether the children are all checked/unchecked or mixed.
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
auto& dit(mDirInfos[dir_index]);
|
||||||
|
|
||||||
|
const RsFileTree::DirData& dir_data(mCollection.fileTree().directoryData(dir_index)); // get the directory data
|
||||||
|
|
||||||
|
bool locally_all_checked = true;
|
||||||
|
bool locally_all_unchecked = true;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subdirs.size() && (locally_all_checked || locally_all_unchecked);++i)
|
||||||
|
{
|
||||||
|
const auto& dit2(mDirInfos[dir_data.subdirs[i]]);
|
||||||
|
|
||||||
|
if(dit2.check_state == UNSELECTED || dit2.check_state == PARTIALLY_SELECTED)
|
||||||
|
locally_all_checked = false;
|
||||||
|
|
||||||
|
if(dit2.check_state == SELECTED || dit2.check_state == PARTIALLY_SELECTED)
|
||||||
|
locally_all_unchecked = false;
|
||||||
|
}
|
||||||
|
for(uint32_t i=0;i<dir_data.subfiles.size() && (locally_all_checked || locally_all_unchecked);++i)
|
||||||
|
{
|
||||||
|
const auto& fit2(mFileInfos[dir_data.subfiles[i]]);
|
||||||
|
|
||||||
|
if(fit2.is_checked)
|
||||||
|
locally_all_unchecked = false;
|
||||||
|
else
|
||||||
|
locally_all_checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(locally_all_checked)
|
||||||
|
dit.check_state = SELECTED;
|
||||||
|
else if(locally_all_unchecked)
|
||||||
|
dit.check_state = UNSELECTED;
|
||||||
|
else
|
||||||
|
dit.check_state = PARTIALLY_SELECTED;
|
||||||
|
|
||||||
|
if(dir_index == mCollection.fileTree().root())
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
dir_index = dit.parent_index; // get the directory data
|
||||||
|
|
||||||
|
}
|
||||||
|
while(true);
|
||||||
|
|
||||||
|
const auto& top_dir(mCollection.fileTree().directoryData(mCollection.fileTree().root()));
|
||||||
|
emit dataChanged(createIndex(0,0,(void*)NULL),
|
||||||
|
createIndex(top_dir.subdirs.size() + top_dir.subfiles.size() - 1,
|
||||||
|
COLLECTION_MODEL_NB_COLUMN-1,
|
||||||
|
(void*)NULL),
|
||||||
|
{ Qt::CheckStateRole });
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return setData(index,value,role);
|
return QAbstractItemModel::setData(index,value,role);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant RsCollectionModel::checkStateRole(const EntryIndex& i,int col) const
|
QVariant RsCollectionModel::checkStateRole(const EntryIndex& i,int col) const
|
||||||
@ -268,27 +344,22 @@ QVariant RsCollectionModel::checkStateRole(const EntryIndex& i,int col) const
|
|||||||
{
|
{
|
||||||
if(i.is_file)
|
if(i.is_file)
|
||||||
{
|
{
|
||||||
auto it = mFileInfos.find(i.index);
|
std::cerr<< "entry is file, checkstate = " << (int)mFileInfos[i.index].is_checked << std::endl;
|
||||||
if(it == mFileInfos.end())
|
if(mFileInfos[i.index].is_checked)
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
if(it->second.is_checked)
|
|
||||||
return QVariant(Qt::Checked);
|
return QVariant(Qt::Checked);
|
||||||
else
|
else
|
||||||
return QVariant(Qt::Unchecked);
|
return QVariant(Qt::Unchecked);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto it = mDirInfos.find(i.index);
|
std::cerr<< "entry is dir, checkstate = " << (int)mDirInfos[i.index].check_state << std::endl;
|
||||||
if(it == mDirInfos.end())
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
switch(it->second.check_state)
|
switch(mDirInfos[i.index].check_state)
|
||||||
{
|
{
|
||||||
case SELECTED: return QVariant(Qt::Checked);
|
case SELECTED: return QVariant::fromValue((int)Qt::Checked);
|
||||||
case PARTIALLY_SELECTED: return QVariant(Qt::PartiallyChecked);
|
case PARTIALLY_SELECTED: return QVariant::fromValue((int)Qt::PartiallyChecked);
|
||||||
default:
|
default:
|
||||||
case UNSELECTED: return QVariant(Qt::Unchecked);
|
case UNSELECTED: return QVariant::fromValue((int)Qt::Unchecked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,12 +378,12 @@ QVariant RsCollectionModel::displayRole(const EntryIndex& i,int col) const
|
|||||||
return QVariant((qulonglong)mCollection.fileTree().fileData(i.index).size) ;
|
return QVariant((qulonglong)mCollection.fileTree().fileData(i.index).size) ;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto it = mDirInfos.find(i.index);
|
// auto it = mDirInfos[i.index];
|
||||||
|
|
||||||
if(it == mDirInfos.end())
|
// if(it == mDirInfos.end())
|
||||||
return QVariant();
|
// return QVariant();
|
||||||
else
|
// else
|
||||||
return QVariant((qulonglong)it->second.total_size);
|
return QVariant((qulonglong)mDirInfos[i.index].total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2: return (i.is_file)?
|
case 2: return (i.is_file)?
|
||||||
@ -344,6 +415,11 @@ void RsCollectionModel::postMods()
|
|||||||
mDirInfos.clear();
|
mDirInfos.clear();
|
||||||
mFileInfos.clear();
|
mFileInfos.clear();
|
||||||
|
|
||||||
|
mDirInfos.resize(mCollection.fileTree().numDirs());
|
||||||
|
mFileInfos.resize(mCollection.fileTree().numFiles());
|
||||||
|
|
||||||
|
mDirInfos[0].parent_index = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_COLLECTION_MODEL
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
std::cerr << "Updating from tree: " << std::endl;
|
std::cerr << "Updating from tree: " << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,8 +80,8 @@ class RsCollectionModel: public QAbstractItemModel
|
|||||||
bool is_checked;
|
bool is_checked;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<uint64_t,ModelFileInfo> mFileInfos;
|
std::vector<ModelFileInfo> mFileInfos;
|
||||||
std::map<uint64_t,ModelDirInfo> mDirInfos;
|
std::vector<ModelDirInfo> mDirInfos;
|
||||||
|
|
||||||
// std::set<void*> mFilteredPointers ;
|
// std::set<void*> mFilteredPointers ;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user