From ea2f5df95fd091257d1ff8eb878d63df359e7574 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Wed, 11 Nov 2009 14:06:07 +0000 Subject: [PATCH] - Completed port to TorrentFilesModel. Got rid or old arborescense.h --- src/TorrentFilesModel.h | 5 + src/arborescence.h | 287 ---------------------------------------- src/src.pro | 1 - src/torrentAddition.h | 196 +++------------------------ 4 files changed, 20 insertions(+), 469 deletions(-) delete mode 100644 src/arborescence.h diff --git a/src/TorrentFilesModel.h b/src/TorrentFilesModel.h index decd6dddb..3809232a6 100644 --- a/src/TorrentFilesModel.h +++ b/src/TorrentFilesModel.h @@ -273,6 +273,11 @@ public: return prio; } + bool allFiltered() const { + if(!rootItem->childCount()) return true; + return (rootItem->child(0)->getPriority() == IGNORED); + } + int columnCount(const QModelIndex &parent=QModelIndex()) const { if (parent.isValid()) return static_cast(parent.internalPointer())->columnCount(); diff --git a/src/arborescence.h b/src/arborescence.h deleted file mode 100644 index bad1919a9..000000000 --- a/src/arborescence.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Bittorrent Client using Qt4 and libtorrent. - * Copyright (C) 2006 Christophe Dumez - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * In addition, as a special exception, the copyright holders give permission to - * link this program with the OpenSSL project's "OpenSSL" library (or with - * modified versions of it that use the same license as the "OpenSSL" library), - * and distribute the linked executables. You must obey the GNU General Public - * License in all respects for all of the code used other than "OpenSSL". If you - * modify file(s), you may extend this exception to your version of the file(s), - * but you are not obligated to do so. If you do not wish to do so, delete this - * exception statement from your version. - * - * Contact : chris@qbittorrent.org - */ - -#ifndef ARBORESCENCE_H -#define ARBORESCENCE_H - -#include -#include -#include -#include "misc.h" - -class torrent_file { -private: - torrent_file *parent; - bool is_dir; - QString rel_path; - QList children; - size_type size; - float progress; - int priority; - int index; // Index in torrent_info - -public: - torrent_file(torrent_file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){ - qDebug("created a file with index %d", index); - rel_path = QDir::cleanPath(path); - Q_ASSERT(progress >= 0.); - Q_ASSERT(progress <= 1.); - if(parent) { - parent->updateProgress(); - parent->updatePriority(priority); - } - } - - ~torrent_file() { - qDeleteAll(children); - } - - void updateProgress(std::vector fp) { - progress = fp[index]/size; - Q_ASSERT(progress >= 0.); - Q_ASSERT(progress <= 1.); - // Update children - foreach(torrent_file* child, children) { - child->updateProgress(fp); - } - if(parent) { - parent->updateProgress(); - } - } - - QString path() const { - return rel_path; - } - - QString name() const { - return rel_path.split(QDir::separator()).last(); - } - - void updateProgress() { - Q_ASSERT(is_dir); - if(children.isEmpty()) { - progress = 0.; - return; - } - double wanted = 0.; - double done = 0.; - foreach(const torrent_file *child, children) { - wanted += child->getSize(); - done += child->getSize()*child->getProgress(); - } - progress = done / wanted; - Q_ASSERT(progress >= 0.); - Q_ASSERT(progress <= 1.); - } - - void updatePriority(int prio) { - Q_ASSERT(is_dir); - foreach(torrent_file *child, children) { - if(child->getPriority() != prio) return; - } - priority = prio; - } - - int getPriority() const { - return priority; - } - - size_type getSize() const { - return size; - } - - float getProgress() const { - return progress; - } - - int getIndex() const { - return index; - } - - bool isDir() const { - return is_dir; - } - - bool hasChildren() const { - return (!children.isEmpty()); - } - - QList getChildren() const { - return children; - } - - torrent_file* getChild(QString fileName) const { - Q_ASSERT(is_dir); - foreach(torrent_file *f, children) { - if(f->name() == fileName) return f; - } - return 0; - } - - void addBytes(size_type b) { - size += b; - if(parent) - parent->addBytes(b); - } - - torrent_file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) { - Q_ASSERT(is_dir); - qDebug("Adding a new child of size: %ld", (long)size); - torrent_file *f = new torrent_file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority); - children << f; - if(size) { - addBytes(size); - } - return f; - } - - bool removeFromFS(QString saveDir) const { - QString full_path = saveDir + QDir::separator() + rel_path; - if(!QFile::exists(full_path)) { - qDebug("%s does not exist, no need to remove it", full_path.toLocal8Bit().data()); - return true; - } - bool success = true; - qDebug("We have %d children", children.size()); - foreach(const torrent_file *f, children) { - bool s = f->removeFromFS(saveDir); - success = s && success; - } - if(is_dir) { - qDebug("trying to remove directory: %s", full_path.toLocal8Bit().data()); - QDir dir(full_path); - dir.rmdir(full_path); - } else { - qDebug("trying to remove file: %s", full_path.toLocal8Bit().data()); - bool s = QFile::remove(full_path); - success = s && success; - } - return success; - } -}; - -class arborescence { -private: - torrent_file *root; - -public: - arborescence(boost::intrusive_ptr t) { - torrent_info::file_iterator fi = t->begin_files(); - if(t->num_files() > 1) { - root = new torrent_file(0, misc::toQString(t->name()), true); - } else { - // XXX: Will crash if there is no file in torrent - root = new torrent_file(0, misc::toQString(t->name()), false, fi->size, 0); - return; - } - int i = 0; - while(fi != t->end_files()) { - QString path = QDir::cleanPath(misc::toQString(fi->path.string())); - addFile(path, fi->size, i); - fi++; - ++i; - } - qDebug("real size: %ld, tree size: %ld", (long)t->total_size(), (long)root->getSize()); - Q_ASSERT(root->getSize() == t->total_size()); - } - - arborescence(torrent_info const& t, std::vector fp, std::vector files_priority) { - torrent_info::file_iterator fi = t.begin_files(); - if(t.num_files() > 1) { - qDebug("More than one file in the torrent, setting a folder as root"); - root = new torrent_file(0, misc::toQString(t.name()), true); - } else { - // XXX: Will crash if there is no file in torrent - qDebug("one file in the torrent, setting it as root with index 0"); - root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, ((double)fp[0])/t.file_at(0).size, files_priority.at(0)); - return; - } - int i = 0; - while(fi != t.end_files()) { - QString path = QDir::cleanPath(misc::toQString(fi->path.string())); - addFile(path, fi->size, i, ((double)fp[i])/t.file_at(i).size, files_priority.at(i)); - fi++; - ++i; - } - qDebug("real size: %ld, tree size: %ld", (long)t.total_size(), (long)root->getSize()); - Q_ASSERT(root->getSize() == t.total_size()); - } - - ~arborescence() { - delete root; - } - - void updateFileProgress(std::vector fp) { - root->updateProgress(fp); - } - - torrent_file* getRoot() const { - return root; - } - - bool removeFromFS(QString saveDir) { - if(!QFile::exists(saveDir+QDir::separator()+root->path())) return true; - bool success = root->removeFromFS(saveDir); - QDir root_dir(root->path()); - root_dir.rmdir(saveDir+QDir::separator()+root->path()); - return success; - } - -protected: - void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) { - Q_ASSERT(root->isDir()); - path = QDir::cleanPath(path); - //Q_ASSERT(path.startsWith(root->path())); - QString relative_path = path.remove(0, root->path().size()); - if(relative_path.at(0) ==QDir::separator()) - relative_path.remove(0, 1); - QStringList fileNames = relative_path.split(QDir::separator()); - torrent_file *dad = root; - unsigned int nb_i = 0; - unsigned int size = fileNames.size(); - foreach(const QString &fileName, fileNames) { - ++nb_i; - if(fileName == ".") continue; - const torrent_file* child = dad->getChild(fileName); - if(!child) { - if(nb_i != size) { - // Folder - child = dad->addChild(fileName, true); - } else { - // File - child = dad->addChild(fileName, false, file_size, index, progress, priority); - } - } - dad = (torrent_file*)child; - } - } -}; - -#endif diff --git a/src/src.pro b/src/src.pro index 28fe0b7ef..e2ef4066d 100644 --- a/src/src.pro +++ b/src/src.pro @@ -160,7 +160,6 @@ HEADERS += GUI.h \ qtorrenthandle.h \ engineSelectDlg.h \ pluginSource.h \ - arborescence.h \ qgnomelook.h \ realprogressbar.h \ realprogressbarthread.h \ diff --git a/src/torrentAddition.h b/src/torrentAddition.h index 00bde2d13..addbb9ada 100644 --- a/src/torrentAddition.h +++ b/src/torrentAddition.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -47,8 +46,8 @@ #include "misc.h" #include "PropListDelegate.h" #include "ui_addTorrentDialog.h" -#include "arborescence.h" #include "torrentPersistentData.h" +#include "TorrentFilesModel.h" using namespace libtorrent; @@ -61,7 +60,7 @@ private: QString hash; QString filePath; QString from_url; - QStandardItemModel *PropListModel; + TorrentFilesModel *PropListModel; PropListDelegate *PropDelegate; unsigned int nbFiles; boost::intrusive_ptr t; @@ -72,11 +71,7 @@ public: setAttribute(Qt::WA_DeleteOnClose); BTSession = _BTSession; // Set Properties list model - PropListModel = new QStandardItemModel(0,5); - PropListModel->setHeaderData(NAME, Qt::Horizontal, tr("File name")); - PropListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size")); - PropListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress")); - PropListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority")); + PropListModel = new TorrentFilesModel(); torrentContentList->setModel(PropListModel); torrentContentList->hideColumn(PROGRESS); torrentContentList->hideColumn(INDEX); @@ -90,7 +85,7 @@ public: connect(actionMaximum, SIGNAL(triggered()), this, SLOT(maximumSelection())); connect(collapseAllButton, SIGNAL(clicked()), torrentContentList, SLOT(collapseAll())); connect(expandAllButton, SIGNAL(clicked()), torrentContentList, SLOT(expandAll())); - + // FIXME: Remember columns width torrentContentList->header()->resizeSection(0, 200); //torrentContentList->header()->setResizeMode(0, QHeaderView::Stretch); QString home = QDir::homePath(); @@ -144,151 +139,28 @@ public: } fileNameLbl->setText(QString::fromUtf8("
")+newFileName+QString::fromUtf8("
")); // List files in torrent - arborescence *arb = new arborescence(t); - addFilesToTree(arb->getRoot(), PropListModel->invisibleRootItem()); - delete arb; - connect(PropListModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updatePriorities(QStandardItem*))); + PropListModel->setupModelData(*t); + // Expand first item if possible + torrentContentList->expand(PropListModel->index(0, 0)); + connect(PropDelegate, SIGNAL(filteredFilesChanged()), this, SLOT(updateDiskSpaceLabels())); //torrentContentList->expandAll(); connect(savePathTxt, SIGNAL(textChanged(QString)), this, SLOT(updateDiskSpaceLabels())); updateDiskSpaceLabels(); show(); } - void addFilesToTree(const torrent_file *root, QStandardItem *parent) { - QList child; - // Name - QStandardItem *first; - if(root->isDir()) { - first = new QStandardItem(QIcon(":/Icons/oxygen/folder.png"), root->name()); - } else { - first = new QStandardItem(QIcon(":/Icons/oxygen/file.png"), root->name()); - } - child << first; - // Size - child << new QStandardItem(misc::toQString(root->getSize())); - // Hidden progress - child << new QStandardItem(""); - // Prio - child << new QStandardItem(misc::toQString(NORMAL)); - // INDEX - child << new QStandardItem(misc::toQString(root->getIndex())); - - // Add the child to the tree - parent->appendRow(child); - - // set row Color - setItemColor(first->index(), "green"); - // Add children - QList children = root->getChildren(); - foreach(torrent_file *child, children) { - addFilesToTree(child, first); - } - } - public slots: - // priority is the new priority of given item - void updateParentsPriority(QStandardItem *item, int priority) { - QStandardItem *parent = item->parent(); - if(!parent) return; - // Check if children have different priorities - // then folder must have NORMAL priority - unsigned int rowCount = parent->rowCount(); - for(unsigned int i=0; ichild(i, PRIORITY)->text().toInt() != priority) { - QStandardItem *grandFather = parent->parent(); - if(!grandFather) { - grandFather = PropListModel->invisibleRootItem(); - } - QStandardItem *parentPrio = grandFather->child(parent->row(), PRIORITY); - if(parentPrio->text().toInt() != NORMAL) { - parentPrio->setText(misc::toQString(NORMAL)); - setItemColor(parentPrio->index(), "green"); - // Recursively update ancesters of this parent too - updateParentsPriority(grandFather->child(parent->row()), priority); - } - return; - } - } - // All the children have the same priority - // Parent folder should have the same priority too - QStandardItem *grandFather = parent->parent(); - if(!grandFather) { - grandFather = PropListModel->invisibleRootItem(); - } - QStandardItem *parentPrio = grandFather->child(parent->row(), PRIORITY); - if(parentPrio->text().toInt() != priority) { - parentPrio->setText(misc::toQString(priority)); - if(priority == IGNORED) - setItemColor(parentPrio->index(), "red"); - else - setItemColor(parentPrio->index(), "green"); - // Recursively update ancesters of this parent too - updateParentsPriority(grandFather->child(parent->row()), priority); - } - } - - void updateChildrenPriority(QStandardItem *item, int priority) { - QStandardItem *parent = item->parent(); - if(!parent) { - parent = PropListModel->invisibleRootItem(); - } - parent = parent->child(item->row()); - unsigned int rowCount = parent->rowCount(); - for(unsigned int i=0; ichild(i, PRIORITY); - if(childPrio->text().toInt() != priority) { - childPrio->setText(misc::toQString(priority)); - if(priority == IGNORED) - setItemColor(childPrio->index(), "red"); - else - setItemColor(childPrio->index(), "green"); - // recursively update children of this child too - updateChildrenPriority(parent->child(i), priority); - } - } - } - - void updatePriorities(QStandardItem *item) { - qDebug("Priority changed"); - // First we disable the signal/slot on item edition - // temporarily so that it doesn't mess with our manual updates - disconnect(PropListModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updatePriorities(QStandardItem*))); - QStandardItem *parent = item->parent(); - if(!parent) { - parent = PropListModel->invisibleRootItem(); - } - int priority = parent->child(item->row(), PRIORITY)->text().toInt(); - if(priority == IGNORED) - setItemColor(item->index(), "red"); - else - setItemColor(item->index(), "green"); - // Update parents priorities - updateParentsPriority(item, priority); - // If this is not a directory, then there are - // no children to update - if(parent->child(item->row(), INDEX)->text().toInt() == -1) { - // Updating children - qDebug("Priority changed for a folder to %d", priority); - updateChildrenPriority(item, priority); - } - // Reconnect the signal/slot on item edition so that we - // get future updates - connect(PropListModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updatePriorities(QStandardItem*))); - // Update disk space labels - updateDiskSpaceLabels(); - } - void updateDiskSpaceLabels() { long long available = misc::freeDiskSpaceOnPath(savePathTxt->text()); lbl_disk_space->setText(misc::friendlyUnit(available)); // Determine torrent size unsigned long long torrent_size = 0; - int nbFiles = t->num_files(); - int *priorities = new int[nbFiles]; - getPriorities(PropListModel->invisibleRootItem(), priorities); - for(int i=0; inum_files(); + std::vector priorities = PropListModel->getFilesPriorities(nbFiles); + + for(unsigned int i=0; i 0) torrent_size += t->file_at(i).size; } @@ -325,20 +197,8 @@ public slots: close(); } - // Set the color of a row in data model - void setItemColor(QModelIndex index, QString color){ - for(int i=0; icolumnCount(); ++i){ - PropListModel->setData(index.sibling(index.row(), i), QVariant(QColor(color)), Qt::ForegroundRole); - } - } - bool allFiltered() const { - unsigned int nbRows = PropListModel->rowCount(); - for(unsigned int i=0; idata(PropListModel->index(i, PRIORITY)).toInt() != IGNORED) - return false; - } - return true; + return PropListModel->allFiltered(); } void displayFilesListMenu(const QPoint&){ @@ -361,7 +221,6 @@ public slots: foreach(const QModelIndex &index, selectedIndexes){ if(index.column() == PRIORITY){ PropListModel->setData(index, QVariant(IGNORED)); - setItemColor(index, "red"); } } } @@ -371,7 +230,6 @@ public slots: foreach(const QModelIndex &index, selectedIndexes){ if(index.column() == PRIORITY){ PropListModel->setData(index, QVariant(NORMAL)); - setItemColor(index, "green"); } } } @@ -381,7 +239,6 @@ public slots: foreach(const QModelIndex &index, selectedIndexes){ if(index.column() == PRIORITY){ PropListModel->setData(index, QVariant(HIGH)); - setItemColor(index, "green"); } } } @@ -391,37 +248,14 @@ public slots: foreach(const QModelIndex &index, selectedIndexes){ if(index.column() == PRIORITY){ PropListModel->setData(index, QVariant(MAXIMUM)); - setItemColor(index, "green"); - } - } - } - - void getPriorities(QStandardItem *parent, int *priorities) { - unsigned int nbRows = parent->rowCount(); - for(unsigned int i=0; ichild(i, INDEX); - int index = item->text().toInt(); - if(index < 0) { - qDebug("getPriorities(), found a folder, checking its children"); - getPriorities(parent->child(i), priorities); - } else { - item = parent->child(i, PRIORITY); - qDebug("getPriorities(), found priority %d for file at index %d", item->text().toInt(), index); - priorities[index] = item->text().toInt(); } } } void savePiecesPriorities(){ qDebug("Saving pieces priorities"); - int *priorities = new int[nbFiles]; - getPriorities(PropListModel->invisibleRootItem(), priorities); - std::vector vect_prio; - for(unsigned int i=0; i priorities = PropListModel->getFilesPriorities(t->num_files()); + TorrentTempData::setFilesPriority(hash, priorities); } void on_OkButton_clicked(){