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
|
* @param event: event occured
|
||||||
* @return If we don't have to process event in parent.
|
* @return If we don't have to process event in parent.
|
||||||
*/
|
*/
|
||||||
|
#ifdef TODO_COLLECTION
|
||||||
bool RsCollectionDialog::eventFilter(QObject *obj, QEvent *event)
|
bool RsCollectionDialog::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
#ifdef TODO_COLLECTION
|
|
||||||
if (obj == ui._fileEntriesTW) {
|
if (obj == ui._fileEntriesTW) {
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
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
|
// pass the event on to the parent class
|
||||||
return QDialog::eventFilter(obj, event);
|
return QDialog::eventFilter(obj, event);
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief RsCollectionDialog::processSettings
|
* @brief RsCollectionDialog::processSettings
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
static bool openExistingCollection(const QString& fileName, bool readOnly = false, bool showError = true);
|
static bool openExistingCollection(const QString& fileName, bool readOnly = false, bool showError = true);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *ev);
|
//bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
|
|
||||||
RsCollectionDialog(const QString& filename, const bool& creation, const bool& readOnly = false) ;
|
RsCollectionDialog(const QString& filename, const bool& creation, const bool& readOnly = false) ;
|
||||||
|
|
||||||
|
@ -2,10 +2,28 @@
|
|||||||
|
|
||||||
#include "RsCollectionModel.h"
|
#include "RsCollectionModel.h"
|
||||||
|
|
||||||
|
// #define DEBUG_COLLECTION_MODEL 1
|
||||||
|
|
||||||
|
static const int COLLECTION_MODEL_NB_COLUMN = 4;
|
||||||
|
|
||||||
RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent)
|
RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent)
|
||||||
: QAbstractItemModel(parent),mCollection(col)
|
: 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
|
// 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
|
// 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)
|
// 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)
|
bool RsCollectionModel::convertIndexToInternalId(const EntryIndex& e,quintptr& ref)
|
||||||
{
|
{
|
||||||
ref = (e.index << 1) || e.is_file;
|
ref = (e.index << 1) | e.is_file;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,56 +44,95 @@ bool RsCollectionModel::convertInternalIdToIndex(quintptr ref, EntryIndex& e)
|
|||||||
|
|
||||||
int RsCollectionModel::rowCount(const QModelIndex& parent) const
|
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())
|
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;
|
EntryIndex i;
|
||||||
if(!convertInternalIdToIndex(parent.internalId(),i))
|
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(i.is_file)
|
if(i.is_file)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << " file: returning 0" << std::endl;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else
|
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();
|
return mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsCollectionModel::hasChildren(const QModelIndex & parent) const
|
bool RsCollectionModel::hasChildren(const QModelIndex & parent) const
|
||||||
{
|
{
|
||||||
if(!parent.isValid())
|
if(!parent.isValid())
|
||||||
return mCollection.fileTree().root();
|
return true;
|
||||||
|
|
||||||
EntryIndex i;
|
EntryIndex i;
|
||||||
if(!convertInternalIdToIndex(parent.internalId(),i))
|
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if(i.is_file)
|
if(i.is_file)
|
||||||
return false;
|
return false;
|
||||||
|
else if(mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size() > 0)
|
||||||
|
return true;
|
||||||
else
|
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
|
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)
|
if(role == Qt::DisplayRole)
|
||||||
{
|
switch(section)
|
||||||
case 0: return tr("File");
|
{
|
||||||
case 1: return tr("Size");
|
case 0: return tr("File");
|
||||||
case 2: return tr("Hash");
|
case 1: return tr("Size");
|
||||||
case 3: return tr("Count");
|
case 2: return tr("Hash");
|
||||||
default:
|
case 3: return tr("Count");
|
||||||
return QVariant();
|
default:
|
||||||
}
|
return QVariant();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & parent) const
|
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;
|
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();
|
return QModelIndex();
|
||||||
|
|
||||||
if(i.is_file || i.index >= mCollection.fileTree().numDirs())
|
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));
|
const auto& parentData(mCollection.fileTree().directoryData(i.index));
|
||||||
|
|
||||||
if(row < 0)
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
if((size_t)row < parentData.subdirs.size())
|
if((size_t)row < parentData.subdirs.size())
|
||||||
{
|
{
|
||||||
EntryIndex e;
|
EntryIndex e;
|
||||||
@ -94,6 +148,10 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||||||
|
|
||||||
quintptr ref;
|
quintptr ref;
|
||||||
convertIndexToInternalId(e,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);
|
return createIndex(row,column,ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +163,9 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa
|
|||||||
|
|
||||||
quintptr ref;
|
quintptr ref;
|
||||||
convertIndexToInternalId(e,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);
|
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
|
QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
||||||
{
|
{
|
||||||
|
if(!index.isValid())
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
EntryIndex i;
|
EntryIndex i;
|
||||||
if(!convertInternalIdToIndex(index.internalId(),i))
|
if(!convertInternalIdToIndex(index.internalId(),i) || i.index==0)
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
EntryIndex p;
|
EntryIndex p;
|
||||||
p.is_file = false; // all parents are directories
|
p.is_file = false; // all parents are directories
|
||||||
|
int row;
|
||||||
|
|
||||||
if(i.is_file)
|
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();
|
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
p.index = it->second;
|
p.index = it->second.parent_index;
|
||||||
|
row = it->second.parent_row;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -138,12 +204,14 @@ QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
|||||||
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column();
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
p.index = it->second;
|
p.index = it->second.parent_index;
|
||||||
|
row = it->second.parent_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
quintptr ref;
|
quintptr ref;
|
||||||
convertIndexToInternalId(p,ref);
|
convertIndexToInternalId(p,ref);
|
||||||
return createIndex(0,index.column(),ref);
|
|
||||||
|
return createIndex(row,0,ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant RsCollectionModel::data(const QModelIndex& index, int role) const
|
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))
|
if(!convertInternalIdToIndex(index.internalId(),i))
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "Asking data of " << i << std::endl;
|
||||||
|
#endif
|
||||||
switch(role)
|
switch(role)
|
||||||
{
|
{
|
||||||
case Qt::DisplayRole: return displayRole(i,index.column());
|
case Qt::DisplayRole: return displayRole(i,index.column());
|
||||||
@ -212,32 +283,54 @@ void RsCollectionModel::postMods()
|
|||||||
mFileParents.clear();
|
mFileParents.clear();
|
||||||
mDirSizes.clear();
|
mDirSizes.clear();
|
||||||
|
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "Updating from tree: " << std::endl;
|
||||||
|
#endif
|
||||||
uint64_t s;
|
uint64_t s;
|
||||||
recursUpdateLocalStructures(mCollection.fileTree().root(),s);
|
recursUpdateLocalStructures(mCollection.fileTree().root(),s,0);
|
||||||
|
|
||||||
mUpdating = false;
|
mUpdating = false;
|
||||||
emit layoutChanged();
|
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;
|
total_size = 0;
|
||||||
|
|
||||||
const auto& dd(mCollection.fileTree().directoryData(dir_index));
|
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)
|
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;
|
uint64_t ss;
|
||||||
recursUpdateLocalStructures(dd.subdirs[i],ss);
|
recursUpdateLocalStructures(dd.subdirs[i],ss,depth+1);
|
||||||
total_size += ss;
|
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;
|
mDirSizes[dir_index] = total_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class RsCollectionModel: public QAbstractItemModel
|
|||||||
|
|
||||||
/* Callback from GUI */
|
/* Callback from GUI */
|
||||||
|
|
||||||
void update() {}
|
void update() ;
|
||||||
void filterItems(const std::list<std::string>& keywords, uint32_t& found) ;
|
void filterItems(const std::list<std::string>& keywords, uint32_t& found) ;
|
||||||
|
|
||||||
// Overloaded from QAbstractItemModel
|
// Overloaded from QAbstractItemModel
|
||||||
@ -40,15 +40,15 @@ class RsCollectionModel: public QAbstractItemModel
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
|
||||||
struct EntryIndex {
|
struct EntryIndex {
|
||||||
bool is_file; // false=dir, true=file
|
bool is_file; // false=dir, true=file
|
||||||
uint64_t index;
|
uint64_t index;
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
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);
|
||||||
|
|
||||||
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 displayRole(const EntryIndex&,int col) const ;
|
||||||
QVariant sortRole(const EntryIndex&,int col) const ;
|
QVariant sortRole(const EntryIndex&,int col) const ;
|
||||||
@ -59,8 +59,13 @@ class RsCollectionModel: public QAbstractItemModel
|
|||||||
|
|
||||||
const RsCollection& mCollection;
|
const RsCollection& mCollection;
|
||||||
|
|
||||||
std::map<uint64_t,RsFileTree::DirIndex> mFileParents;
|
struct ParentInfo {
|
||||||
std::map<uint64_t,RsFileTree::DirIndex> mDirParents;
|
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::map<uint64_t,uint64_t> mDirSizes;
|
||||||
|
|
||||||
// std::set<void*> mFilteredPointers ;
|
// std::set<void*> mFilteredPointers ;
|
||||||
|
Loading…
Reference in New Issue
Block a user