mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-22 22:21:09 -04:00
fixed basic functionality of RsCollectionModel
This commit is contained in:
parent
885eb640dc
commit
2ed72a146b
4 changed files with 141 additions and 44 deletions
|
@ -2,10 +2,28 @@
|
|||
|
||||
#include "RsCollectionModel.h"
|
||||
|
||||
// #define DEBUG_COLLECTION_MODEL 1
|
||||
|
||||
static const int COLLECTION_MODEL_NB_COLUMN = 4;
|
||||
|
||||
RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent)
|
||||
: QAbstractItemModel(parent),mCollection(col)
|
||||
{}
|
||||
{
|
||||
postMods();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
static std::ostream& operator<<(std::ostream& o,const RsCollectionModel::EntryIndex& i)
|
||||
{
|
||||
return o << ((i.is_file)?("File"):"Dir") << " with index " << (int)i.index ;
|
||||
}
|
||||
static std::ostream& operator<<(std::ostream& o,const QModelIndex& i)
|
||||
{
|
||||
return o << "QModelIndex (row " << i.row() << ", of ref " << i.internalId() << ")" ;
|
||||
}
|
||||
#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
|
||||
// architecture, the pointer may have 4 or 8 bytes. We use the low-level bit for type (0=dir, 1=file) and
|
||||
// the remaining bits for the index (which will be accordingly understood as a FileIndex or a DirIndex)
|
||||
|
@ -13,7 +31,7 @@ RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent)
|
|||
|
||||
bool RsCollectionModel::convertIndexToInternalId(const EntryIndex& e,quintptr& ref)
|
||||
{
|
||||
ref = (e.index << 1) || e.is_file;
|
||||
ref = (e.index << 1) | e.is_file;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -26,56 +44,95 @@ bool RsCollectionModel::convertInternalIdToIndex(quintptr ref, EntryIndex& e)
|
|||
|
||||
int RsCollectionModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << "Asking rowCount of " << parent << std::endl;
|
||||
#endif
|
||||
|
||||
if(parent.column() >= COLLECTION_MODEL_NB_COLUMN)
|
||||
return 0;
|
||||
|
||||
if(!parent.isValid())
|
||||
return mCollection.fileTree().root();
|
||||
{
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << " root! returning " << mCollection.fileTree().directoryData(0).subdirs.size()
|
||||
+ mCollection.fileTree().directoryData(0).subfiles.size() << std::endl;
|
||||
#endif
|
||||
|
||||
return mCollection.fileTree().directoryData(0).subdirs.size()
|
||||
+ mCollection.fileTree().directoryData(0).subfiles.size();
|
||||
}
|
||||
|
||||
EntryIndex i;
|
||||
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||
return 0;
|
||||
|
||||
if(i.is_file)
|
||||
{
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << " file: returning 0" << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << " dir: returning " << mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size()
|
||||
<< std::endl;
|
||||
#endif
|
||||
return mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size();
|
||||
}
|
||||
}
|
||||
|
||||
bool RsCollectionModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
if(!parent.isValid())
|
||||
return mCollection.fileTree().root();
|
||||
return true;
|
||||
|
||||
EntryIndex i;
|
||||
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if(i.is_file)
|
||||
return false;
|
||||
else if(mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size() > 0)
|
||||
return true;
|
||||
else
|
||||
return mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size() > 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int RsCollectionModel::columnCount(const QModelIndex&) const
|
||||
{
|
||||
return 4;
|
||||
return COLLECTION_MODEL_NB_COLUMN;
|
||||
}
|
||||
|
||||
QVariant RsCollectionModel::headerData(int section, Qt::Orientation,int) const
|
||||
QVariant RsCollectionModel::headerData(int section, Qt::Orientation,int role) const
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
case 0: return tr("File");
|
||||
case 1: return tr("Size");
|
||||
case 2: return tr("Hash");
|
||||
case 3: return tr("Count");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
if(role == Qt::DisplayRole)
|
||||
switch(section)
|
||||
{
|
||||
case 0: return tr("File");
|
||||
case 1: return tr("Size");
|
||||
case 2: return tr("Hash");
|
||||
case 3: return tr("Count");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & parent) const
|
||||
{
|
||||
if(row < 0 || column < 0 || column >= columnCount(parent) || row >= rowCount(parent))
|
||||
return QModelIndex();
|
||||
|
||||
EntryIndex i;
|
||||
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||
|
||||
if(!parent.isValid()) // root
|
||||
{
|
||||
i.is_file = false;
|
||||
i.index = 0;
|
||||
}
|
||||
else if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||
return QModelIndex();
|
||||
|
||||
if(i.is_file || i.index >= mCollection.fileTree().numDirs())
|
||||
|
@ -83,9 +140,6 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||
|
||||
const auto& parentData(mCollection.fileTree().directoryData(i.index));
|
||||
|
||||
if(row < 0)
|
||||
return QModelIndex();
|
||||
|
||||
if((size_t)row < parentData.subdirs.size())
|
||||
{
|
||||
EntryIndex e;
|
||||
|
@ -94,6 +148,10 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||
|
||||
quintptr ref;
|
||||
convertIndexToInternalId(e,ref);
|
||||
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << "creating index for row " << row << " of parent " << parent << ". result is " << createIndex(row,column,ref) << std::endl;
|
||||
#endif
|
||||
return createIndex(row,column,ref);
|
||||
}
|
||||
|
||||
|
@ -105,6 +163,9 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||
|
||||
quintptr ref;
|
||||
convertIndexToInternalId(e,ref);
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << "creating index for row " << row << " of parent " << parent << ". result is " << createIndex(row,column,ref) << std::endl;
|
||||
#endif
|
||||
return createIndex(row,column,ref);
|
||||
}
|
||||
|
||||
|
@ -113,12 +174,16 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||
|
||||
QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
EntryIndex i;
|
||||
if(!convertInternalIdToIndex(index.internalId(),i))
|
||||
if(!convertInternalIdToIndex(index.internalId(),i) || i.index==0)
|
||||
return QModelIndex();
|
||||
|
||||
EntryIndex p;
|
||||
p.is_file = false; // all parents are directories
|
||||
int row;
|
||||
|
||||
if(i.is_file)
|
||||
{
|
||||
|
@ -128,7 +193,8 @@ QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
|||
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
||||
return QModelIndex();
|
||||
}
|
||||
p.index = it->second;
|
||||
p.index = it->second.parent_index;
|
||||
row = it->second.parent_row;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -138,12 +204,14 @@ QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
|||
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
||||
return QModelIndex();
|
||||
}
|
||||
p.index = it->second;
|
||||
p.index = it->second.parent_index;
|
||||
row = it->second.parent_row;
|
||||
}
|
||||
|
||||
quintptr ref;
|
||||
convertIndexToInternalId(p,ref);
|
||||
return createIndex(0,index.column(),ref);
|
||||
|
||||
return createIndex(row,0,ref);
|
||||
}
|
||||
|
||||
QVariant RsCollectionModel::data(const QModelIndex& index, int role) const
|
||||
|
@ -152,6 +220,9 @@ QVariant RsCollectionModel::data(const QModelIndex& index, int role) const
|
|||
if(!convertInternalIdToIndex(index.internalId(),i))
|
||||
return QVariant();
|
||||
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << "Asking data of " << i << std::endl;
|
||||
#endif
|
||||
switch(role)
|
||||
{
|
||||
case Qt::DisplayRole: return displayRole(i,index.column());
|
||||
|
@ -212,32 +283,54 @@ void RsCollectionModel::postMods()
|
|||
mFileParents.clear();
|
||||
mDirSizes.clear();
|
||||
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
std::cerr << "Updating from tree: " << std::endl;
|
||||
#endif
|
||||
uint64_t s;
|
||||
recursUpdateLocalStructures(mCollection.fileTree().root(),s);
|
||||
recursUpdateLocalStructures(mCollection.fileTree().root(),s,0);
|
||||
|
||||
mUpdating = false;
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
void RsCollectionModel::recursUpdateLocalStructures(RsFileTree::DirIndex dir_index,uint64_t& total_size)
|
||||
void RsCollectionModel::recursUpdateLocalStructures(RsFileTree::DirIndex dir_index,uint64_t& total_size,int depth)
|
||||
{
|
||||
total_size = 0;
|
||||
|
||||
const auto& dd(mCollection.fileTree().directoryData(dir_index));
|
||||
|
||||
for(uint32_t i=0;i<dd.subfiles.size();++i)
|
||||
{
|
||||
total_size += mCollection.fileTree().fileData(dd.subfiles[i]).size;
|
||||
mFileParents[dd.subfiles[i]] = dir_index;
|
||||
}
|
||||
|
||||
for(uint32_t i=0;i<dd.subdirs.size();++i)
|
||||
{
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
for(int j=0;j<depth;++j) std::cerr << " ";
|
||||
std::cerr << "Dir \"" << mCollection.fileTree().directoryData(dd.subdirs[i]).name << "\"" << std::endl ;
|
||||
#endif
|
||||
|
||||
uint64_t ss;
|
||||
recursUpdateLocalStructures(dd.subdirs[i],ss);
|
||||
recursUpdateLocalStructures(dd.subdirs[i],ss,depth+1);
|
||||
total_size += ss;
|
||||
mDirParents[dd.subdirs[i]] = dir_index;
|
||||
|
||||
auto& ref(mDirParents[dd.subdirs[i]]);
|
||||
|
||||
ref.parent_index = dir_index;
|
||||
ref.parent_row = i;
|
||||
}
|
||||
|
||||
for(uint32_t i=0;i<dd.subfiles.size();++i)
|
||||
{
|
||||
#ifdef DEBUG_COLLECTION_MODEL
|
||||
for(int j=0;j<depth;++j) std::cerr << " ";
|
||||
std::cerr << "File \"" << mCollection.fileTree().fileData(dd.subfiles[i]).name << "\"" << std::endl;
|
||||
#endif
|
||||
|
||||
total_size += mCollection.fileTree().fileData(dd.subfiles[i]).size;
|
||||
|
||||
auto& ref(mFileParents[dd.subfiles[i]]);
|
||||
|
||||
ref.parent_index = dir_index;
|
||||
ref.parent_row = i + dd.subdirs.size();
|
||||
}
|
||||
|
||||
mDirSizes[dir_index] = total_size;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue