From 658d876ff7baa2b1693014bec46ae5a7650f3b7c Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sun, 31 Oct 2010 16:05:59 +0000 Subject: [PATCH] Fix and improve file priorities editing --- src/properties/propertieswidget.cpp | 2 +- src/properties/proplistdelegate.h | 7 +- src/qtlibtorrent/qtorrenthandle.cpp | 1 + src/torrentfilesmodel.h | 106 ++++++++++++++++------------ src/torrentpersistentdata.h | 1 + 5 files changed, 69 insertions(+), 48 deletions(-) diff --git a/src/properties/propertieswidget.cpp b/src/properties/propertieswidget.cpp index 935203b9c..c77f78846 100644 --- a/src/properties/propertieswidget.cpp +++ b/src/properties/propertieswidget.cpp @@ -676,7 +676,7 @@ void PropertiesWidget::renameSelectedFile() { } bool PropertiesWidget::applyPriorities() { - qDebug("Saving pieces priorities"); + qDebug("Saving files priorities"); const std::vector priorities = PropListModel->getFilesPriorities(h.get_torrent_info().num_files()); bool first_last_piece_first = false; // Save first/last piece first option state diff --git a/src/properties/proplistdelegate.h b/src/properties/proplistdelegate.h index b919f586e..5cc3d232c 100644 --- a/src/properties/proplistdelegate.h +++ b/src/properties/proplistdelegate.h @@ -96,6 +96,9 @@ public: QItemDelegate::drawBackground(painter, opt, index); QString text = ""; switch(index.data().toInt()) { + case -1: + text = tr("Mixed", "Mixed (priorities"); + break; case 0: text = tr("Not downloaded"); break; @@ -151,8 +154,8 @@ public: QTorrentHandle h = properties->getCurrentTorrent(); if(!h.is_valid() || static_cast(h).is_seed() || !h.has_metadata()) return 0; } - if(index.data().toInt() == 0) { - // IGNORED + if(index.data().toInt() <= 0) { + // IGNORED or MIXED return 0; } QComboBox* editor = new QComboBox(parent); diff --git a/src/qtlibtorrent/qtorrenthandle.cpp b/src/qtlibtorrent/qtorrenthandle.cpp index 660ba9e82..1d15a5c56 100644 --- a/src/qtlibtorrent/qtorrenthandle.cpp +++ b/src/qtlibtorrent/qtorrenthandle.cpp @@ -474,6 +474,7 @@ void QTorrentHandle::add_url_seed(QString seed) { void QTorrentHandle::prioritize_files(const std::vector &v) { // Does not do anything for seeding torrents Q_ASSERT(torrent_handle::is_valid()); + Q_ASSERT(v.size() == (unsigned int)torrent_handle::get_torrent_info().num_files()); if(v.size() != (unsigned int)torrent_handle::get_torrent_info().num_files()) return; bool was_seed = is_seed(); diff --git a/src/torrentfilesmodel.h b/src/torrentfilesmodel.h index fcd596208..f40a5ba64 100644 --- a/src/torrentfilesmodel.h +++ b/src/torrentfilesmodel.h @@ -42,11 +42,12 @@ #include "misc.h" using namespace libtorrent; -enum FilePriority {IGNORED=0, NORMAL=1, HIGH=2, MAXIMUM=7}; +enum FilePriority {IGNORED=0, NORMAL=1, HIGH=2, MAXIMUM=7, PARTIAL=-1}; enum TreeItemType {TFILE, FOLDER, ROOT}; class TreeItem { -private: + +public: enum TreeItemColumns {COL_NAME, COL_SIZE, COL_PROGRESS, COL_PRIO}; private: @@ -127,27 +128,27 @@ public: Q_ASSERT(childItems.empty()); } - const QList& children() const { + QList children() const { return childItems; } QString getName() const { //Q_ASSERT(type != ROOT); - return itemData.first().toString(); + return itemData.at(COL_NAME).toString(); } void setName(QString name) { Q_ASSERT(type != ROOT); - itemData.replace(0, name); + itemData.replace(COL_NAME, name); } qulonglong getSize() const { - return itemData.value(1).toULongLong(); + return itemData.value(COL_SIZE).toULongLong(); } void setSize(qulonglong size) { if(getSize() == size) return; - itemData.replace(1, (qulonglong)size); + itemData.replace(COL_SIZE, (qulonglong)size); if(parentItem) parentItem->updateSize(); } @@ -157,7 +158,7 @@ public: Q_ASSERT(type == FOLDER); qulonglong size = 0; foreach(TreeItem* child, childItems) { - if(child->getPriority() > 0) + if(child->getPriority() != IGNORED) size += child->getSize(); } setSize(size); @@ -173,7 +174,7 @@ public: else progress = 1.; Q_ASSERT(progress >= 0. && progress <= 1.); - itemData.replace(2, progress); + itemData.replace(COL_PROGRESS, progress); if(parentItem) parentItem->updateProgress(); } @@ -203,50 +204,58 @@ public: } int getPriority() const { - return itemData.value(3).toInt(); + return itemData.value(COL_PRIO).toInt(); } - void setPriority(int new_prio, bool update_children=true, bool update_parent=true) { - int old_prio = getPriority(); - if(old_prio != new_prio) { - qDebug("setPriority(%s, %d)", qPrintable(getName()), new_prio); - itemData.replace(3, new_prio); - // Update parent - if(update_parent && parentItem) { - parentItem->updateSize(); - parentItem->updateProgress(); - parentItem->updatePriority(); - } + void setPriority(int new_prio, bool update_parent=true) { + Q_ASSERT(new_prio != PARTIAL || type == FOLDER); // PARTIAL only applies to folders + const int old_prio = getPriority(); + if(old_prio == new_prio) return; + qDebug("setPriority(%s, %d)", qPrintable(getName()), new_prio); + itemData.replace(COL_PRIO, new_prio); + + // Update parent + if(update_parent && parentItem) { + qDebug("Updating parent item"); + parentItem->updateSize(); + parentItem->updateProgress(); + parentItem->updatePriority(); } + // Update children - if(update_children) { + if(new_prio != PARTIAL && !childItems.empty()) { + qDebug("Updating children items"); foreach(TreeItem* child, childItems) { - child->setPriority(new_prio, true, false); + // Do not update the parent since + // the parent is causing the update + child->setPriority(new_prio, false); } } - if(type==FOLDER) { + if(type == FOLDER) { updateSize(); updateProgress(); } } + // Only non-root folders use this function void updatePriority() { if(type == ROOT) return; Q_ASSERT(type == FOLDER); - int priority = getPriority(); - bool first = true; - foreach(TreeItem* child, childItems) { - if(first) { - priority = child->getPriority(); - first = false; - } else { - if(child->getPriority() != priority) { - setPriority(NORMAL, false); - return; - } + if(childItems.isEmpty()) return; + // If all children have the same priority + // then the folder should have the same + // priority + const int prio = childItems.first()->getPriority(); + for(int i=1; igetPriority() != prio) { + setPriority(PARTIAL); + return; } } - setPriority(priority); + // All child items have the same priorrity + // Update mine if necessary + if(prio != getPriority()) + setPriority(prio); } TreeItem* childWithName(QString name) const { @@ -366,13 +375,16 @@ public: bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) { if(!index.isValid()) return false; - if (role == Qt::CheckStateRole) { + if (index.column() == 0 && role == Qt::CheckStateRole) { TreeItem *item = static_cast(index.internalPointer()); + qDebug("setData(%s, %d", qPrintable(item->getName()), value.toInt()); if(item->getPriority() != value.toInt()) { - if(value.toInt() == Qt::Checked) - item->setPriority(NORMAL); - else + if(value.toInt() == Qt::PartiallyChecked) + item->setPriority(PARTIAL); + else if (value.toInt() == Qt::Unchecked) item->setPriority(IGNORED); + else + item->setPriority(NORMAL); emit filteredFilesChanged(); emit dataChanged(this->index(0,0), this->index(rowCount(), 0)); } @@ -402,8 +414,8 @@ public: return false; } - TreeItemType getType(const QModelIndex &index) { - TreeItem *item = static_cast(index.internalPointer()); + TreeItemType getType(const QModelIndex &index) const { + const TreeItem *item = static_cast(index.internalPointer()); return item->getType(); } @@ -422,9 +434,11 @@ public: else return QIcon(":/Icons/oxygen/file.png"); } - if(role == Qt::CheckStateRole) { - if(item->data(3).toInt() == IGNORED) + if(index.column() == 0 && role == Qt::CheckStateRole) { + if(item->data(TreeItem::COL_PRIO).toInt() == IGNORED) return Qt::Unchecked; + if(item->data(TreeItem::COL_PRIO).toInt() == PARTIAL) + return Qt::PartiallyChecked; return Qt::Checked; } if (role != Qt::DisplayRole) @@ -436,7 +450,8 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const { if (!index.isValid()) return 0; - + if(getType(index) == FOLDER) + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; } @@ -508,6 +523,7 @@ public: qDebug("setup model data called"); if(t.num_files() == 0) return; // Initialize files_index array + qDebug("Torrent contains %d files", t.num_files()); files_index = new TreeItem*[t.num_files()]; TreeItem *parent = this->rootItem; diff --git a/src/torrentpersistentdata.h b/src/torrentpersistentdata.h index eb5b6a2d4..d90a4af77 100644 --- a/src/torrentpersistentdata.h +++ b/src/torrentpersistentdata.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include "qtorrenthandle.h"