|
|
@ -42,11 +42,12 @@ |
|
|
|
#include "misc.h" |
|
|
|
#include "misc.h" |
|
|
|
using namespace libtorrent; |
|
|
|
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}; |
|
|
|
enum TreeItemType {TFILE, FOLDER, ROOT}; |
|
|
|
|
|
|
|
|
|
|
|
class TreeItem { |
|
|
|
class TreeItem { |
|
|
|
private: |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
enum TreeItemColumns {COL_NAME, COL_SIZE, COL_PROGRESS, COL_PRIO}; |
|
|
|
enum TreeItemColumns {COL_NAME, COL_SIZE, COL_PROGRESS, COL_PRIO}; |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
@ -127,27 +128,27 @@ public: |
|
|
|
Q_ASSERT(childItems.empty()); |
|
|
|
Q_ASSERT(childItems.empty()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const QList<TreeItem*>& children() const { |
|
|
|
QList<TreeItem*> children() const { |
|
|
|
return childItems; |
|
|
|
return childItems; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QString getName() const { |
|
|
|
QString getName() const { |
|
|
|
//Q_ASSERT(type != ROOT);
|
|
|
|
//Q_ASSERT(type != ROOT);
|
|
|
|
return itemData.first().toString(); |
|
|
|
return itemData.at(COL_NAME).toString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void setName(QString name) { |
|
|
|
void setName(QString name) { |
|
|
|
Q_ASSERT(type != ROOT); |
|
|
|
Q_ASSERT(type != ROOT); |
|
|
|
itemData.replace(0, name); |
|
|
|
itemData.replace(COL_NAME, name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qulonglong getSize() const { |
|
|
|
qulonglong getSize() const { |
|
|
|
return itemData.value(1).toULongLong(); |
|
|
|
return itemData.value(COL_SIZE).toULongLong(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void setSize(qulonglong size) { |
|
|
|
void setSize(qulonglong size) { |
|
|
|
if(getSize() == size) return; |
|
|
|
if(getSize() == size) return; |
|
|
|
itemData.replace(1, (qulonglong)size); |
|
|
|
itemData.replace(COL_SIZE, (qulonglong)size); |
|
|
|
if(parentItem) |
|
|
|
if(parentItem) |
|
|
|
parentItem->updateSize(); |
|
|
|
parentItem->updateSize(); |
|
|
|
} |
|
|
|
} |
|
|
@ -157,7 +158,7 @@ public: |
|
|
|
Q_ASSERT(type == FOLDER); |
|
|
|
Q_ASSERT(type == FOLDER); |
|
|
|
qulonglong size = 0; |
|
|
|
qulonglong size = 0; |
|
|
|
foreach(TreeItem* child, childItems) { |
|
|
|
foreach(TreeItem* child, childItems) { |
|
|
|
if(child->getPriority() > 0) |
|
|
|
if(child->getPriority() != IGNORED) |
|
|
|
size += child->getSize(); |
|
|
|
size += child->getSize(); |
|
|
|
} |
|
|
|
} |
|
|
|
setSize(size); |
|
|
|
setSize(size); |
|
|
@ -173,7 +174,7 @@ public: |
|
|
|
else |
|
|
|
else |
|
|
|
progress = 1.; |
|
|
|
progress = 1.; |
|
|
|
Q_ASSERT(progress >= 0. && progress <= 1.); |
|
|
|
Q_ASSERT(progress >= 0. && progress <= 1.); |
|
|
|
itemData.replace(2, progress); |
|
|
|
itemData.replace(COL_PROGRESS, progress); |
|
|
|
if(parentItem) |
|
|
|
if(parentItem) |
|
|
|
parentItem->updateProgress(); |
|
|
|
parentItem->updateProgress(); |
|
|
|
} |
|
|
|
} |
|
|
@ -203,25 +204,31 @@ public: |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int getPriority() const { |
|
|
|
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) { |
|
|
|
void setPriority(int new_prio, bool update_parent=true) { |
|
|
|
int old_prio = getPriority(); |
|
|
|
Q_ASSERT(new_prio != PARTIAL || type == FOLDER); // PARTIAL only applies to folders
|
|
|
|
if(old_prio != new_prio) { |
|
|
|
const int old_prio = getPriority(); |
|
|
|
|
|
|
|
if(old_prio == new_prio) return; |
|
|
|
qDebug("setPriority(%s, %d)", qPrintable(getName()), new_prio); |
|
|
|
qDebug("setPriority(%s, %d)", qPrintable(getName()), new_prio); |
|
|
|
itemData.replace(3, new_prio); |
|
|
|
itemData.replace(COL_PRIO, new_prio); |
|
|
|
|
|
|
|
|
|
|
|
// Update parent
|
|
|
|
// Update parent
|
|
|
|
if(update_parent && parentItem) { |
|
|
|
if(update_parent && parentItem) { |
|
|
|
|
|
|
|
qDebug("Updating parent item"); |
|
|
|
parentItem->updateSize(); |
|
|
|
parentItem->updateSize(); |
|
|
|
parentItem->updateProgress(); |
|
|
|
parentItem->updateProgress(); |
|
|
|
parentItem->updatePriority(); |
|
|
|
parentItem->updatePriority(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Update children
|
|
|
|
// Update children
|
|
|
|
if(update_children) { |
|
|
|
if(new_prio != PARTIAL && !childItems.empty()) { |
|
|
|
|
|
|
|
qDebug("Updating children items"); |
|
|
|
foreach(TreeItem* child, childItems) { |
|
|
|
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) { |
|
|
@ -230,23 +237,25 @@ public: |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Only non-root folders use this function
|
|
|
|
void updatePriority() { |
|
|
|
void updatePriority() { |
|
|
|
if(type == ROOT) return; |
|
|
|
if(type == ROOT) return; |
|
|
|
Q_ASSERT(type == FOLDER); |
|
|
|
Q_ASSERT(type == FOLDER); |
|
|
|
int priority = getPriority(); |
|
|
|
if(childItems.isEmpty()) return; |
|
|
|
bool first = true; |
|
|
|
// If all children have the same priority
|
|
|
|
foreach(TreeItem* child, childItems) { |
|
|
|
// then the folder should have the same
|
|
|
|
if(first) { |
|
|
|
// priority
|
|
|
|
priority = child->getPriority(); |
|
|
|
const int prio = childItems.first()->getPriority(); |
|
|
|
first = false; |
|
|
|
for(int i=1; i<childItems.size(); ++i) { |
|
|
|
} else { |
|
|
|
if(childItems.at(i)->getPriority() != prio) { |
|
|
|
if(child->getPriority() != priority) { |
|
|
|
setPriority(PARTIAL); |
|
|
|
setPriority(NORMAL, false); |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// All child items have the same priorrity
|
|
|
|
setPriority(priority); |
|
|
|
// Update mine if necessary
|
|
|
|
|
|
|
|
if(prio != getPriority()) |
|
|
|
|
|
|
|
setPriority(prio); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TreeItem* childWithName(QString name) const { |
|
|
|
TreeItem* childWithName(QString name) const { |
|
|
@ -366,13 +375,16 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) { |
|
|
|
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) { |
|
|
|
if(!index.isValid()) return false; |
|
|
|
if(!index.isValid()) return false; |
|
|
|
if (role == Qt::CheckStateRole) { |
|
|
|
if (index.column() == 0 && role == Qt::CheckStateRole) { |
|
|
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); |
|
|
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); |
|
|
|
|
|
|
|
qDebug("setData(%s, %d", qPrintable(item->getName()), value.toInt()); |
|
|
|
if(item->getPriority() != value.toInt()) { |
|
|
|
if(item->getPriority() != value.toInt()) { |
|
|
|
if(value.toInt() == Qt::Checked) |
|
|
|
if(value.toInt() == Qt::PartiallyChecked) |
|
|
|
item->setPriority(NORMAL); |
|
|
|
item->setPriority(PARTIAL); |
|
|
|
else |
|
|
|
else if (value.toInt() == Qt::Unchecked) |
|
|
|
item->setPriority(IGNORED); |
|
|
|
item->setPriority(IGNORED); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
item->setPriority(NORMAL); |
|
|
|
emit filteredFilesChanged(); |
|
|
|
emit filteredFilesChanged(); |
|
|
|
emit dataChanged(this->index(0,0), this->index(rowCount(), 0)); |
|
|
|
emit dataChanged(this->index(0,0), this->index(rowCount(), 0)); |
|
|
|
} |
|
|
|
} |
|
|
@ -402,8 +414,8 @@ public: |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TreeItemType getType(const QModelIndex &index) { |
|
|
|
TreeItemType getType(const QModelIndex &index) const { |
|
|
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); |
|
|
|
const TreeItem *item = static_cast<const TreeItem*>(index.internalPointer()); |
|
|
|
return item->getType(); |
|
|
|
return item->getType(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -422,9 +434,11 @@ public: |
|
|
|
else |
|
|
|
else |
|
|
|
return QIcon(":/Icons/oxygen/file.png"); |
|
|
|
return QIcon(":/Icons/oxygen/file.png"); |
|
|
|
} |
|
|
|
} |
|
|
|
if(role == Qt::CheckStateRole) { |
|
|
|
if(index.column() == 0 && role == Qt::CheckStateRole) { |
|
|
|
if(item->data(3).toInt() == IGNORED) |
|
|
|
if(item->data(TreeItem::COL_PRIO).toInt() == IGNORED) |
|
|
|
return Qt::Unchecked; |
|
|
|
return Qt::Unchecked; |
|
|
|
|
|
|
|
if(item->data(TreeItem::COL_PRIO).toInt() == PARTIAL) |
|
|
|
|
|
|
|
return Qt::PartiallyChecked; |
|
|
|
return Qt::Checked; |
|
|
|
return Qt::Checked; |
|
|
|
} |
|
|
|
} |
|
|
|
if (role != Qt::DisplayRole) |
|
|
|
if (role != Qt::DisplayRole) |
|
|
@ -436,7 +450,8 @@ public: |
|
|
|
Qt::ItemFlags flags(const QModelIndex &index) const { |
|
|
|
Qt::ItemFlags flags(const QModelIndex &index) const { |
|
|
|
if (!index.isValid()) |
|
|
|
if (!index.isValid()) |
|
|
|
return 0; |
|
|
|
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; |
|
|
|
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -508,6 +523,7 @@ public: |
|
|
|
qDebug("setup model data called"); |
|
|
|
qDebug("setup model data called"); |
|
|
|
if(t.num_files() == 0) return; |
|
|
|
if(t.num_files() == 0) return; |
|
|
|
// Initialize files_index array
|
|
|
|
// Initialize files_index array
|
|
|
|
|
|
|
|
qDebug("Torrent contains %d files", t.num_files()); |
|
|
|
files_index = new TreeItem*[t.num_files()]; |
|
|
|
files_index = new TreeItem*[t.num_files()]; |
|
|
|
|
|
|
|
|
|
|
|
TreeItem *parent = this->rootItem; |
|
|
|
TreeItem *parent = this->rootItem; |
|
|
|