mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-23 13:51:12 -05:00
fixed basic functionality of RsCollectionModel
This commit is contained in:
parent
885eb640dc
commit
2ed72a146b
@ -307,9 +307,9 @@ RsCollectionDialog::~RsCollectionDialog()
|
||||
* @param event: event occured
|
||||
* @return If we don't have to process event in parent.
|
||||
*/
|
||||
#ifdef TODO_COLLECTION
|
||||
bool RsCollectionDialog::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
#ifdef TODO_COLLECTION
|
||||
if (obj == ui._fileEntriesTW) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||
@ -367,9 +367,8 @@ bool RsCollectionDialog::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
// pass the event on to the parent class
|
||||
return QDialog::eventFilter(obj, event);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RsCollectionDialog::processSettings
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
static bool openExistingCollection(const QString& fileName, bool readOnly = false, bool showError = true);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev);
|
||||
//bool eventFilter(QObject *obj, QEvent *ev);
|
||||
|
||||
RsCollectionDialog(const QString& filename, const bool& creation, const bool& readOnly = false) ;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ class RsCollectionModel: public QAbstractItemModel
|
||||
|
||||
/* Callback from GUI */
|
||||
|
||||
void update() {}
|
||||
void update() ;
|
||||
void filterItems(const std::list<std::string>& keywords, uint32_t& found) ;
|
||||
|
||||
// Overloaded from QAbstractItemModel
|
||||
@ -40,15 +40,15 @@ class RsCollectionModel: public QAbstractItemModel
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
struct EntryIndex {
|
||||
bool is_file; // false=dir, true=file
|
||||
uint64_t index;
|
||||
};
|
||||
private:
|
||||
static bool convertIndexToInternalId(const EntryIndex& e,quintptr& ref);
|
||||
static bool convertInternalIdToIndex(quintptr ref, EntryIndex& e);
|
||||
|
||||
void recursUpdateLocalStructures(RsFileTree::DirIndex dir_index,uint64_t& total_size);
|
||||
void recursUpdateLocalStructures(RsFileTree::DirIndex dir_index, uint64_t& total_size, int depth);
|
||||
|
||||
QVariant displayRole(const EntryIndex&,int col) const ;
|
||||
QVariant sortRole(const EntryIndex&,int col) const ;
|
||||
@ -59,8 +59,13 @@ class RsCollectionModel: public QAbstractItemModel
|
||||
|
||||
const RsCollection& mCollection;
|
||||
|
||||
std::map<uint64_t,RsFileTree::DirIndex> mFileParents;
|
||||
std::map<uint64_t,RsFileTree::DirIndex> mDirParents;
|
||||
struct ParentInfo {
|
||||
RsFileTree::DirIndex parent_index; // index of the parent
|
||||
RsFileTree::DirIndex parent_row; // row of that child, in this parent
|
||||
};
|
||||
|
||||
std::map<uint64_t,ParentInfo> mFileParents;
|
||||
std::map<uint64_t,ParentInfo> mDirParents;
|
||||
std::map<uint64_t,uint64_t> mDirSizes;
|
||||
|
||||
// std::set<void*> mFilteredPointers ;
|
||||
|
Loading…
Reference in New Issue
Block a user