From f27dc977e92c11350b5db26800937d0244b01a06 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Sun, 21 Oct 2018 18:58:11 -0400 Subject: [PATCH 1/5] Replace prio namespace with FilePriority enum class --- src/base/CMakeLists.txt | 2 ++ src/base/base.pri | 2 ++ src/base/bittorrent/filepriority.cpp | 46 +++++++++++++++++++++++++ src/base/bittorrent/filepriority.h | 43 +++++++++++++++++++++++ src/gui/addnewtorrentdialog.cpp | 13 +++---- src/gui/properties/propertieswidget.cpp | 13 +++---- src/gui/properties/proplistdelegate.cpp | 33 +++++++++--------- src/gui/torrentcontentmodel.cpp | 30 ++++++++-------- src/gui/torrentcontentmodelfile.cpp | 4 +-- src/gui/torrentcontentmodelfile.h | 3 +- src/gui/torrentcontentmodelfolder.cpp | 12 +++---- src/gui/torrentcontentmodelfolder.h | 3 +- src/gui/torrentcontentmodelitem.cpp | 6 ++-- src/gui/torrentcontentmodelitem.h | 18 +++------- 14 files changed, 159 insertions(+), 69 deletions(-) create mode 100644 src/base/bittorrent/filepriority.cpp create mode 100644 src/base/bittorrent/filepriority.h 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/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/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; }; From c5b8f62780b178a5912fd0d60b7459cec3a9067d Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Sun, 21 Oct 2018 19:00:38 -0400 Subject: [PATCH 2/5] Set priority for multiple files in one WebAPI request Closes #6259. --- src/base/bittorrent/torrenthandle.cpp | 10 --- src/base/bittorrent/torrenthandle.h | 1 - src/webui/api/torrentscontroller.cpp | 37 ++++++++-- src/webui/www/private/scripts/prop-files.js | 77 +++++++++++++-------- 4 files changed, 80 insertions(+), 45 deletions(-) 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/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 1082f829d..3d3ad5481 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); @@ -561,12 +562,38 @@ void TorrentsController::filePrioAction() checkParams({"hash", "id", "priority"}); const QString hash = params()["hash"]; - int fileID = params()["id"].toInt(); - int priority = params()["priority"].toInt(); + bool ok = false; + const int priority = params()["priority"].toInt(&ok); + if (!ok) + throw APIError(APIErrorType::BadParams, tr("Priority must be an integer")); + + 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 (torrent && torrent->hasMetadata()) - torrent->setFilePriority(fileID, priority); + if (priorityChanged) + torrent->prioritizeFiles(priorities); } void TorrentsController::uploadLimitAction() diff --git a/src/webui/www/private/scripts/prop-files.js b/src/webui/www/private/scripts/prop-files.js index de107140a..c1511dcb2 100644 --- a/src/webui/www/private/scripts/prop-files.js +++ b/src/webui/www/private/scripts/prop-files.js @@ -47,28 +47,34 @@ var switchCBState = function() { if ($("all_files_cb").hasClass("partial")) { $("all_files_cb").removeClass("partial"); // Uncheck all checkboxes + var indexes = []; $$('input.DownloadedCB').each(function(item, index) { item.erase("checked"); - setFilePriority(index, 0); + indexes.push(index); }); + setFilePriority(indexes, 0); return; } if ($("all_files_cb").hasClass("checked")) { $("all_files_cb").removeClass("checked"); // Uncheck all checkboxes + var indexes = []; $$('input.DownloadedCB').each(function(item, index) { item.erase("checked"); - setFilePriority(index, 0); + indexes.push(index); }); + setFilePriority(indexes, 0); return; } // Check $("all_files_cb").addClass("checked"); // Check all checkboxes + var indexes = []; $$('input.DownloadedCB').each(function(item, index) { item.set("checked", "checked"); - setFilePriority(index, 1); + indexes.push(index); }); + setFilePriority(indexes, 1); }; var allCBChecked = function() { @@ -93,22 +99,31 @@ var allCBUnchecked = function() { var setFilePriority = function(id, priority) { if (current_hash === "") return; + var ids = Array.isArray(id) ? id : [id]; + new Request({ url: 'api/v2/torrents/filePrio', method: 'post', data: { 'hash': current_hash, - 'id': id, + 'id': ids.join('|'), 'priority': priority } }).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"); + }); } }; @@ -146,24 +161,27 @@ 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); + + function createOptionElement(priority, html) { + var elem = new Element("option"); + elem.set('value', priority.toString()); + elem.set('html', html); + if (selected_prio == priority) + elem.setAttribute('selected', 'true'); + return elem; + } + + var normal = createOptionElement(1, "QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]"); + if (selected_prio <= 0) + normal.setAttribute('selected', ''); + normal.injectInside(select); + + var high = createOptionElement(2, "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]"); + high.injectInside(select); + + var maximum = createOptionElement(7, "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]"); + maximum.injectInside(select); + if (is_seed || selected_prio < 1) { select.addClass("invisible"); } @@ -203,19 +221,20 @@ 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: + case 4: // download priority if (!is_seed && row[i] > 0) { tds[i].getChildren('select').set('value', row[i]); - $('comboPrio' + id).removeClass("invisible"); + if ($('comboPrio' + id).hasClass("invisible")) + $('comboPrio' + id).removeClass("invisible"); } else { if (!$('comboPrio' + id).hasClass("invisible")) From a44ed9cfd3a45840dbd78ad809c9368c5203be6a Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Mon, 22 Oct 2018 00:07:36 -0400 Subject: [PATCH 3/5] Fix incorrect priority value sent from WebUI Closes #9070. --- src/webui/www/private/scripts/prop-files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webui/www/private/scripts/prop-files.js b/src/webui/www/private/scripts/prop-files.js index c1511dcb2..5d3da36cb 100644 --- a/src/webui/www/private/scripts/prop-files.js +++ b/src/webui/www/private/scripts/prop-files.js @@ -176,7 +176,7 @@ var createPriorityCombo = function(id, selected_prio) { normal.setAttribute('selected', ''); normal.injectInside(select); - var high = createOptionElement(2, "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]"); + var high = createOptionElement(6, "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]"); high.injectInside(select); var maximum = createOptionElement(7, "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]"); From 66015164d7c89a640be8e35deb9a4587cf32cdd4 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Tue, 13 Nov 2018 01:04:49 -0500 Subject: [PATCH 4/5] Fix display bugs in WebUI Files tab. Remove - + QBT_TR(Name)QBT_TR[CONTEXT=TorrentContentModel] QBT_TR(Size)QBT_TR[CONTEXT=TorrentContentModel] QBT_TR(Progress)QBT_TR[CONTEXT=TorrentContentModel] diff --git a/src/webui/www/private/scripts/prop-files.js b/src/webui/www/private/scripts/prop-files.js index 5d3da36cb..ddd567685 100644 --- a/src/webui/www/private/scripts/prop-files.js +++ b/src/webui/www/private/scripts/prop-files.js @@ -1,51 +1,26 @@ 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) { @@ -53,28 +28,19 @@ var switchCBState = function() { indexes.push(index); }); setFilePriority(indexes, 0); - return; } - 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"); + item.set("checked", "checked"); indexes.push(index); }); - setFilePriority(indexes, 0); - return; + setFilePriority(indexes, FilePriority.Normal); } - // Check - $("all_files_cb").addClass("checked"); - // Check all checkboxes - var indexes = []; - $$('input.DownloadedCB').each(function(item, index) { - item.set("checked", "checked"); - indexes.push(index); - }); - setFilePriority(indexes, 1); }; var allCBChecked = function() { @@ -97,10 +63,32 @@ 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', @@ -108,6 +96,9 @@ var setFilePriority = function(id, priority) { 'hash': current_hash, 'id': ids.join('|'), 'priority': priority + }, + onComplete: function() { + loadTorrentFilesDataTimer = loadTorrentFilesData.delay(1000); } }).send(); // Display or add combobox @@ -142,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; @@ -166,23 +155,16 @@ var createPriorityCombo = function(id, selected_prio) { var elem = new Element("option"); elem.set('value', priority.toString()); elem.set('html', html); - if (selected_prio == priority) - elem.setAttribute('selected', 'true'); + if (priority == selected_prio) + elem.setAttribute('selected', ''); return elem; } - var normal = createOptionElement(1, "QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]"); - if (selected_prio <= 0) - normal.setAttribute('selected', ''); - normal.injectInside(select); - - var high = createOptionElement(6, "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]"); - high.injectInside(select); - - var maximum = createOptionElement(7, "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]"); - maximum.injectInside(select); + 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 < 1) { + if (is_seed || (selected_prio === FilePriority.Ignored) || (selected_prio === FilePriority.Mixed)) { select.addClass("invisible"); } else { @@ -231,8 +213,9 @@ var filesDynTable = new Class({ $('pbf_' + id).setValue(row[i].toFloat()); break; case 4: // download priority - if (!is_seed && row[i] > 0) { - tds[i].getChildren('select').set('value', row[i]); + 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"); } @@ -278,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]); @@ -346,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 { From 57e625494b26e0223fc236dc4d954dcbf2fe1985 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Sun, 2 Dec 2018 19:13:17 -0500 Subject: [PATCH 5/5] Update Copyright email address --- src/gui/ipsubnetwhitelistoptionsdialog.cpp | 2 +- src/gui/ipsubnetwhitelistoptionsdialog.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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