diff --git a/retroshare-gui/src/gui/common/RsCollectionModel.cpp b/retroshare-gui/src/gui/common/RsCollectionModel.cpp index c0485360d..87fe1fb53 100644 --- a/retroshare-gui/src/gui/common/RsCollectionModel.cpp +++ b/retroshare-gui/src/gui/common/RsCollectionModel.cpp @@ -4,6 +4,10 @@ // #define DEBUG_COLLECTION_MODEL 1 +static const int COLLECTION_MODEL_FILENAME = 0; +static const int COLLECTION_MODEL_SIZE = 1; +static const int COLLECTION_MODEL_HASH = 2; +static const int COLLECTION_MODEL_COUNT = 3; static const int COLLECTION_MODEL_NB_COLUMN = 4; RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent) @@ -172,6 +176,14 @@ QModelIndex RsCollectionModel::index(int row, int column, const QModelIndex & pa return QModelIndex(); } +Qt::ItemFlags RsCollectionModel::flags ( const QModelIndex & index ) const +{ + if(index.isValid() && index.column() == COLLECTION_MODEL_FILENAME) + return QAbstractItemModel::flags(index) | Qt::ItemIsUserTristate; + + return QAbstractItemModel::flags(index) & ~Qt::ItemIsUserTristate; +} + QModelIndex RsCollectionModel::parent(const QModelIndex & index) const { if(!index.isValid()) @@ -187,8 +199,8 @@ QModelIndex RsCollectionModel::parent(const QModelIndex & index) const if(i.is_file) { - const auto it = mFileParents.find(i.index); - if(it == mFileParents.end()) + const auto it = mFileInfos.find(i.index); + if(it == mFileInfos.end()) { RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column(); return QModelIndex(); @@ -198,8 +210,8 @@ QModelIndex RsCollectionModel::parent(const QModelIndex & index) const } else { - const auto it = mDirParents.find(i.index); - if(it == mDirParents.end()) + const auto it = mDirInfos.find(i.index); + if(it == mDirInfos.end()) { RsErr() << "Error: parent not found for index " << index.row() << ", " << index.column(); return QModelIndex(); @@ -228,11 +240,61 @@ QVariant RsCollectionModel::data(const QModelIndex& index, int role) const 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::CheckStateRole: return checkStateRole(i,index.column()); default: return QVariant(); } } +bool RsCollectionModel::setData(const QModelIndex& index,const QVariant& value,int role) +{ + if(!index.isValid()) + return false; + + if (role==Qt::CheckStateRole) + { +#ifdef DEBUG_COLLECTION_MODEL + std::cerr << "Setting check state of item " << index << " to " << value.toBool() << std::endl; +#endif + return true; + } + else + return setData(index,value,role); +} + +QVariant RsCollectionModel::checkStateRole(const EntryIndex& i,int col) const +{ + if(col == COLLECTION_MODEL_FILENAME) + { + if(i.is_file) + { + auto it = mFileInfos.find(i.index); + if(it == mFileInfos.end()) + return QVariant(); + + if(it->second.is_checked) + return QVariant(Qt::Checked); + else + return QVariant(Qt::Unchecked); + } + else + { + auto it = mDirInfos.find(i.index); + if(it == mDirInfos.end()) + return QVariant(); + + switch(it->second.check_state) + { + case SELECTED: return QVariant(Qt::Checked); + case PARTIALLY_SELECTED: return QVariant(Qt::PartiallyChecked); + default: + case UNSELECTED: return QVariant(Qt::Unchecked); + } + } + } + else + return QVariant(); +} QVariant RsCollectionModel::displayRole(const EntryIndex& i,int col) const { switch(col) @@ -245,12 +307,12 @@ QVariant RsCollectionModel::displayRole(const EntryIndex& i,int col) const return QVariant((qulonglong)mCollection.fileTree().fileData(i.index).size) ; { - auto it = mDirSizes.find(i.index); + auto it = mDirInfos.find(i.index); - if(it == mDirSizes.end()) + if(it == mDirInfos.end()) return QVariant(); else - return QVariant((qulonglong)it->second); + return QVariant((qulonglong)it->second.total_size); } case 2: return (i.is_file)? @@ -279,9 +341,8 @@ void RsCollectionModel::postMods() { // update all the local structures - mDirParents.clear(); - mFileParents.clear(); - mDirSizes.clear(); + mDirInfos.clear(); + mFileInfos.clear(); #ifdef DEBUG_COLLECTION_MODEL std::cerr << "Updating from tree: " << std::endl; @@ -296,9 +357,29 @@ void RsCollectionModel::postMods() void RsCollectionModel::recursUpdateLocalStructures(RsFileTree::DirIndex dir_index,uint64_t& total_size,int depth) { total_size = 0; + bool all_checked = true; + bool all_unchecked = false; const auto& dd(mCollection.fileTree().directoryData(dir_index)); + for(uint32_t i=0;i= QT_VERSION_CHECK (5, 0, 0) @@ -53,20 +54,34 @@ class RsCollectionModel: public QAbstractItemModel QVariant displayRole(const EntryIndex&,int col) const ; QVariant sortRole(const EntryIndex&,int col) const ; QVariant decorationRole(const EntryIndex&,int col) const ; + QVariant checkStateRole(const EntryIndex& i,int col) const; //QVariant filterRole(const DirDetails& details,int coln) const; bool mUpdating ; const RsCollection& mCollection; - struct ParentInfo { - RsFileTree::DirIndex parent_index; // index of the parent - RsFileTree::DirIndex parent_row; // row of that child, in this parent + enum DirCheckState: uint8_t { + UNSELECTED = 0x00, + PARTIALLY_SELECTED = 0x01, + SELECTED = 0x02, }; - std::map mFileParents; - std::map mDirParents; - std::map mDirSizes; + struct ModelDirInfo { + RsFileTree::DirIndex parent_index; // index of the parent + RsFileTree::DirIndex parent_row; // row of that child, in this parent + DirCheckState check_state; + uint64_t total_size; + }; + + struct ModelFileInfo { + RsFileTree::DirIndex parent_index; // index of the parent + RsFileTree::DirIndex parent_row; // row of that child, in this parent + bool is_checked; + }; + + std::map mFileInfos; + std::map mDirInfos; // std::set mFilteredPointers ; };