Browse Source

- Fixed a lot of bugs in the new TorrentFilesModel

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
2e2e506162
  1. 144
      src/TorrentFilesModel.h

144
src/TorrentFilesModel.h

@ -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);
}
void deleteAllChildren() {
Q_ASSERT(type==ROOT);
qDeleteAll(childItems); 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(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; 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…
Cancel
Save