diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index 02548b1b5..103e0f9a6 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(qbt_base STATIC # headers bittorrent/addtorrentparams.h bittorrent/cachestatus.h +bittorrent/filepriority.h bittorrent/infohash.h bittorrent/magneturi.h bittorrent/peerinfo.h @@ -77,6 +78,7 @@ types.h unicodestrings.h # sources +bittorrent/filepriority.cpp bittorrent/infohash.cpp bittorrent/magneturi.cpp bittorrent/peerinfo.cpp diff --git a/src/base/base.pri b/src/base/base.pri index 7aa681937..c820af369 100644 --- a/src/base/base.pri +++ b/src/base/base.pri @@ -3,6 +3,7 @@ HEADERS += \ $$PWD/asyncfilestorage.h \ $$PWD/bittorrent/addtorrentparams.h \ $$PWD/bittorrent/cachestatus.h \ + $$PWD/bittorrent/filepriority.h \ $$PWD/bittorrent/infohash.h \ $$PWD/bittorrent/magneturi.h \ $$PWD/bittorrent/peerinfo.h \ @@ -76,6 +77,7 @@ HEADERS += \ SOURCES += \ $$PWD/asyncfilestorage.cpp \ + $$PWD/bittorrent/filepriority.cpp \ $$PWD/bittorrent/infohash.cpp \ $$PWD/bittorrent/magneturi.cpp \ $$PWD/bittorrent/peerinfo.cpp \ diff --git a/src/base/bittorrent/filepriority.cpp b/src/base/bittorrent/filepriority.cpp new file mode 100644 index 000000000..92c6f6f23 --- /dev/null +++ b/src/base/bittorrent/filepriority.cpp @@ -0,0 +1,46 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2018 Thomas Piccirello + * + * 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. + */ + +#include "filepriority.h" + +namespace BitTorrent +{ + bool isValidFilePriority(const BitTorrent::FilePriority priority) + { + switch (priority) { + case BitTorrent::FilePriority::Ignored: + case BitTorrent::FilePriority::Normal: + case BitTorrent::FilePriority::High: + case BitTorrent::FilePriority::Maximum: + case BitTorrent::FilePriority::Mixed: + return true; + default: + return false; + } + } +} diff --git a/src/base/bittorrent/filepriority.h b/src/base/bittorrent/filepriority.h new file mode 100644 index 000000000..b5e2fc3aa --- /dev/null +++ b/src/base/bittorrent/filepriority.h @@ -0,0 +1,43 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2018 Thomas Piccirello + * + * 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. + */ + +#pragma once + +namespace BitTorrent +{ + enum class FilePriority : int + { + Ignored = 0, + Normal = 1, + High = 6, + Maximum = 7, + Mixed = -1 + }; + + bool isValidFilePriority(BitTorrent::FilePriority priority); +} diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 6efebf01d..10d790f01 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1424,16 +1424,6 @@ bool TorrentHandle::saveTorrentFile(const QString &path) return false; } -void TorrentHandle::setFilePriority(int index, int priority) -{ - std::vector priorities = m_nativeHandle.file_priorities(); - - if ((priorities.size() > static_cast(index)) && (priorities[index] != priority)) { - priorities[index] = priority; - prioritizeFiles(QVector::fromStdVector(priorities)); - } -} - void TorrentHandle::handleStateUpdate(const libt::torrent_status &nativeStatus) { updateStatus(nativeStatus); diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 03540fab9..df66766e3 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -348,7 +348,6 @@ namespace BitTorrent void renameFile(int index, const QString &name); bool saveTorrentFile(const QString &path); void prioritizeFiles(const QVector &priorities); - void setFilePriority(int index, int priority); void setRatioLimit(qreal limit); void setSeedingTimeLimit(int limit); void setUploadLimit(int limit); diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 8f456fa44..132207714 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -36,6 +36,7 @@ #include #include +#include "base/bittorrent/filepriority.h" #include "base/bittorrent/magneturi.h" #include "base/bittorrent/session.h" #include "base/bittorrent/torrenthandle.h" @@ -622,18 +623,18 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) renameSelectedFile(); } else { - int prio = prio::NORMAL; + BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; if (act == m_ui->actionHigh) - prio = prio::HIGH; + prio = BitTorrent::FilePriority::High; else if (act == m_ui->actionMaximum) - prio = prio::MAXIMUM; + prio = BitTorrent::FilePriority::Maximum; else if (act == m_ui->actionNotDownloaded) - prio = prio::IGNORED; + prio = BitTorrent::FilePriority::Ignored; qDebug("Setting files priority"); for (const QModelIndex &index : selectedRows) { - qDebug("Setting priority(%d) for file at row %d", prio, index.row()); - m_contentModel->setData(m_contentModel->index(index.row(), PRIORITY, index.parent()), prio); + qDebug("Setting priority(%d) for file at row %d", static_cast(prio), index.row()); + m_contentModel->setData(m_contentModel->index(index.row(), PRIORITY, index.parent()), static_cast(prio)); } } } diff --git a/src/gui/ipsubnetwhitelistoptionsdialog.cpp b/src/gui/ipsubnetwhitelistoptionsdialog.cpp index ad0c075c7..51a7f81a2 100644 --- a/src/gui/ipsubnetwhitelistoptionsdialog.cpp +++ b/src/gui/ipsubnetwhitelistoptionsdialog.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2017 Thomas Piccirello + * Copyright (C) 2017 Thomas Piccirello * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/src/gui/ipsubnetwhitelistoptionsdialog.h b/src/gui/ipsubnetwhitelistoptionsdialog.h index 804e32214..912c25ef5 100644 --- a/src/gui/ipsubnetwhitelistoptionsdialog.h +++ b/src/gui/ipsubnetwhitelistoptionsdialog.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2017 Thomas Piccirello + * Copyright (C) 2017 Thomas Piccirello * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index f85f57e42..c0387a716 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -38,6 +38,7 @@ #include #include +#include "base/bittorrent/filepriority.h" #include "base/bittorrent/session.h" #include "base/preferences.h" #include "base/unicodestrings.h" @@ -621,18 +622,18 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &) renameSelectedFile(); } else { - int prio = prio::NORMAL; + BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; if (act == m_ui->actionHigh) - prio = prio::HIGH; + prio = BitTorrent::FilePriority::High; else if (act == m_ui->actionMaximum) - prio = prio::MAXIMUM; + prio = BitTorrent::FilePriority::Maximum; else if (act == m_ui->actionNotDownloaded) - prio = prio::IGNORED; + prio = BitTorrent::FilePriority::Ignored; qDebug("Setting files priority"); for (const QModelIndex &index : selectedRows) { - qDebug("Setting priority(%d) for file at row %d", prio, index.row()); - m_propListModel->setData(m_propListModel->index(index.row(), PRIORITY, index.parent()), prio); + qDebug("Setting priority(%d) for file at row %d", static_cast(prio), index.row()); + m_propListModel->setData(m_propListModel->index(index.row(), PRIORITY, index.parent()), static_cast(prio)); } // Save changes filteredFilesChanged(); diff --git a/src/gui/properties/proplistdelegate.cpp b/src/gui/properties/proplistdelegate.cpp index f748f6462..8549ca983 100644 --- a/src/gui/properties/proplistdelegate.cpp +++ b/src/gui/properties/proplistdelegate.cpp @@ -40,6 +40,7 @@ #include #endif +#include "base/bittorrent/filepriority.h" #include "base/unicodestrings.h" #include "base/utils/misc.h" #include "base/utils/string.h" @@ -92,7 +93,7 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti newopt.maximum = 100; newopt.minimum = 0; newopt.textVisible = true; - if (index.sibling(index.row(), PRIORITY).data().toInt() == prio::IGNORED) { + if (index.sibling(index.row(), PRIORITY).data().toInt() == static_cast(BitTorrent::FilePriority::Ignored)) { newopt.state &= ~QStyle::State_Enabled; newopt.palette = progressBarDisabledPalette(); } @@ -110,17 +111,17 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti break; case PRIORITY: { QString text = ""; - switch (index.data().toInt()) { - case prio::MIXED: + switch (static_cast(index.data().toInt())) { + case BitTorrent::FilePriority::Mixed: text = tr("Mixed", "Mixed (priorities"); break; - case prio::IGNORED: + case BitTorrent::FilePriority::Ignored: text = tr("Not downloaded"); break; - case prio::HIGH: + case BitTorrent::FilePriority::High: text = tr("High", "High (priority)"); break; - case prio::MAXIMUM: + case BitTorrent::FilePriority::Maximum: text = tr("Maximum", "Maximum (priority)"); break; default: @@ -154,14 +155,14 @@ void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) { QComboBox *combobox = static_cast(editor); // Set combobox index - switch (index.data().toInt()) { - case prio::IGNORED: + switch (static_cast(index.data().toInt())) { + case BitTorrent::FilePriority::Ignored: combobox->setCurrentIndex(0); break; - case prio::HIGH: + case BitTorrent::FilePriority::High: combobox->setCurrentIndex(2); break; - case prio::MAXIMUM: + case BitTorrent::FilePriority::Maximum: combobox->setCurrentIndex(3); break; default: @@ -180,7 +181,7 @@ QWidget *PropListDelegate::createEditor(QWidget *parent, const QStyleOptionViewI return nullptr; } - if (index.data().toInt() == prio::MIXED) + if (index.data().toInt() == static_cast(BitTorrent::FilePriority::Mixed)) return nullptr; QComboBox *editor = new QComboBox(parent); @@ -198,20 +199,20 @@ void PropListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, int value = combobox->currentIndex(); qDebug("PropListDelegate: setModelData(%d)", value); + BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; // NORMAL switch (value) { case 0: - model->setData(index, prio::IGNORED); // IGNORED + prio = BitTorrent::FilePriority::Ignored; // IGNORED break; case 2: - model->setData(index, prio::HIGH); // HIGH + prio = BitTorrent::FilePriority::High; // HIGH break; case 3: - model->setData(index, prio::MAXIMUM); // MAX + prio = BitTorrent::FilePriority::Maximum; // MAX break; - default: - model->setData(index, prio::NORMAL); // NORMAL } + model->setData(index, static_cast(prio)); emit filteredFilesChanged(); } diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index c826364dc..249af9096 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -48,6 +48,7 @@ #include #endif +#include "base/bittorrent/filepriority.h" #include "base/global.h" #include "base/utils/misc.h" #include "base/utils/fs.h" @@ -245,7 +246,7 @@ void TorrentContentModel::updateFilesPriorities(const QVector &fprio) emit layoutAboutToBeChanged(); for (int i = 0; i < fprio.size(); ++i) - m_filesIndex[i]->setPriority(fprio[i]); + m_filesIndex[i]->setPriority(static_cast(fprio[i])); emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } @@ -268,14 +269,14 @@ QVector TorrentContentModel::getFilePriorities() const QVector prio; prio.reserve(m_filesIndex.size()); for (const TorrentContentModelFile *file : asConst(m_filesIndex)) - prio.push_back(file->priority()); + prio.push_back(static_cast(file->priority())); return prio; } bool TorrentContentModel::allFiltered() const { for (const TorrentContentModelFile *fileItem : asConst(m_filesIndex)) - if (fileItem->priority() != prio::IGNORED) + if (fileItem->priority() != BitTorrent::FilePriority::Ignored) return false; return true; } @@ -296,13 +297,14 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) { TorrentContentModelItem *item = static_cast(index.internalPointer()); qDebug("setData(%s, %d", qUtf8Printable(item->name()), value.toInt()); - if (item->priority() != value.toInt()) { + if (static_cast(item->priority()) != value.toInt()) { + BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; if (value.toInt() == Qt::PartiallyChecked) - item->setPriority(prio::MIXED); + prio = BitTorrent::FilePriority::Mixed; else if (value.toInt() == Qt::Unchecked) - item->setPriority(prio::IGNORED); - else - item->setPriority(prio::NORMAL); + prio = BitTorrent::FilePriority::Ignored; + + item->setPriority(prio); // Update folders progress in the tree m_rootItem->recalculateProgress(); m_rootItem->recalculateAvailability(); @@ -320,7 +322,7 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu item->setName(value.toString()); break; case TorrentContentModelItem::COL_PRIO: - item->setPriority(value.toInt()); + item->setPriority(static_cast(value.toInt())); break; default: return false; @@ -362,9 +364,9 @@ QVariant TorrentContentModel::data(const QModelIndex &index, int role) const } if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) { - if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == prio::IGNORED) + if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::FilePriority::Ignored)) return Qt::Unchecked; - if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == prio::MIXED) + if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::FilePriority::Mixed)) return Qt::PartiallyChecked; return Qt::Checked; } @@ -499,8 +501,8 @@ void TorrentContentModel::selectAll() { for (int i = 0; i < m_rootItem->childCount(); ++i) { TorrentContentModelItem* child = m_rootItem->child(i); - if (child->priority() == prio::IGNORED) - child->setPriority(prio::NORMAL); + if (child->priority() == BitTorrent::FilePriority::Ignored) + child->setPriority(BitTorrent::FilePriority::Normal); } emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } @@ -508,6 +510,6 @@ void TorrentContentModel::selectAll() void TorrentContentModel::selectNone() { for (int i = 0; i < m_rootItem->childCount(); ++i) - m_rootItem->child(i)->setPriority(prio::IGNORED); + m_rootItem->child(i)->setPriority(BitTorrent::FilePriority::Ignored); emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } diff --git a/src/gui/torrentcontentmodelfile.cpp b/src/gui/torrentcontentmodelfile.cpp index e3fbbee57..cb6a8aa0f 100644 --- a/src/gui/torrentcontentmodelfile.cpp +++ b/src/gui/torrentcontentmodelfile.cpp @@ -52,9 +52,9 @@ int TorrentContentModelFile::fileIndex() const return m_fileIndex; } -void TorrentContentModelFile::setPriority(int newPriority, bool updateParent) +void TorrentContentModelFile::setPriority(BitTorrent::FilePriority newPriority, bool updateParent) { - Q_ASSERT(newPriority != prio::MIXED); + Q_ASSERT(newPriority != BitTorrent::FilePriority::Mixed); if (m_priority == newPriority) return; diff --git a/src/gui/torrentcontentmodelfile.h b/src/gui/torrentcontentmodelfile.h index 079f43651..00c371a5b 100644 --- a/src/gui/torrentcontentmodelfile.h +++ b/src/gui/torrentcontentmodelfile.h @@ -29,6 +29,7 @@ #ifndef TORRENTCONTENTMODELFILE_H #define TORRENTCONTENTMODELFILE_H +#include "base/bittorrent/filepriority.h" #include "torrentcontentmodelitem.h" class TorrentContentModelFile : public TorrentContentModelItem @@ -38,7 +39,7 @@ public: TorrentContentModelFolder *parent, int fileIndex); int fileIndex() const; - void setPriority(int newPriority, bool updateParent = true) override; + void setPriority(BitTorrent::FilePriority newPriority, bool updateParent = true) override; void setProgress(qreal progress); void setAvailability(qreal availability); ItemType itemType() const override; diff --git a/src/gui/torrentcontentmodelfolder.cpp b/src/gui/torrentcontentmodelfolder.cpp index 963a2fa93..8417d71e3 100644 --- a/src/gui/torrentcontentmodelfolder.cpp +++ b/src/gui/torrentcontentmodelfolder.cpp @@ -108,10 +108,10 @@ void TorrentContentModelFolder::updatePriority() // If all children have the same priority // then the folder should have the same // priority - const int prio = m_childItems.first()->priority(); + const BitTorrent::FilePriority prio = m_childItems.first()->priority(); for (int i = 1; i < m_childItems.size(); ++i) { if (m_childItems.at(i)->priority() != prio) { - setPriority(prio::MIXED); + setPriority(BitTorrent::FilePriority::Mixed); return; } } @@ -120,7 +120,7 @@ void TorrentContentModelFolder::updatePriority() setPriority(prio); } -void TorrentContentModelFolder::setPriority(int newPriority, bool updateParent) +void TorrentContentModelFolder::setPriority(BitTorrent::FilePriority newPriority, bool updateParent) { if (m_priority == newPriority) return; @@ -132,7 +132,7 @@ void TorrentContentModelFolder::setPriority(int newPriority, bool updateParent) m_parentItem->updatePriority(); // Update children - if (m_priority != prio::MIXED) + if (m_priority != BitTorrent::FilePriority::Mixed) for (TorrentContentModelItem *child : asConst(m_childItems)) child->setPriority(m_priority, false); } @@ -143,7 +143,7 @@ void TorrentContentModelFolder::recalculateProgress() qulonglong tSize = 0; qulonglong tRemaining = 0; for (TorrentContentModelItem *child : asConst(m_childItems)) { - if (child->priority() == prio::IGNORED) + if (child->priority() == BitTorrent::FilePriority::Ignored) continue; if (child->itemType() == FolderType) @@ -166,7 +166,7 @@ void TorrentContentModelFolder::recalculateAvailability() qulonglong tSize = 0; bool foundAnyData = false; for (TorrentContentModelItem *child : asConst(m_childItems)) { - if (child->priority() == prio::IGNORED) + if (child->priority() == BitTorrent::FilePriority::Ignored) continue; if (child->itemType() == FolderType) diff --git a/src/gui/torrentcontentmodelfolder.h b/src/gui/torrentcontentmodelfolder.h index 940a2629a..983b73477 100644 --- a/src/gui/torrentcontentmodelfolder.h +++ b/src/gui/torrentcontentmodelfolder.h @@ -29,6 +29,7 @@ #ifndef TORRENTCONTENTMODELFOLDER_H #define TORRENTCONTENTMODELFOLDER_H +#include "base/bittorrent/filepriority.h" #include "torrentcontentmodelitem.h" class TorrentContentModelFolder : public TorrentContentModelItem @@ -49,7 +50,7 @@ public: void recalculateAvailability(); void updatePriority(); - void setPriority(int newPriority, bool updateParent = true) override; + void setPriority(BitTorrent::FilePriority newPriority, bool updateParent = true) override; void deleteAllChildren(); const QList &children() const; diff --git a/src/gui/torrentcontentmodelitem.cpp b/src/gui/torrentcontentmodelitem.cpp index 01f0e39f5..7a78ece4d 100644 --- a/src/gui/torrentcontentmodelitem.cpp +++ b/src/gui/torrentcontentmodelitem.cpp @@ -38,7 +38,7 @@ TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *pare : m_parentItem(parent) , m_size(0) , m_remaining(0) - , m_priority(prio::NORMAL) + , m_priority(BitTorrent::FilePriority::Normal) , m_progress(0) , m_availability(-1.) { @@ -90,7 +90,7 @@ qreal TorrentContentModelItem::availability() const return (m_size > 0) ? m_availability : 0; } -int TorrentContentModelItem::priority() const +BitTorrent::FilePriority TorrentContentModelItem::priority() const { Q_ASSERT(!isRootItem()); return m_priority; @@ -110,7 +110,7 @@ QVariant TorrentContentModelItem::data(int column) const case COL_NAME: return m_name; case COL_PRIO: - return m_priority; + return static_cast(m_priority); case COL_PROGRESS: return progress(); case COL_SIZE: diff --git a/src/gui/torrentcontentmodelitem.h b/src/gui/torrentcontentmodelitem.h index 64597bd80..f31fe3f9f 100644 --- a/src/gui/torrentcontentmodelitem.h +++ b/src/gui/torrentcontentmodelitem.h @@ -32,17 +32,7 @@ #include #include -namespace prio -{ - enum FilePriority - { - IGNORED=0, - NORMAL=1, - HIGH=6, - MAXIMUM=7, - MIXED=-1 - }; -} +#include "base/bittorrent/filepriority.h" class TorrentContentModelFolder; @@ -82,8 +72,8 @@ public: qreal availability() const; - int priority() const; - virtual void setPriority(int newPriority, bool updateParent = true) = 0; + BitTorrent::FilePriority priority() const; + virtual void setPriority(BitTorrent::FilePriority newPriority, bool updateParent = true) = 0; int columnCount() const; QVariant data(int column) const; @@ -97,7 +87,7 @@ protected: QString m_name; qulonglong m_size; qulonglong m_remaining; - int m_priority; + BitTorrent::FilePriority m_priority; qreal m_progress; qreal m_availability; }; diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index c25c75790..c0482b411 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -39,6 +39,7 @@ #include #include +#include "base/bittorrent/filepriority.h" #include "base/bittorrent/session.h" #include "base/bittorrent/torrenthandle.h" #include "base/bittorrent/torrentinfo.h" @@ -371,7 +372,7 @@ void TorrentsController::filesAction() const QString hash {params()["hash"]}; QVariantList fileList; - BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -563,12 +564,38 @@ void TorrentsController::filePrioAction() checkParams({"hash", "id", "priority"}); const QString hash = params()["hash"]; - int fileID = params()["id"].toInt(); - int priority = params()["priority"].toInt(); - BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + bool ok = false; + const int priority = params()["priority"].toInt(&ok); + if (!ok) + throw APIError(APIErrorType::BadParams, tr("Priority must be an integer")); - if (torrent && torrent->hasMetadata()) - torrent->setFilePriority(fileID, priority); + if (!BitTorrent::isValidFilePriority(static_cast(priority))) + throw APIError(APIErrorType::BadParams, tr("Priority is not valid")); + + BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + if (!torrent) + throw APIError(APIErrorType::NotFound); + if (!torrent->hasMetadata()) + throw APIError(APIErrorType::Conflict, tr("Torrent's metadata has not yet downloaded")); + + const int filesCount = torrent->filesCount(); + QVector priorities = torrent->filePriorities(); + bool priorityChanged = false; + for (const QString &fileID : params()["id"].split('|')) { + const int id = fileID.toInt(&ok); + if (!ok) + throw APIError(APIErrorType::BadParams, tr("File IDs must be integers")); + if ((id < 0) || (id >= filesCount)) + throw APIError(APIErrorType::Conflict, tr("File ID is not valid")); + + if (priorities[id] != priority) { + priorities[id] = priority; + priorityChanged = true; + } + } + + if (priorityChanged) + torrent->prioritizeFiles(priorities); } void TorrentsController::uploadLimitAction() diff --git a/src/webui/www/private/properties_content.html b/src/webui/www/private/properties_content.html index 9f9d4d09d..ecd56f4d8 100644 --- a/src/webui/www/private/properties_content.html +++ b/src/webui/www/private/properties_content.html @@ -133,7 +133,7 @@ - + diff --git a/src/webui/www/private/scripts/prop-files.js b/src/webui/www/private/scripts/prop-files.js index de107140a..ddd567685 100644 --- a/src/webui/www/private/scripts/prop-files.js +++ b/src/webui/www/private/scripts/prop-files.js @@ -1,74 +1,46 @@ var is_seed = true; var current_hash = ""; -if (!(Browser.name == "ie" && Browser.version < 9)) { - $("all_files_cb").removeClass("tristate"); - $("all_files_cb").removeClass("partial"); - $("all_files_cb").removeClass("checked"); - $("tristate_cb").style.display = "inline"; -} - var setCBState = function(state) { - if (Browser.name == "ie" && Browser.version < 9) { - if (state == "partial") { - if (!$("all_files_cb").hasClass("partial")) { - $("all_files_cb").removeClass("checked"); - $("all_files_cb").addClass("partial"); - } - return; - } - if (state == "checked") { - if (!$("all_files_cb").hasClass("checked")) { - $("all_files_cb").removeClass("partial"); - $("all_files_cb").addClass("checked"); - } - return; - } - $("all_files_cb").removeClass("partial"); - $("all_files_cb").removeClass("checked"); + $("tristate_cb").state = state; + if (state === "partial") { + $("tristate_cb").indeterminate = true; } - else { - if (state == "partial") { - $("tristate_cb").indeterminate = true; - } - else if (state == "checked") { - $("tristate_cb").indeterminate = false; - $("tristate_cb").checked = true; - } - else { - $("tristate_cb").indeterminate = false; - $("tristate_cb").checked = false; - } + else if (state === "checked") { + $("tristate_cb").indeterminate = false; + $("tristate_cb").checked = true; + } + else if (state === "unchecked") { + $("tristate_cb").indeterminate = false; + $("tristate_cb").checked = false; } }; var switchCBState = function() { // Uncheck - if ($("all_files_cb").hasClass("partial")) { - $("all_files_cb").removeClass("partial"); + if (($("tristate_cb").state === "partial") || ($("tristate_cb").state === "checked")) { + $("tristate_cb").state = "unchecked"; + $("tristate_cb").checked = false; // Uncheck all checkboxes + var indexes = []; $$('input.DownloadedCB').each(function(item, index) { item.erase("checked"); - setFilePriority(index, 0); + indexes.push(index); }); - return; + setFilePriority(indexes, 0); } - if ($("all_files_cb").hasClass("checked")) { - $("all_files_cb").removeClass("checked"); - // Uncheck all checkboxes + else if ($("tristate_cb").state === "unchecked") { + // Check + $("tristate_cb").state = "checked"; + $("tristate_cb").checked = true; + // Check all checkboxes + var indexes = []; $$('input.DownloadedCB').each(function(item, index) { - item.erase("checked"); - setFilePriority(index, 0); + item.set("checked", "checked"); + indexes.push(index); }); - return; + setFilePriority(indexes, FilePriority.Normal); } - // Check - $("all_files_cb").addClass("checked"); - // Check all checkboxes - $$('input.DownloadedCB').each(function(item, index) { - item.set("checked", "checked"); - setFilePriority(index, 1); - }); }; var allCBChecked = function() { @@ -91,24 +63,58 @@ var allCBUnchecked = function() { return true; }; +var FilePriority = { + "Ignored": 0, + "Normal": 1, + "High": 6, + "Maximum": 7, + "Mixed": -1 +}; + +var normalizePriority = function(priority) { + switch (priority) { + case FilePriority.Ignored: + case FilePriority.Normal: + case FilePriority.High: + case FilePriority.Maximum: + case FilePriority.Mixed: + return priority; + default: + return FilePriority.Normal; + } +}; + var setFilePriority = function(id, priority) { if (current_hash === "") return; + var ids = Array.isArray(id) ? id : [id]; + + clearTimeout(loadTorrentFilesDataTimer); new Request({ url: 'api/v2/torrents/filePrio', method: 'post', data: { 'hash': current_hash, - 'id': id, + 'id': ids.join('|'), 'priority': priority + }, + onComplete: function() { + loadTorrentFilesDataTimer = loadTorrentFilesData.delay(1000); } }).send(); // Display or add combobox if (priority > 0) { - $('comboPrio' + id).set("value", 1); - $('comboPrio' + id).removeClass("invisible"); + ids.forEach(function(_id) { + if ($('comboPrio' + _id).hasClass("invisible")) { + $('comboPrio' + _id).set("value", priority); + $('comboPrio' + _id).removeClass("invisible"); + } + }); } else { - $('comboPrio' + id).addClass("invisible"); + ids.forEach(function(_id) { + if (!$('comboPrio' + _id).hasClass("invisible")) + $('comboPrio' + _id).addClass("invisible"); + }); } }; @@ -127,13 +133,11 @@ var createDownloadedCB = function(id, downloaded) { if (allCBChecked()) { setCBState("checked"); } + else if (allCBUnchecked()) { + setCBState("unchecked"); + } else { - if (allCBUnchecked()) { - setCBState("unchecked"); - } - else { - setCBState("partial"); - } + setCBState("partial"); } }); return CB; @@ -146,25 +150,21 @@ var createPriorityCombo = function(id, selected_prio) { var new_prio = $('comboPrio' + id).get('value'); setFilePriority(id, new_prio); }); - var opt = new Element("option"); - opt.set('value', '1'); - opt.set('html', "QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]"); - if (selected_prio <= 1) - opt.setAttribute('selected', ''); - opt.injectInside(select); - opt = new Element("option"); - opt.set('value', '2'); - opt.set('html', "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]"); - if (selected_prio == 2) - opt.setAttribute('selected', ''); - opt.injectInside(select); - opt = new Element("option"); - opt.set('value', '7'); - opt.set('html', "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]"); - if (selected_prio == 7) - opt.setAttribute('selected', ''); - opt.injectInside(select); - if (is_seed || selected_prio < 1) { + + function createOptionElement(priority, html) { + var elem = new Element("option"); + elem.set('value', priority.toString()); + elem.set('html', html); + if (priority == selected_prio) + elem.setAttribute('selected', ''); + return elem; + } + + createOptionElement(FilePriority.Normal, "QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]").injectInside(select); + createOptionElement(FilePriority.High, "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]").injectInside(select); + createOptionElement(FilePriority.Maximum, "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]").injectInside(select); + + if (is_seed || (selected_prio === FilePriority.Ignored) || (selected_prio === FilePriority.Mixed)) { select.addClass("invisible"); } else { @@ -203,19 +203,21 @@ var filesDynTable = new Class({ var tds = tr.getElements('td'); for (var i = 0; i < row.length; ++i) { switch (i) { - case 0: + case 0: // checkbox if (row[i] > 0) tds[i].getChildren('input')[0].set('checked', 'checked'); else tds[i].getChildren('input')[0].removeProperty('checked'); break; - case 3: + case 3: // progress bar $('pbf_' + id).setValue(row[i].toFloat()); break; - case 4: - if (!is_seed && row[i] > 0) { - tds[i].getChildren('select').set('value', row[i]); - $('comboPrio' + id).removeClass("invisible"); + case 4: // download priority + var priority = normalizePriority(row[i]); + if (!is_seed && (priority > 0)) { + tds[i].getChildren('select').set('value', priority); + if ($('comboPrio' + id).hasClass("invisible")) + $('comboPrio' + id).removeClass("invisible"); } else { if (!$('comboPrio' + id).hasClass("invisible")) @@ -259,7 +261,7 @@ var filesDynTable = new Class({ })); break; case 4: - td.adopt(createPriorityCombo(id, row[i])); + td.adopt(createPriorityCombo(id, normalizePriority(row[i]))); break; default: td.set('html', row[i]); @@ -327,13 +329,11 @@ var loadTorrentFilesData = function() { if (allCBChecked()) { setCBState("checked"); } + else if (allCBUnchecked()) { + setCBState("unchecked"); + } else { - if (allCBUnchecked()) { - setCBState("unchecked"); - } - else { - setCBState("partial"); - } + setCBState("partial"); } } else {
QBT_TR(Name)QBT_TR[CONTEXT=TorrentContentModel] QBT_TR(Size)QBT_TR[CONTEXT=TorrentContentModel] QBT_TR(Progress)QBT_TR[CONTEXT=TorrentContentModel]