mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-02 09:55:55 +00:00
- Fixed a lot of bugs in the new TorrentFilesModel
This commit is contained in:
parent
d006327f14
commit
2e2e506162
@ -49,19 +49,23 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// File Construction
|
// File Construction
|
||||||
TreeItem(file_entry const& f, TreeItem *parent=0) {
|
TreeItem(file_entry const& f, TreeItem *parent) {
|
||||||
parentItem = parent;
|
parentItem = parent;
|
||||||
type = TFILE;
|
type = TFILE;
|
||||||
itemData << misc::toQString(f.path.string()).split("/").last();
|
itemData << misc::toQString(f.path.string()).split("/").last();
|
||||||
|
qDebug("Created a TreeItem file with name %s", getName().toLocal8Bit().data());
|
||||||
|
qDebug("parent is %s", parent->getName().toLocal8Bit().data());
|
||||||
itemData << f.size;
|
itemData << f.size;
|
||||||
itemData << 0.; // Progress;
|
itemData << 0.; // Progress;
|
||||||
itemData << 1; // Priority
|
itemData << 1; // Priority
|
||||||
|
if(parent)
|
||||||
|
parent->updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Folder constructor
|
// Folder constructor
|
||||||
TreeItem(QString name, TreeItem *parent=0) {
|
TreeItem(QString name, TreeItem *parent=0) {
|
||||||
type = FOLDER;
|
|
||||||
parentItem = parent;
|
parentItem = parent;
|
||||||
|
type = FOLDER;
|
||||||
itemData << name;
|
itemData << name;
|
||||||
itemData << 0.; // Size
|
itemData << 0.; // Size
|
||||||
itemData << 0.; // Progress;
|
itemData << 0.; // Progress;
|
||||||
@ -69,25 +73,45 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
TreeItem(QList<QVariant> data) {
|
TreeItem(QList<QVariant> data) {
|
||||||
|
parentItem = 0;
|
||||||
type = ROOT;
|
type = ROOT;
|
||||||
itemData = data;
|
itemData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
~TreeItem() {
|
~TreeItem() {
|
||||||
|
qDebug("Deleting item: %s", getName().toLocal8Bit().data());
|
||||||
qDeleteAll(childItems);
|
qDeleteAll(childItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deleteAllChildren() {
|
||||||
|
Q_ASSERT(type==ROOT);
|
||||||
|
qDeleteAll(childItems);
|
||||||
|
childItems.clear();
|
||||||
|
Q_ASSERT(childItems.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<TreeItem*>& children() const {
|
||||||
|
return childItems;
|
||||||
|
}
|
||||||
|
|
||||||
QString getName() const {
|
QString getName() const {
|
||||||
|
//Q_ASSERT(type != ROOT);
|
||||||
return itemData.first().toString();
|
return itemData.first().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getSize() const {
|
void setName(QString name) {
|
||||||
|
Q_ASSERT(type != ROOT);
|
||||||
|
itemData.replace(0, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
qulonglong getSize() const {
|
||||||
return itemData.value(1).toULongLong();
|
return itemData.value(1).toULongLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSize(size_t size) {
|
void setSize(qulonglong size) {
|
||||||
|
qDebug("Called setSize(%llu) in %s", (unsigned long long)size, getName().toLocal8Bit().data());
|
||||||
if(getSize() == size) return;
|
if(getSize() == size) return;
|
||||||
itemData.replace(1, size);
|
itemData.replace(1, (qulonglong)size);
|
||||||
if(parentItem)
|
if(parentItem)
|
||||||
parentItem->updateSize();
|
parentItem->updateSize();
|
||||||
}
|
}
|
||||||
@ -95,9 +119,11 @@ public:
|
|||||||
void updateSize() {
|
void updateSize() {
|
||||||
if(type == ROOT) return;
|
if(type == ROOT) return;
|
||||||
Q_ASSERT(type == FOLDER);
|
Q_ASSERT(type == FOLDER);
|
||||||
size_t size = 0;
|
qulonglong size = 0;
|
||||||
|
qDebug("UpdateSize in %s", getName().toLocal8Bit().data());
|
||||||
foreach(TreeItem* child, childItems) {
|
foreach(TreeItem* child, childItems) {
|
||||||
size += child->getSize();
|
size += child->getSize();
|
||||||
|
qDebug("Child %s has size %llu", child->getName().toLocal8Bit().data(), (unsigned long long)child->getSize());
|
||||||
}
|
}
|
||||||
setSize(size);
|
setSize(size);
|
||||||
}
|
}
|
||||||
@ -162,16 +188,29 @@ public:
|
|||||||
setPriority(priority);
|
setPriority(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TreeItem* childWithName(QString name) const {
|
||||||
|
foreach(TreeItem *child, childItems) {
|
||||||
|
if(child->getName() == name) return child;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool isFolder() const {
|
bool isFolder() const {
|
||||||
return (type==FOLDER);
|
return (type==FOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendChild(TreeItem *item) {
|
void appendChild(TreeItem *item) {
|
||||||
|
Q_ASSERT(item);
|
||||||
|
Q_ASSERT(!childWithName(item->getName()));
|
||||||
|
Q_ASSERT(parentItem != item);
|
||||||
|
Q_ASSERT(type != TFILE);
|
||||||
childItems.append(item);
|
childItems.append(item);
|
||||||
|
Q_ASSERT(type != ROOT || childItems.size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *child(int row) {
|
TreeItem *child(int row) {
|
||||||
return childItems.value(row);
|
//Q_ASSERT(row >= 0 && row < childItems.size());
|
||||||
|
return childItems.value(row, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int childCount() const {
|
int childCount() const {
|
||||||
@ -187,9 +226,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int row() const {
|
int row() const {
|
||||||
if (parentItem)
|
if (parentItem) {
|
||||||
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
|
return parentItem->children().indexOf(const_cast<TreeItem*>(this));
|
||||||
|
}
|
||||||
|
Q_ASSERT(0); // Should not go through here
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,12 +245,11 @@ private:
|
|||||||
TreeItem **files_index;
|
TreeItem **files_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TorrentFilesModel(torrent_info const& t, QObject *parent): QAbstractItemModel(parent) {
|
TorrentFilesModel(QObject *parent=0): QAbstractItemModel(parent) {
|
||||||
files_index = new TreeItem*[t.num_files()];
|
files_index = 0;
|
||||||
QList<QVariant> rootData;
|
QList<QVariant> rootData;
|
||||||
rootData << "Name" << "Size" << "Progress" << "Priority";
|
rootData << "Name" << "Size" << "Progress" << "Priority";
|
||||||
rootItem = new TreeItem(rootData);
|
rootItem = new TreeItem(rootData);
|
||||||
setupModelData(t, rootItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~TorrentFilesModel() {
|
~TorrentFilesModel() {
|
||||||
@ -231,14 +270,46 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int columnCount(const QModelIndex &parent) const {
|
std::vector<int> getFilesPriorities(unsigned int nbFiles) const {
|
||||||
|
std::vector<int> prio;
|
||||||
|
for(unsigned int i=0; i<nbFiles; ++i) {
|
||||||
|
prio.push_back(files_index[i]->getPriority());
|
||||||
|
}
|
||||||
|
return prio;
|
||||||
|
}
|
||||||
|
|
||||||
|
int columnCount(const QModelIndex &parent=QModelIndex()) const {
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
|
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
|
||||||
else
|
else
|
||||||
return rootItem->columnCount();
|
return rootItem->columnCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const {
|
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) {
|
||||||
|
if(!index.isValid()) return false;
|
||||||
|
if (role != Qt::EditRole) return false;
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
switch(index.column()) {
|
||||||
|
case 0:
|
||||||
|
item->setName(value.toString());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
item->setSize(value.toULongLong());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
item->setProgress(value.toDouble());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
item->setPriority(value.toInt());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
@ -258,7 +329,7 @@ public:
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const {
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
@ -268,9 +339,9 @@ public:
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent) const {
|
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const {
|
||||||
if (!hasIndex(row, column, parent))
|
if (parent.isValid() && parent.column() != 0)
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
TreeItem *parentItem;
|
TreeItem *parentItem;
|
||||||
|
|
||||||
@ -299,8 +370,9 @@ public:
|
|||||||
return createIndex(parentItem->row(), 0, parentItem);
|
return createIndex(parentItem->row(), 0, parentItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const {
|
int rowCount(const QModelIndex &parent=QModelIndex()) const {
|
||||||
TreeItem *parentItem;
|
TreeItem *parentItem;
|
||||||
|
|
||||||
if (parent.column() > 0)
|
if (parent.column() > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -312,24 +384,44 @@ public:
|
|||||||
return parentItem->childCount();
|
return parentItem->childCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void clear() {
|
||||||
void setupModelData(torrent_info const& t, TreeItem *parent) {
|
qDebug("clear called");
|
||||||
if(t.num_files() == 0) return;
|
if(files_index) {
|
||||||
|
delete [] files_index;
|
||||||
|
files_index = 0;
|
||||||
|
}
|
||||||
|
rootItem->deleteAllChildren();
|
||||||
|
Q_ASSERT(rootItem->children().empty());
|
||||||
|
reset();
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupModelData(torrent_info const& t) {
|
||||||
|
qDebug("setup model data called");
|
||||||
|
if(t.num_files() == 0) return;
|
||||||
|
// Initialize files_index array
|
||||||
|
files_index = new TreeItem*[t.num_files()];
|
||||||
|
|
||||||
|
TreeItem *parent = this->rootItem;
|
||||||
if(t.num_files() ==1) {
|
if(t.num_files() ==1) {
|
||||||
TreeItem *f = new TreeItem(t.file_at(0), parent);
|
TreeItem *f = new TreeItem(t.file_at(0), parent);
|
||||||
parent->appendChild(f);
|
parent->appendChild(f);
|
||||||
files_index[0] = f;
|
files_index[0] = f;
|
||||||
|
qDebug("setup model data completed (before signal)");
|
||||||
|
emit layoutChanged();
|
||||||
|
qDebug("setup model data completed (after signal)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Create parent folder
|
// Create parent folder
|
||||||
TreeItem *current_parent = new TreeItem(misc::toQString(t.name()), parent);
|
TreeItem *current_parent = new TreeItem(misc::toQString(t.name()), parent);
|
||||||
parent->appendChild(current_parent);
|
parent->appendChild(current_parent);
|
||||||
|
TreeItem *root_folder = current_parent;
|
||||||
|
|
||||||
// Iterate over files
|
// Iterate over files
|
||||||
int i = 0;
|
int i = 0;
|
||||||
torrent_info::file_iterator fi = t.begin_files();
|
torrent_info::file_iterator fi = t.begin_files();
|
||||||
while(fi != t.end_files()) {
|
while(fi != t.end_files()) {
|
||||||
|
current_parent = root_folder;
|
||||||
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
|
||||||
// Iterate of parts of the path to create necessary folders
|
// Iterate of parts of the path to create necessary folders
|
||||||
QStringList pathFolders = path.split('/');
|
QStringList pathFolders = path.split('/');
|
||||||
@ -338,8 +430,11 @@ private:
|
|||||||
QString currentFolderName = pathFolders.takeFirst();
|
QString currentFolderName = pathFolders.takeFirst();
|
||||||
Q_ASSERT(currentFolderName == current_parent->getName());
|
Q_ASSERT(currentFolderName == current_parent->getName());
|
||||||
foreach(const QString &pathPart, pathFolders) {
|
foreach(const QString &pathPart, pathFolders) {
|
||||||
TreeItem *new_parent = new TreeItem(pathPart, current_parent);
|
TreeItem *new_parent = current_parent->childWithName(pathPart);
|
||||||
current_parent->appendChild(new_parent);
|
if(!new_parent) {
|
||||||
|
new_parent = new TreeItem(pathPart, current_parent);
|
||||||
|
current_parent->appendChild(new_parent);
|
||||||
|
}
|
||||||
current_parent = new_parent;
|
current_parent = new_parent;
|
||||||
}
|
}
|
||||||
// Actually create the file
|
// Actually create the file
|
||||||
@ -349,6 +444,7 @@ private:
|
|||||||
fi++;
|
fi++;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
emit layoutChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user