implemented RsCollectionModel

This commit is contained in:
csoler 2024-02-25 17:58:51 +01:00
parent 97309f2f9f
commit eb0ef1e39b
3 changed files with 157 additions and 42 deletions

View File

@ -155,36 +155,21 @@ void RsCollection::merge_in(const QString& fname,uint64_t size,const RsFileHash&
} }
void RsCollection::merge_in(const RsFileTree& tree) void RsCollection::merge_in(const RsFileTree& tree)
{ {
RsFileTree::DirData dd; recursMergeTree(mFileTree.root(),tree,tree.directoryData(tree.root())) ;
tree.getDirectoryContent(tree.root(),dd);
recursMergeTree(mFileTree.root(),tree,dd) ;
} }
void RsCollection::recursMergeTree(RsFileTree::DirIndex parent,const RsFileTree& tree,const RsFileTree::DirData& dd) void RsCollection::recursMergeTree(RsFileTree::DirIndex parent,const RsFileTree& tree,const RsFileTree::DirData& dd)
{ {
for(uint32_t i=0;i<dd.subfiles.size();++i) for(uint32_t i=0;i<dd.subfiles.size();++i)
{ {
RsFileTree::FileData fd; const RsFileTree::FileData& fd(tree.fileData(dd.subfiles[i]));
if(!tree.getFileContent(dd.subfiles[i],fd))
{
RsErr() << "Error while merging file trees. This should not happen. Report a bug!";
return;
}
mFileTree.addFile(parent,fd.name,fd.hash,fd.size); mFileTree.addFile(parent,fd.name,fd.hash,fd.size);
} }
for(uint32_t i=0;i<dd.subdirs.size();++i) for(uint32_t i=0;i<dd.subdirs.size();++i)
{ {
RsFileTree::DirData ld; const RsFileTree::DirData& ld(tree.directoryData(dd.subdirs[i]));
if(!tree.getDirectoryContent(dd.subdirs[i],ld))
{
RsErr() << "Error while merging file trees. This should not happen. Report a bug!";
return;
}
auto new_dir_index = mFileTree.addDirectory(parent,ld.name); auto new_dir_index = mFileTree.addDirectory(parent,ld.name);
recursMergeTree(new_dir_index,tree,ld); recursMergeTree(new_dir_index,tree,ld);
} }
} }
@ -480,9 +465,7 @@ bool RsCollection::save(const QString& fileName) const
QDomDocument xml_doc ; QDomDocument xml_doc ;
QDomElement root = xml_doc.createElement("RsCollection"); QDomElement root = xml_doc.createElement("RsCollection");
RsFileTree::DirData root_data; const RsFileTree::DirData& root_data(mFileTree.directoryData(mFileTree.root()));
if(!mFileTree.getDirectoryContent(mFileTree.root(),root_data))
return false;
if(!recursExportToXml(xml_doc,root,root_data)) if(!recursExportToXml(xml_doc,root,root_data))
return false; return false;
@ -571,9 +554,7 @@ bool RsCollection::recursExportToXml(QDomDocument& doc,QDomElement& e,const RsFi
{ {
QDomElement f = doc.createElement("File") ; QDomElement f = doc.createElement("File") ;
RsFileTree::FileData fd; const RsFileTree::FileData& fd(mFileTree.fileData(dd.subfiles[i]));
if(!mFileTree.getFileContent(dd.subfiles[i],fd))
return false;
f.setAttribute(QString("name"),QString::fromUtf8(fd.name.c_str())) ; f.setAttribute(QString("name"),QString::fromUtf8(fd.name.c_str())) ;
f.setAttribute(QString("sha1"),QString::fromStdString(fd.hash.toStdString())) ; f.setAttribute(QString("sha1"),QString::fromStdString(fd.hash.toStdString())) ;
@ -584,9 +565,7 @@ bool RsCollection::recursExportToXml(QDomDocument& doc,QDomElement& e,const RsFi
for(uint32_t i=0;i<dd.subdirs.size();++i) for(uint32_t i=0;i<dd.subdirs.size();++i)
{ {
RsFileTree::DirData di; const RsFileTree::DirData& di(mFileTree.directoryData(dd.subdirs[i]));
if(!mFileTree.getDirectoryContent(dd.subdirs[i],di))
return false;
QDomElement d = doc.createElement("Directory") ; QDomElement d = doc.createElement("Directory") ;
d.setAttribute(QString("name"),QString::fromUtf8(di.name.c_str())) ; d.setAttribute(QString("name"),QString::fromUtf8(di.name.c_str())) ;

View File

@ -32,12 +32,12 @@ int RsCollectionModel::rowCount(const QModelIndex& parent) const
if(i.is_file) if(i.is_file)
return 0; return 0;
else else
return mCollection.fileTree().directoryData(i.index).subdirs.size(); return mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size();
} }
int RsCollectionModel::columnCount(const QModelIndex&) const int RsCollectionModel::columnCount(const QModelIndex&) const
{ {
return 5; return 4;
} }
QVariant RsCollectionModel::headerData(int section, Qt::Orientation,int) const QVariant RsCollectionModel::headerData(int section, Qt::Orientation,int) const
@ -45,12 +45,146 @@ QVariant RsCollectionModel::headerData(int section, Qt::Orientation,int) const
switch(section) switch(section)
{ {
case 0: return tr("File"); case 0: return tr("File");
case 1: return tr("Path"); case 1: return tr("Size");
case 2: return tr("Size"); case 2: return tr("Hash");
case 3: return tr("Hash"); case 3: return tr("Count");
case 4: return tr("Count");
default: default:
return QVariant(); return QVariant();
} }
} }
QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & parent) const
{
EntryIndex i;
if(!convertInternalIdToIndex(parent.internalId(),i))
return QModelIndex();
if(i.is_file || i.index >= mCollection.fileTree().numDirs())
return QModelIndex();
const auto& parentData(mCollection.fileTree().directoryData(i.index));
if(row < 0)
return QModelIndex();
if((size_t)row < parentData.subdirs.size())
{
EntryIndex e;
e.is_file = false;
e.index = parentData.subdirs[row];
quintptr ref;
convertIndexToInternalId(e,ref);
return createIndex(row,column,ref);
}
if((size_t)row < parentData.subdirs.size() + parentData.subfiles.size())
{
EntryIndex e;
e.is_file = true;
e.index = parentData.subfiles[row - parentData.subdirs.size()];
quintptr ref;
convertIndexToInternalId(e,ref);
return createIndex(row,column,ref);
}
return QModelIndex();
}
QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
{
EntryIndex i;
if(!convertInternalIdToIndex(index.internalId(),i))
return QModelIndex();
EntryIndex p;
p.is_file = false; // all parents are directories
if(i.is_file)
{
const auto it = mFileParents.find(i.index);
if(it == mFileParents.end())
{
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
return QModelIndex();
}
p.index = it->second;
}
else
{
const auto it = mDirParents.find(i.index);
if(it == mDirParents.end())
{
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
return QModelIndex();
}
p.index = it->second;
}
quintptr ref;
convertIndexToInternalId(p,ref);
return createIndex(0,index.column(),ref);
}
QVariant RsCollectionModel::data(const QModelIndex& index, int role) const
{
EntryIndex i;
if(!convertInternalIdToIndex(index.internalId(),i))
return QVariant();
switch(role)
{
case Qt::DisplayRole: return displayRole(i,index.column());
//case Qt::SortRole: return SortRole(i,index.column());
case Qt::DecorationRole: return decorationRole(i,index.column());
default:
return QVariant();
}
}
QVariant RsCollectionModel::displayRole(const EntryIndex& i,int col) const
{
switch(col)
{
case 0: return (i.is_file)?
(QString::fromUtf8(mCollection.fileTree().fileData(i.index).name.c_str()))
: (QString::fromUtf8(mCollection.fileTree().directoryData(i.index).name.c_str()));
case 1: if(i.is_file)
return QVariant((qulonglong)mCollection.fileTree().fileData(i.index).size) ;
{
auto it = mDirSizes.find(i.index);
if(it == mDirSizes.end())
return QVariant();
else
return QVariant((qulonglong)it->second);
}
case 2: return (i.is_file)?
QString::fromStdString(mCollection.fileTree().fileData(i.index).hash.toStdString())
:QVariant();
case 3: return (i.is_file)?((qulonglong)1):((qulonglong)(mCollection.fileTree().directoryData(i.index).subdirs.size()));
}
return QVariant();
}
QVariant RsCollectionModel::sortRole(const EntryIndex& i,int col) const
{
return QVariant();
}
QVariant RsCollectionModel::decorationRole(const EntryIndex& i,int col) const
{
return QVariant();
}

View File

@ -9,13 +9,12 @@ class RsCollectionModel: public QAbstractItemModel
public: public:
enum Roles{ FileNameRole = Qt::UserRole+1, SortRole = Qt::UserRole+2, FilterRole = Qt::UserRole+3 }; enum Roles{ FileNameRole = Qt::UserRole+1, SortRole = Qt::UserRole+2, FilterRole = Qt::UserRole+3 };
RsCollectionModel(bool mode, QObject *parent = 0); RsCollectionModel(const RsCollection& col, QObject *parent = 0);
virtual ~RsCollectionModel() ; virtual ~RsCollectionModel() ;
/* Callback from Core */ /* Callback from Core */
void preMods(); void preMods(); // always call this before updating the RsCollection!
void postMods(); void postMods(); // always call this after updating the RsCollection!
/* Callback from GUI */ /* Callback from GUI */
@ -48,15 +47,18 @@ class RsCollectionModel: public QAbstractItemModel
static bool convertIndexToInternalId(const EntryIndex& e,quintptr& ref); static bool convertIndexToInternalId(const EntryIndex& e,quintptr& ref);
static bool convertInternalIdToIndex(quintptr ref, EntryIndex& e); static bool convertInternalIdToIndex(quintptr ref, EntryIndex& e);
// virtual QVariant displayRole(const DirDetails&,int) const = 0 ; QVariant displayRole(const EntryIndex&,int col) const ;
// virtual QVariant sortRole(const QModelIndex&,const DirDetails&,int) const =0; QVariant sortRole(const EntryIndex&,int col) const ;
QVariant decorationRole(const EntryIndex&,int col) const ;
// QVariant decorationRole(const DirDetails&,int) const ; //QVariant filterRole(const DirDetails& details,int coln) const;
// QVariant filterRole(const DirDetails& details,int coln) const;
bool mUpdating ; bool mUpdating ;
const RsCollection& mCollection; const RsCollection& mCollection;
std::map<uint64_t,RsFileTree::DirIndex> mFileParents;
std::map<uint64_t,RsFileTree::DirIndex> mDirParents;
std::map<uint64_t,uint64_t> mDirSizes;
// std::set<void*> mFilteredPointers ; // std::set<void*> mFilteredPointers ;
}; };