From 03b06fbf81f719269443e9f752113ec5f61f31b0 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sat, 25 Oct 2014 14:53:29 +0400 Subject: [PATCH 1/5] Split src/transferlistdelegate into .h and .cpp --- src/src.pro | 1 + src/transferlistdelegate.cpp | 229 +++++++++++++++++++++++++++++++++++ src/transferlistdelegate.h | 204 ++----------------------------- 3 files changed, 240 insertions(+), 194 deletions(-) create mode 100644 src/transferlistdelegate.cpp diff --git a/src/src.pro b/src/src.pro index 58f7f2c5b..00db80108 100644 --- a/src/src.pro +++ b/src/src.pro @@ -159,6 +159,7 @@ nox { SOURCES += mainwindow.cpp \ ico.cpp \ transferlistwidget.cpp \ + transferlistdelegate.cpp \ torrentcontentmodel.cpp \ torrentcontentmodelitem.cpp \ torrentcontentmodelfolder.cpp \ diff --git a/src/transferlistdelegate.cpp b/src/transferlistdelegate.cpp new file mode 100644 index 000000000..ed3778c4c --- /dev/null +++ b/src/transferlistdelegate.cpp @@ -0,0 +1,229 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "transferlistdelegate.h" + +#include +#include +#include +#include +#include "misc.h" +#include "torrentmodel.h" +#include "qbtsession.h" + +#ifdef Q_OS_WIN +#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) +#include +#else +#include +#endif +#endif + +TransferListDelegate::TransferListDelegate(QObject *parent) : QItemDelegate(parent) {} + +TransferListDelegate::~TransferListDelegate() {} + +void TransferListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + painter->save(); + switch(index.column()) { + case TorrentModelItem::TR_AMOUNT_DOWNLOADED: + case TorrentModelItem::TR_AMOUNT_UPLOADED: + case TorrentModelItem::TR_AMOUNT_LEFT: + case TorrentModelItem::TR_COMPLETED: + case TorrentModelItem::TR_SIZE: { + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + } + case TorrentModelItem::TR_ETA: { + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::userFriendlyDuration(index.data().toLongLong())); + break; + } + case TorrentModelItem::TR_SEEDS: + case TorrentModelItem::TR_PEERS: { + QString display = QString::number(index.data().toLongLong()); + qlonglong total = index.data(Qt::UserRole).toLongLong(); + if (total > 0) { + // Scrape was successful, we have total values + display += " ("+QString::number(total)+")"; + } + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, display); + break; + } + case TorrentModelItem::TR_STATUS: { + const int state = index.data().toInt(); + QString display; + switch(state) { + case TorrentModelItem::STATE_DOWNLOADING: + display = tr("Downloading"); + break; + case TorrentModelItem::STATE_DOWNLOADING_META: + display = tr("Downloading metadata", "used when loading a magnet link"); + break; + case TorrentModelItem::STATE_ALLOCATING: + display = tr("Allocating", "qBittorrent is allocating the files on disk"); + break; + case TorrentModelItem::STATE_PAUSED_DL: + case TorrentModelItem::STATE_PAUSED_UP: + display = tr("Paused"); + break; + case TorrentModelItem::STATE_QUEUED_DL: + case TorrentModelItem::STATE_QUEUED_UP: + display = tr("Queued", "i.e. torrent is queued"); + break; + case TorrentModelItem::STATE_SEEDING: + case TorrentModelItem::STATE_STALLED_UP: + display = tr("Seeding", "Torrent is complete and in upload-only mode"); + break; + case TorrentModelItem::STATE_STALLED_DL: + display = tr("Stalled", "Torrent is waiting for download to begin"); + break; + case TorrentModelItem::STATE_CHECKING_DL: + case TorrentModelItem::STATE_CHECKING_UP: + display = tr("Checking", "Torrent local data is being checked"); + break; + case TorrentModelItem::STATE_QUEUED_CHECK: + display = tr("Queued for checking", "i.e. torrent is queued for hash checking"); + break; + case TorrentModelItem::STATE_QUEUED_FASTCHECK: + display = tr("Checking resume data", "used when loading the torrents from disk after qbt is launched. It checks the correctness of the .fastresume file. Normally it is completed in a fraction of a second, unless loading many many torrents."); + break; + default: + display = ""; + } + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, opt.rect, display); + break; + } + case TorrentModelItem::TR_UPSPEED: + case TorrentModelItem::TR_DLSPEED: { + QItemDelegate::drawBackground(painter, opt, index); + const qulonglong speed = index.data().toULongLong(); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)")); + break; + } + case TorrentModelItem::TR_UPLIMIT: + case TorrentModelItem::TR_DLLIMIT: { + QItemDelegate::drawBackground(painter, opt, index); + const qlonglong limit = index.data().toLongLong(); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, limit > 0 ? misc::accurateDoubleToString(limit/1024., 1) + " " + tr("KiB/s", "KiB/second (.i.e per second)") : QString::fromUtf8("∞")); + break; + } + case TorrentModelItem::TR_TIME_ELAPSED: { + QItemDelegate::drawBackground(painter, opt, index); + QString txt = misc::userFriendlyDuration(index.data().toLongLong()); + qlonglong seeding_time = index.data(Qt::UserRole).toLongLong(); + if (seeding_time > 0) + txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(seeding_time))+")"; + QItemDelegate::drawDisplay(painter, opt, opt.rect, txt); + break; + } + case TorrentModelItem::TR_ADD_DATE: + case TorrentModelItem::TR_SEED_DATE: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, opt.rect, index.data().toDateTime().toLocalTime().toString(Qt::DefaultLocaleShortDate)); + break; + case TorrentModelItem::TR_RATIO_LIMIT: + case TorrentModelItem::TR_RATIO: { + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + const qreal ratio = index.data().toDouble(); + QItemDelegate::drawDisplay(painter, opt, opt.rect, + (ratio == -1 || ratio > QBtSession::MAX_RATIO) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 2)); + break; + } + case TorrentModelItem::TR_PRIORITY: { + const int priority = index.data().toInt(); + opt.displayAlignment = Qt::AlignRight; + if (priority >= 0) + QItemDelegate::paint(painter, opt, index); + else { + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); + } + break; + } + case TorrentModelItem::TR_PROGRESS: { + QStyleOptionProgressBarV2 newopt; + qreal progress = index.data().toDouble()*100.; + newopt.rect = opt.rect; + newopt.text = misc::accurateDoubleToString(progress, 1) + "%"; + newopt.progress = (int)progress; + newopt.maximum = 100; + newopt.minimum = 0; + newopt.state |= QStyle::State_Enabled; + newopt.textVisible = true; +#ifndef Q_OS_WIN + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); +#else + // XXX: To avoid having the progress text on the right of the bar +#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) + QPlastiqueStyle st; +#else + QProxyStyle st("fusion"); +#endif + st.drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); +#endif + break; + } + default: + QItemDelegate::paint(painter, option, index); + } + painter->restore(); +} + +QWidget* TransferListDelegate::createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { + // No editor here + return 0; +} + +QSize TransferListDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { + QSize size = QItemDelegate::sizeHint(option, index); + + static int icon_height = -1; + if (icon_height == -1) { + QIcon icon(":/Icons/skin/downloading.png"); + QList ic_sizes(icon.availableSizes()); + icon_height = ic_sizes[0].height(); + } + + if (size.height() < icon_height) + size.setHeight(icon_height); + + return size; +} diff --git a/src/transferlistdelegate.h b/src/transferlistdelegate.h index 091586dd5..ce8593241 100644 --- a/src/transferlistdelegate.h +++ b/src/transferlistdelegate.h @@ -32,21 +32,12 @@ #define TRANSFERLISTDELEGATE_H #include -#include -#include -#include -#include -#include "misc.h" -#include "torrentmodel.h" -#include "qbtsession.h" -#ifdef Q_OS_WIN -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) -#include -#else -#include -#endif -#endif +QT_BEGIN_NAMESPACE +class QPainter; +class QStyleOptionViewItem; +class QModelIndex; +QT_END_NAMESPACE // Defines for download list list columns @@ -54,191 +45,16 @@ class TransferListDelegate: public QItemDelegate { Q_OBJECT public: - TransferListDelegate(QObject *parent) : QItemDelegate(parent) {} - - ~TransferListDelegate() {} - - void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { - QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); - painter->save(); - switch(index.column()) { - case TorrentModelItem::TR_AMOUNT_DOWNLOADED: - case TorrentModelItem::TR_AMOUNT_UPLOADED: - case TorrentModelItem::TR_AMOUNT_LEFT: - case TorrentModelItem::TR_COMPLETED: - case TorrentModelItem::TR_SIZE: { - QItemDelegate::drawBackground(painter, opt, index); - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); - break; - } - case TorrentModelItem::TR_ETA: { - QItemDelegate::drawBackground(painter, opt, index); - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::drawDisplay(painter, opt, option.rect, misc::userFriendlyDuration(index.data().toLongLong())); - break; - } - case TorrentModelItem::TR_SEEDS: - case TorrentModelItem::TR_PEERS: { - QString display = QString::number(index.data().toLongLong()); - qlonglong total = index.data(Qt::UserRole).toLongLong(); - if (total > 0) { - // Scrape was successful, we have total values - display += " ("+QString::number(total)+")"; - } - QItemDelegate::drawBackground(painter, opt, index); - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::drawDisplay(painter, opt, opt.rect, display); - break; - } - case TorrentModelItem::TR_STATUS: { - const int state = index.data().toInt(); - QString display; - switch(state) { - case TorrentModelItem::STATE_DOWNLOADING: - display = tr("Downloading"); - break; - case TorrentModelItem::STATE_DOWNLOADING_META: - display = tr("Downloading metadata", "used when loading a magnet link"); - break; - case TorrentModelItem::STATE_ALLOCATING: - display = tr("Allocating", "qBittorrent is allocating the files on disk"); - break; - case TorrentModelItem::STATE_PAUSED_DL: - case TorrentModelItem::STATE_PAUSED_UP: - display = tr("Paused"); - break; - case TorrentModelItem::STATE_QUEUED_DL: - case TorrentModelItem::STATE_QUEUED_UP: - display = tr("Queued", "i.e. torrent is queued"); - break; - case TorrentModelItem::STATE_SEEDING: - case TorrentModelItem::STATE_STALLED_UP: - display = tr("Seeding", "Torrent is complete and in upload-only mode"); - break; - case TorrentModelItem::STATE_STALLED_DL: - display = tr("Stalled", "Torrent is waiting for download to begin"); - break; - case TorrentModelItem::STATE_CHECKING_DL: - case TorrentModelItem::STATE_CHECKING_UP: - display = tr("Checking", "Torrent local data is being checked"); - break; - case TorrentModelItem::STATE_QUEUED_CHECK: - display = tr("Queued for checking", "i.e. torrent is queued for hash checking"); - break; - case TorrentModelItem::STATE_QUEUED_FASTCHECK: - display = tr("Checking resume data", "used when loading the torrents from disk after qbt is launched. It checks the correctness of the .fastresume file. Normally it is completed in a fraction of a second, unless loading many many torrents."); - break; - default: - display = ""; - } - QItemDelegate::drawBackground(painter, opt, index); - QItemDelegate::drawDisplay(painter, opt, opt.rect, display); - break; - } - case TorrentModelItem::TR_UPSPEED: - case TorrentModelItem::TR_DLSPEED: { - QItemDelegate::drawBackground(painter, opt, index); - const qulonglong speed = index.data().toULongLong(); - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)")); - break; - } - case TorrentModelItem::TR_UPLIMIT: - case TorrentModelItem::TR_DLLIMIT: { - QItemDelegate::drawBackground(painter, opt, index); - const qlonglong limit = index.data().toLongLong(); - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::drawDisplay(painter, opt, opt.rect, limit > 0 ? misc::accurateDoubleToString(limit/1024., 1) + " " + tr("KiB/s", "KiB/second (.i.e per second)") : QString::fromUtf8("∞")); - break; - } - case TorrentModelItem::TR_TIME_ELAPSED: { - QItemDelegate::drawBackground(painter, opt, index); - QString txt = misc::userFriendlyDuration(index.data().toLongLong()); - qlonglong seeding_time = index.data(Qt::UserRole).toLongLong(); - if (seeding_time > 0) - txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(seeding_time))+")"; - QItemDelegate::drawDisplay(painter, opt, opt.rect, txt); - break; - } - case TorrentModelItem::TR_ADD_DATE: - case TorrentModelItem::TR_SEED_DATE: - QItemDelegate::drawBackground(painter, opt, index); - QItemDelegate::drawDisplay(painter, opt, opt.rect, index.data().toDateTime().toLocalTime().toString(Qt::DefaultLocaleShortDate)); - break; - case TorrentModelItem::TR_RATIO_LIMIT: - case TorrentModelItem::TR_RATIO: { - QItemDelegate::drawBackground(painter, opt, index); - opt.displayAlignment = Qt::AlignRight; - const qreal ratio = index.data().toDouble(); - QItemDelegate::drawDisplay(painter, opt, opt.rect, - (ratio == -1 || ratio > QBtSession::MAX_RATIO) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 2)); - break; - } - case TorrentModelItem::TR_PRIORITY: { - const int priority = index.data().toInt(); - opt.displayAlignment = Qt::AlignRight; - if (priority >= 0) - QItemDelegate::paint(painter, opt, index); - else { - QItemDelegate::drawBackground(painter, opt, index); - QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); - } - break; - } - case TorrentModelItem::TR_PROGRESS: { - QStyleOptionProgressBarV2 newopt; - qreal progress = index.data().toDouble()*100.; - newopt.rect = opt.rect; - newopt.text = misc::accurateDoubleToString(progress, 1) + "%"; - newopt.progress = (int)progress; - newopt.maximum = 100; - newopt.minimum = 0; - newopt.state |= QStyle::State_Enabled; - newopt.textVisible = true; -#ifndef Q_OS_WIN - QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); -#else - // XXX: To avoid having the progress text on the right of the bar -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) - QPlastiqueStyle st; -#else - QProxyStyle st("fusion"); -#endif - st.drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); -#endif - break; - } - default: - QItemDelegate::paint(painter, option, index); - } - painter->restore(); - } - - QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { - // No editor here - return 0; - } + TransferListDelegate(QObject *parent); + ~TransferListDelegate(); + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; + QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const; // Reimplementing sizeHint() because the 'name' column contains text+icon. // When that WHOLE column goes out of view(eg user scrolls horizontally) // the rows shrink if the text's height is smaller than the icon's height. // This happens because icon from the 'name' column is no longer drawn. - QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { - QSize size = QItemDelegate::sizeHint(option, index); - - static int icon_height = -1; - if (icon_height == -1) { - QIcon icon(":/Icons/skin/downloading.png"); - QList ic_sizes(icon.availableSizes()); - icon_height = ic_sizes[0].height(); - } - - if (size.height() < icon_height) - size.setHeight(icon_height); - - return size; - } + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const; }; From e1b4c5534ea0d9f17c74420450d1fb91854603b6 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sat, 25 Oct 2014 15:13:37 +0400 Subject: [PATCH 2/5] Split src/transferlistfilterswidget into .h and .cpp --- src/src.pro | 1 + src/transferlistfilterswidget.cpp | 449 ++++++++++++++++++++++++++++++ src/transferlistfilterswidget.h | 443 +++-------------------------- 3 files changed, 483 insertions(+), 410 deletions(-) create mode 100644 src/transferlistfilterswidget.cpp diff --git a/src/src.pro b/src/src.pro index 00db80108..dbafe1467 100644 --- a/src/src.pro +++ b/src/src.pro @@ -160,6 +160,7 @@ nox { ico.cpp \ transferlistwidget.cpp \ transferlistdelegate.cpp \ + transferlistfilterswidget.cpp \ torrentcontentmodel.cpp \ torrentcontentmodelitem.cpp \ torrentcontentmodelfolder.cpp \ diff --git a/src/transferlistfilterswidget.cpp b/src/transferlistfilterswidget.cpp new file mode 100644 index 000000000..b3d553f6f --- /dev/null +++ b/src/transferlistfilterswidget.cpp @@ -0,0 +1,449 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "transferlistfilterswidget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "transferlistdelegate.h" +#include "transferlistwidget.h" +#include "preferences.h" +#include "torrentmodel.h" +#include "iconprovider.h" +#include "fs_utils.h" +#include "autoexpandabledialog.h" +#include "torrentfilterenum.h" + +LabelFiltersList::LabelFiltersList(QWidget *parent): QListWidget(parent) { + itemHover = 0; + // Accept drop + setAcceptDrops(true); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + setStyleSheet("QListWidget { background: transparent; border: 0 }"); +#if defined(Q_OS_MAC) + setAttribute(Qt::WA_MacShowFocusRect, false); +#endif +} + +void LabelFiltersList::addItem(QListWidgetItem *it) { + Q_ASSERT(count() >= 2); + for (int i=2; itext().localeAwareCompare(it->text()) >= 0) { + insertItem(i, it); + return; + } + } + QListWidget::addItem(it); +} + +QString LabelFiltersList::labelFromRow(int row) const { + Q_ASSERT(row > 1); + const QString &label = item(row)->text(); + QStringList parts = label.split(" "); + Q_ASSERT(parts.size() >= 2); + parts.removeLast(); // Remove trailing number + return parts.join(" "); +} + +int LabelFiltersList::rowFromLabel(QString label) const { + Q_ASSERT(!label.isEmpty()); + for (int i=2; ipos()) && row(itemAt(event->pos())) > 0) { + if (itemHover) { + if (itemHover != itemAt(event->pos())) { + setItemHover(false); + itemHover = itemAt(event->pos()); + setItemHover(true); + } + } else { + itemHover = itemAt(event->pos()); + setItemHover(true); + } + event->acceptProposedAction(); + } else { + if (itemHover) + setItemHover(false); + event->ignore(); + } +} + +void LabelFiltersList::dropEvent(QDropEvent *event) { + qDebug("Drop Event in labels list"); + if (itemAt(event->pos())) { + emit torrentDropped(row(itemAt(event->pos()))); + } + event->ignore(); + setItemHover(false); + // Select current item again + currentItem()->setSelected(true); +} + +void LabelFiltersList::dragLeaveEvent(QDragLeaveEvent*) { + if (itemHover) + setItemHover(false); + // Select current item again + currentItem()->setSelected(true); +} + +void LabelFiltersList::setItemHover(bool hover) { + Q_ASSERT(itemHover); + if (hover) { + itemHover->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("folder-documents.png")); + itemHover->setSelected(true); + //setCurrentItem(itemHover); + } else { + itemHover->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory.png")); + //itemHover->setSelected(false); + itemHover = 0; + } +} + +StatusFiltersWidget::StatusFiltersWidget(QWidget *parent) : QListWidget(parent), m_shown(false) { + setUniformItemSizes(true); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + // Height is fixed (sizeHint().height() is used) + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + setStyleSheet("QListWidget { background: transparent; border: 0 }"); +#if defined(Q_OS_MAC) + setAttribute(Qt::WA_MacShowFocusRect, false); +#endif +} + +QSize StatusFiltersWidget::sizeHint() const { + QSize size = QListWidget::sizeHint(); + // Height should be exactly the height of the content + size.setHeight(contentsSize().height() + 2 * frameWidth()+6); + return size; +} + +TransferListFiltersWidget::TransferListFiltersWidget(QWidget *parent, TransferListWidget *transferList): QFrame(parent), transferList(transferList), nb_labeled(0), nb_torrents(0) { + // Construct lists + vLayout = new QVBoxLayout(); + vLayout->setContentsMargins(0, 4, 0, 4); + QFont font; + font.setBold(true); + font.setCapitalization(QFont::SmallCaps); + QLabel *torrentsLabel = new QLabel(tr("Torrents")); + torrentsLabel->setIndent(2); + torrentsLabel->setFont(font); + vLayout->addWidget(torrentsLabel); + statusFilters = new StatusFiltersWidget(this); + vLayout->addWidget(statusFilters); + QLabel *labelsLabel = new QLabel(tr("Labels")); + labelsLabel->setIndent(2); + labelsLabel->setFont(font); + vLayout->addWidget(labelsLabel); + labelFilters = new LabelFiltersList(this); + vLayout->addWidget(labelFilters); + setLayout(vLayout); + labelFilters->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + statusFilters->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + statusFilters->setSpacing(0); + setContentsMargins(0,0,0,0); + vLayout->setSpacing(2); + // Add status filters + QListWidgetItem *all = new QListWidgetItem(statusFilters); + all->setData(Qt::DisplayRole, QVariant(tr("All") + " (0)")); + all->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filterall.png")); + QListWidgetItem *downloading = new QListWidgetItem(statusFilters); + downloading->setData(Qt::DisplayRole, QVariant(tr("Downloading") + " (0)")); + downloading->setData(Qt::DecorationRole, QIcon(":/Icons/skin/downloading.png")); + QListWidgetItem *completed = new QListWidgetItem(statusFilters); + completed->setData(Qt::DisplayRole, QVariant(tr("Completed") + " (0)")); + completed->setData(Qt::DecorationRole, QIcon(":/Icons/skin/uploading.png")); + QListWidgetItem *paused = new QListWidgetItem(statusFilters); + paused->setData(Qt::DisplayRole, QVariant(tr("Paused") + " (0)")); + paused->setData(Qt::DecorationRole, QIcon(":/Icons/skin/paused.png")); + QListWidgetItem *active = new QListWidgetItem(statusFilters); + active->setData(Qt::DisplayRole, QVariant(tr("Active") + " (0)")); + active->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filteractive.png")); + QListWidgetItem *inactive = new QListWidgetItem(statusFilters); + inactive->setData(Qt::DisplayRole, QVariant(tr("Inactive") + " (0)")); + inactive->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filterinactive.png")); + + // SIGNAL/SLOT + connect(statusFilters, SIGNAL(currentRowChanged(int)), transferList, SLOT(applyStatusFilter(int))); + connect(transferList->getSourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateTorrentNumbers())); + connect(transferList->getSourceModel(), SIGNAL(torrentAdded(TorrentModelItem*)), SLOT(handleNewTorrent(TorrentModelItem*))); + connect(labelFilters, SIGNAL(currentRowChanged(int)), this, SLOT(applyLabelFilter(int))); + connect(labelFilters, SIGNAL(torrentDropped(int)), this, SLOT(torrentDropped(int))); + connect(transferList->getSourceModel(), SIGNAL(torrentAboutToBeRemoved(TorrentModelItem*)), SLOT(torrentAboutToBeDeleted(TorrentModelItem*))); + connect(transferList->getSourceModel(), SIGNAL(torrentChangedLabel(TorrentModelItem*,QString,QString)), SLOT(torrentChangedLabel(TorrentModelItem*, QString, QString))); + + // Add Label filters + QListWidgetItem *allLabels = new QListWidgetItem(labelFilters); + allLabels->setData(Qt::DisplayRole, QVariant(tr("All labels") + " (0)")); + allLabels->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + QListWidgetItem *noLabel = new QListWidgetItem(labelFilters); + noLabel->setData(Qt::DisplayRole, QVariant(tr("Unlabeled") + " (0)")); + noLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + + // Load settings + loadSettings(); + + labelFilters->setCurrentRow(0); + //labelFilters->selectionModel()->select(labelFilters->model()->index(0,0), QItemSelectionModel::Select); + + // Label menu + labelFilters->setContextMenuPolicy(Qt::CustomContextMenu); + connect(labelFilters, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showLabelMenu(QPoint))); +} + +TransferListFiltersWidget::~TransferListFiltersWidget() { + saveSettings(); + delete statusFilters; + delete labelFilters; + delete vLayout; +} + +StatusFiltersWidget* TransferListFiltersWidget::getStatusFilters() const { + return statusFilters; +} + +void TransferListFiltersWidget::saveSettings() const { + Preferences* const pref = Preferences::instance(); + pref->setTransSelFilter(statusFilters->currentRow()); + pref->setTorrentLabels(customLabels.keys()); +} + +void TransferListFiltersWidget::loadSettings() { + statusFilters->setCurrentRow(Preferences::instance()->getTransSelFilter()); + const QStringList label_list = Preferences::instance()->getTorrentLabels(); + foreach (const QString &label, label_list) { + customLabels.insert(label, 0); + qDebug("Creating label QListWidgetItem: %s", qPrintable(label)); + QListWidgetItem *newLabel = new QListWidgetItem(); + newLabel->setText(label + " (0)"); + newLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + labelFilters->addItem(newLabel); + } +} + +void TransferListFiltersWidget::updateTorrentNumbers() { + const TorrentStatusReport report = transferList->getSourceModel()->getTorrentStatusReport(); + statusFilters->item(TorrentFilter::ALL)->setData(Qt::DisplayRole, QVariant(tr("All")+" ("+QString::number(report.nb_active+report.nb_inactive)+")")); + statusFilters->item(TorrentFilter::DOWNLOADING)->setData(Qt::DisplayRole, QVariant(tr("Downloading")+" ("+QString::number(report.nb_downloading)+")")); + statusFilters->item(TorrentFilter::COMPLETED)->setData(Qt::DisplayRole, QVariant(tr("Completed")+" ("+QString::number(report.nb_seeding)+")")); + statusFilters->item(TorrentFilter::PAUSED)->setData(Qt::DisplayRole, QVariant(tr("Paused")+" ("+QString::number(report.nb_paused)+")")); + statusFilters->item(TorrentFilter::ACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Active")+" ("+QString::number(report.nb_active)+")")); + statusFilters->item(TorrentFilter::INACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Inactive")+" ("+QString::number(report.nb_inactive)+")")); +} + +void TransferListFiltersWidget::torrentDropped(int row) { + Q_ASSERT(row > 0); + if (row == 1) { + transferList->setSelectionLabel(""); + } else { + transferList->setSelectionLabel(labelFilters->labelFromRow(row)); + } +} + +void TransferListFiltersWidget::addLabel(QString& label) { + label = fsutils::toValidFileSystemName(label.trimmed()); + if (label.isEmpty() || customLabels.contains(label)) return; + QListWidgetItem *newLabel = new QListWidgetItem(); + newLabel->setText(label + " (0)"); + newLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + labelFilters->addItem(newLabel); + customLabels.insert(label, 0); + Preferences::instance()->addTorrentLabel(label); +} + +void TransferListFiltersWidget::showLabelMenu(QPoint) { + QMenu labelMenu(labelFilters); + QAction *removeAct = 0; + if (!labelFilters->selectedItems().empty() && labelFilters->row(labelFilters->selectedItems().first()) > 1) + removeAct = labelMenu.addAction(IconProvider::instance()->getIcon("list-remove"), tr("Remove label")); + QAction *addAct = labelMenu.addAction(IconProvider::instance()->getIcon("list-add"), tr("Add label...")); + labelMenu.addSeparator(); + QAction *startAct = labelMenu.addAction(IconProvider::instance()->getIcon("media-playback-start"), tr("Resume torrents")); + QAction *pauseAct = labelMenu.addAction(IconProvider::instance()->getIcon("media-playback-pause"), tr("Pause torrents")); + QAction *deleteTorrentsAct = labelMenu.addAction(IconProvider::instance()->getIcon("edit-delete"), tr("Delete torrents")); + QAction *act = 0; + act = labelMenu.exec(QCursor::pos()); + if (act) { + if (act == removeAct) { + removeSelectedLabel(); + return; + } + if (act == deleteTorrentsAct) { + transferList->deleteVisibleTorrents(); + return; + } + if (act == startAct) { + transferList->startVisibleTorrents(); + return; + } + if (act == pauseAct) { + transferList->pauseVisibleTorrents(); + return; + } + if (act == addAct) { + bool ok; + QString label = ""; + bool invalid; + do { + invalid = false; + label = AutoExpandableDialog::getText(this, tr("New Label"), tr("Label:"), QLineEdit::Normal, label, &ok); + if (ok && !label.isEmpty()) { + if (fsutils::isValidFileSystemName(label)) { + addLabel(label); + } else { + QMessageBox::warning(this, tr("Invalid label name"), tr("Please don't use any special characters in the label name.")); + invalid = true; + } + } + } while(invalid); + return; + } + } +} + +void TransferListFiltersWidget::removeSelectedLabel() { + const int row = labelFilters->row(labelFilters->selectedItems().first()); + Q_ASSERT(row > 1); + const QString &label = labelFilters->labelFromRow(row); + Q_ASSERT(customLabels.contains(label)); + customLabels.remove(label); + transferList->removeLabelFromRows(label); + // Select first label + labelFilters->setCurrentItem(labelFilters->item(0)); + labelFilters->selectionModel()->select(labelFilters->model()->index(0,0), QItemSelectionModel::Select); + applyLabelFilter(0); + // Un display filter + delete labelFilters->takeItem(row); + // Save custom labels to remember it was deleted + Preferences::instance()->removeTorrentLabel(label); +} + +void TransferListFiltersWidget::applyLabelFilter(int row) { + switch(row) { + case 0: + transferList->applyLabelFilter("all"); + break; + case 1: + transferList->applyLabelFilter("none"); + break; + default: + transferList->applyLabelFilter(labelFilters->labelFromRow(row)); + } +} + +void TransferListFiltersWidget::torrentChangedLabel(TorrentModelItem *torrentItem, QString old_label, QString new_label) { + Q_UNUSED(torrentItem); + qDebug("Torrent label changed from %s to %s", qPrintable(old_label), qPrintable(new_label)); + if (!old_label.isEmpty()) { + if (customLabels.contains(old_label)) { + const int new_count = customLabels.value(old_label, 0) - 1; + Q_ASSERT(new_count >= 0); + customLabels.insert(old_label, new_count); + const int row = labelFilters->rowFromLabel(old_label); + Q_ASSERT(row >= 2); + labelFilters->item(row)->setText(old_label + " ("+ QString::number(new_count) +")"); + } + --nb_labeled; + } + if (!new_label.isEmpty()) { + if (!customLabels.contains(new_label)) + addLabel(new_label); + const int new_count = customLabels.value(new_label, 0) + 1; + Q_ASSERT(new_count >= 1); + customLabels.insert(new_label, new_count); + const int row = labelFilters->rowFromLabel(new_label); + Q_ASSERT(row >= 2); + labelFilters->item(row)->setText(new_label + " ("+ QString::number(new_count) +")"); + ++nb_labeled; + } + updateStickyLabelCounters(); +} + +void TransferListFiltersWidget::handleNewTorrent(TorrentModelItem* torrentItem) { + QString label = torrentItem->data(TorrentModelItem::TR_LABEL).toString(); + qDebug("New torrent was added with label: %s", qPrintable(label)); + if (!label.isEmpty()) { + if (!customLabels.contains(label)) { + addLabel(label); + // addLabel may have changed the label, update the model accordingly. + torrentItem->setData(TorrentModelItem::TR_LABEL, label); + } + // Update label counter + Q_ASSERT(customLabels.contains(label)); + const int new_count = customLabels.value(label, 0) + 1; + customLabels.insert(label, new_count); + const int row = labelFilters->rowFromLabel(label); + qDebug("torrentAdded, Row: %d", row); + Q_ASSERT(row >= 2); + Q_ASSERT(labelFilters->item(row)); + labelFilters->item(row)->setText(label + " ("+ QString::number(new_count) +")"); + ++nb_labeled; + } + ++nb_torrents; + Q_ASSERT(nb_torrents >= 0); + Q_ASSERT(nb_labeled >= 0); + Q_ASSERT(nb_labeled <= nb_torrents); + updateStickyLabelCounters(); +} + +void TransferListFiltersWidget::torrentAboutToBeDeleted(TorrentModelItem* torrentItem) { + Q_ASSERT(torrentItem); + QString label = torrentItem->data(TorrentModelItem::TR_LABEL).toString(); + if (!label.isEmpty()) { + // Update label counter + const int new_count = customLabels.value(label, 0) - 1; + customLabels.insert(label, new_count); + const int row = labelFilters->rowFromLabel(label); + Q_ASSERT(row >= 2); + labelFilters->item(row)->setText(label + " ("+ QString::number(new_count) +")"); + --nb_labeled; + } + --nb_torrents; + qDebug("nb_torrents: %d, nb_labeled: %d", nb_torrents, nb_labeled); + Q_ASSERT(nb_torrents >= 0); + Q_ASSERT(nb_labeled >= 0); + Q_ASSERT(nb_labeled <= nb_torrents); + updateStickyLabelCounters(); +} + +void TransferListFiltersWidget::updateStickyLabelCounters() { + labelFilters->item(0)->setText(tr("All labels") + " ("+QString::number(nb_torrents)+")"); + labelFilters->item(1)->setText(tr("Unlabeled") + " ("+QString::number(nb_torrents-nb_labeled)+")"); +} diff --git a/src/transferlistfilterswidget.h b/src/transferlistfilterswidget.h index 0a03854b6..3aa35b6ae 100644 --- a/src/transferlistfilterswidget.h +++ b/src/transferlistfilterswidget.h @@ -32,25 +32,16 @@ #define TRANSFERLISTFILTERSWIDGET_H #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include "transferlistdelegate.h" -#include "transferlistwidget.h" -#include "preferences.h" -#include "torrentmodel.h" -#include "iconprovider.h" -#include "fs_utils.h" -#include "autoexpandabledialog.h" -#include "torrentfilterenum.h" +QT_BEGIN_NAMESPACE +class QListWidgetItem; +class QVBoxLayout; +class QDragMoveEvent; +QT_END_NAMESPACE + +class TransferListWidget; +class TorrentModelItem; class LabelFiltersList: public QListWidget { Q_OBJECT @@ -59,128 +50,35 @@ private: QListWidgetItem *itemHover; public: - LabelFiltersList(QWidget *parent): QListWidget(parent) { - itemHover = 0; - // Accept drop - setAcceptDrops(true); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - setStyleSheet("QListWidget { background: transparent; border: 0 }"); -#if defined(Q_OS_MAC) - setAttribute(Qt::WA_MacShowFocusRect, false); -#endif - } + LabelFiltersList(QWidget *parent); // Redefine addItem() to make sure the list stays sorted - void addItem(QListWidgetItem *it) { - Q_ASSERT(count() >= 2); - for (int i=2; itext().localeAwareCompare(it->text()) >= 0) { - insertItem(i, it); - return; - } - } - QListWidget::addItem(it); - } + void addItem(QListWidgetItem *it); - QString labelFromRow(int row) const { - Q_ASSERT(row > 1); - const QString &label = item(row)->text(); - QStringList parts = label.split(" "); - Q_ASSERT(parts.size() >= 2); - parts.removeLast(); // Remove trailing number - return parts.join(" "); - } - - int rowFromLabel(QString label) const { - Q_ASSERT(!label.isEmpty()); - for (int i=2; ipos()) && row(itemAt(event->pos())) > 0) { - if (itemHover) { - if (itemHover != itemAt(event->pos())) { - setItemHover(false); - itemHover = itemAt(event->pos()); - setItemHover(true); - } - } else { - itemHover = itemAt(event->pos()); - setItemHover(true); - } - event->acceptProposedAction(); - } else { - if (itemHover) - setItemHover(false); - event->ignore(); - } - } - - void dropEvent(QDropEvent *event) { - qDebug("Drop Event in labels list"); - if (itemAt(event->pos())) { - emit torrentDropped(row(itemAt(event->pos()))); - } - event->ignore(); - setItemHover(false); - // Select current item again - currentItem()->setSelected(true); - } - - void dragLeaveEvent(QDragLeaveEvent*) { - if (itemHover) - setItemHover(false); - // Select current item again - currentItem()->setSelected(true); - } - - void setItemHover(bool hover) { - Q_ASSERT(itemHover); - if (hover) { - itemHover->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("folder-documents.png")); - itemHover->setSelected(true); - //setCurrentItem(itemHover); - } else { - itemHover->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory.png")); - //itemHover->setSelected(false); - itemHover = 0; - } - } + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + void dragLeaveEvent(QDragLeaveEvent*); + void setItemHover(bool hover); }; class StatusFiltersWidget : public QListWidget { Q_OBJECT public: - StatusFiltersWidget(QWidget *parent) : QListWidget(parent), m_shown(false) { - setUniformItemSizes(true); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - // Height is fixed (sizeHint().height() is used) - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - setStyleSheet("QListWidget { background: transparent; border: 0 }"); -#if defined(Q_OS_MAC) - setAttribute(Qt::WA_MacShowFocusRect, false); -#endif - } + StatusFiltersWidget(QWidget *parent); protected: - QSize sizeHint() const { - QSize size = QListWidget::sizeHint(); - // Height should be exactly the height of the content - size.setHeight(contentsSize().height() + 2 * frameWidth()+6); - return size; - } + QSize sizeHint() const; private: bool m_shown; - }; class TransferListFiltersWidget: public QFrame { @@ -196,300 +94,25 @@ private: int nb_torrents; public: - TransferListFiltersWidget(QWidget *parent, TransferListWidget *transferList): QFrame(parent), transferList(transferList), nb_labeled(0), nb_torrents(0) { - // Construct lists - vLayout = new QVBoxLayout(); - vLayout->setContentsMargins(0, 4, 0, 4); - QFont font; - font.setBold(true); - font.setCapitalization(QFont::SmallCaps); - QLabel *torrentsLabel = new QLabel(tr("Torrents")); - torrentsLabel->setIndent(2); - torrentsLabel->setFont(font); - vLayout->addWidget(torrentsLabel); - statusFilters = new StatusFiltersWidget(this); - vLayout->addWidget(statusFilters); - QLabel *labelsLabel = new QLabel(tr("Labels")); - labelsLabel->setIndent(2); - labelsLabel->setFont(font); - vLayout->addWidget(labelsLabel); - labelFilters = new LabelFiltersList(this); - vLayout->addWidget(labelFilters); - setLayout(vLayout); - labelFilters->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - statusFilters->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - statusFilters->setSpacing(0); - setContentsMargins(0,0,0,0); - vLayout->setSpacing(2); - // Add status filters - QListWidgetItem *all = new QListWidgetItem(statusFilters); - all->setData(Qt::DisplayRole, QVariant(tr("All") + " (0)")); - all->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filterall.png")); - QListWidgetItem *downloading = new QListWidgetItem(statusFilters); - downloading->setData(Qt::DisplayRole, QVariant(tr("Downloading") + " (0)")); - downloading->setData(Qt::DecorationRole, QIcon(":/Icons/skin/downloading.png")); - QListWidgetItem *completed = new QListWidgetItem(statusFilters); - completed->setData(Qt::DisplayRole, QVariant(tr("Completed") + " (0)")); - completed->setData(Qt::DecorationRole, QIcon(":/Icons/skin/uploading.png")); - QListWidgetItem *paused = new QListWidgetItem(statusFilters); - paused->setData(Qt::DisplayRole, QVariant(tr("Paused") + " (0)")); - paused->setData(Qt::DecorationRole, QIcon(":/Icons/skin/paused.png")); - QListWidgetItem *active = new QListWidgetItem(statusFilters); - active->setData(Qt::DisplayRole, QVariant(tr("Active") + " (0)")); - active->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filteractive.png")); - QListWidgetItem *inactive = new QListWidgetItem(statusFilters); - inactive->setData(Qt::DisplayRole, QVariant(tr("Inactive") + " (0)")); - inactive->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filterinactive.png")); + TransferListFiltersWidget(QWidget *parent, TransferListWidget *transferList); + ~TransferListFiltersWidget(); - // SIGNAL/SLOT - connect(statusFilters, SIGNAL(currentRowChanged(int)), transferList, SLOT(applyStatusFilter(int))); - connect(transferList->getSourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateTorrentNumbers())); - connect(transferList->getSourceModel(), SIGNAL(torrentAdded(TorrentModelItem*)), SLOT(handleNewTorrent(TorrentModelItem*))); - connect(labelFilters, SIGNAL(currentRowChanged(int)), this, SLOT(applyLabelFilter(int))); - connect(labelFilters, SIGNAL(torrentDropped(int)), this, SLOT(torrentDropped(int))); - connect(transferList->getSourceModel(), SIGNAL(torrentAboutToBeRemoved(TorrentModelItem*)), SLOT(torrentAboutToBeDeleted(TorrentModelItem*))); - connect(transferList->getSourceModel(), SIGNAL(torrentChangedLabel(TorrentModelItem*,QString,QString)), SLOT(torrentChangedLabel(TorrentModelItem*, QString, QString))); + StatusFiltersWidget* getStatusFilters() const; - // Add Label filters - QListWidgetItem *allLabels = new QListWidgetItem(labelFilters); - allLabels->setData(Qt::DisplayRole, QVariant(tr("All labels") + " (0)")); - allLabels->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); - QListWidgetItem *noLabel = new QListWidgetItem(labelFilters); - noLabel->setData(Qt::DisplayRole, QVariant(tr("Unlabeled") + " (0)")); - noLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); - - // Load settings - loadSettings(); - - labelFilters->setCurrentRow(0); - //labelFilters->selectionModel()->select(labelFilters->model()->index(0,0), QItemSelectionModel::Select); - - // Label menu - labelFilters->setContextMenuPolicy(Qt::CustomContextMenu); - connect(labelFilters, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showLabelMenu(QPoint))); - } - - ~TransferListFiltersWidget() { - saveSettings(); - delete statusFilters; - delete labelFilters; - delete vLayout; - } - - StatusFiltersWidget* getStatusFilters() const { - return statusFilters; - } - - void saveSettings() const { - Preferences* const pref = Preferences::instance(); - pref->setTransSelFilter(statusFilters->currentRow()); - pref->setTorrentLabels(customLabels.keys()); - } - - void loadSettings() { - statusFilters->setCurrentRow(Preferences::instance()->getTransSelFilter()); - const QStringList label_list = Preferences::instance()->getTorrentLabels(); - foreach (const QString &label, label_list) { - customLabels.insert(label, 0); - qDebug("Creating label QListWidgetItem: %s", qPrintable(label)); - QListWidgetItem *newLabel = new QListWidgetItem(); - newLabel->setText(label + " (0)"); - newLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); - labelFilters->addItem(newLabel); - } - } + void saveSettings() const; + void loadSettings(); protected slots: - void updateTorrentNumbers() { - const TorrentStatusReport report = transferList->getSourceModel()->getTorrentStatusReport(); - statusFilters->item(TorrentFilter::ALL)->setData(Qt::DisplayRole, QVariant(tr("All")+" ("+QString::number(report.nb_active+report.nb_inactive)+")")); - statusFilters->item(TorrentFilter::DOWNLOADING)->setData(Qt::DisplayRole, QVariant(tr("Downloading")+" ("+QString::number(report.nb_downloading)+")")); - statusFilters->item(TorrentFilter::COMPLETED)->setData(Qt::DisplayRole, QVariant(tr("Completed")+" ("+QString::number(report.nb_seeding)+")")); - statusFilters->item(TorrentFilter::PAUSED)->setData(Qt::DisplayRole, QVariant(tr("Paused")+" ("+QString::number(report.nb_paused)+")")); - statusFilters->item(TorrentFilter::ACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Active")+" ("+QString::number(report.nb_active)+")")); - statusFilters->item(TorrentFilter::INACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Inactive")+" ("+QString::number(report.nb_inactive)+")")); - } - - void torrentDropped(int row) { - Q_ASSERT(row > 0); - if (row == 1) { - transferList->setSelectionLabel(""); - } else { - transferList->setSelectionLabel(labelFilters->labelFromRow(row)); - } - } - - void addLabel(QString& label) { - label = fsutils::toValidFileSystemName(label.trimmed()); - if (label.isEmpty() || customLabels.contains(label)) return; - QListWidgetItem *newLabel = new QListWidgetItem(); - newLabel->setText(label + " (0)"); - newLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); - labelFilters->addItem(newLabel); - customLabels.insert(label, 0); - Preferences::instance()->addTorrentLabel(label); - } - - void showLabelMenu(QPoint) { - QMenu labelMenu(labelFilters); - QAction *removeAct = 0; - if (!labelFilters->selectedItems().empty() && labelFilters->row(labelFilters->selectedItems().first()) > 1) - removeAct = labelMenu.addAction(IconProvider::instance()->getIcon("list-remove"), tr("Remove label")); - QAction *addAct = labelMenu.addAction(IconProvider::instance()->getIcon("list-add"), tr("Add label...")); - labelMenu.addSeparator(); - QAction *startAct = labelMenu.addAction(IconProvider::instance()->getIcon("media-playback-start"), tr("Resume torrents")); - QAction *pauseAct = labelMenu.addAction(IconProvider::instance()->getIcon("media-playback-pause"), tr("Pause torrents")); - QAction *deleteTorrentsAct = labelMenu.addAction(IconProvider::instance()->getIcon("edit-delete"), tr("Delete torrents")); - QAction *act = 0; - act = labelMenu.exec(QCursor::pos()); - if (act) { - if (act == removeAct) { - removeSelectedLabel(); - return; - } - if (act == deleteTorrentsAct) { - transferList->deleteVisibleTorrents(); - return; - } - if (act == startAct) { - transferList->startVisibleTorrents(); - return; - } - if (act == pauseAct) { - transferList->pauseVisibleTorrents(); - return; - } - if (act == addAct) { - bool ok; - QString label = ""; - bool invalid; - do { - invalid = false; - label = AutoExpandableDialog::getText(this, tr("New Label"), tr("Label:"), QLineEdit::Normal, label, &ok); - if (ok && !label.isEmpty()) { - if (fsutils::isValidFileSystemName(label)) { - addLabel(label); - } else { - QMessageBox::warning(this, tr("Invalid label name"), tr("Please don't use any special characters in the label name.")); - invalid = true; - } - } - } while(invalid); - return; - } - } - } - - void removeSelectedLabel() { - const int row = labelFilters->row(labelFilters->selectedItems().first()); - Q_ASSERT(row > 1); - const QString &label = labelFilters->labelFromRow(row); - Q_ASSERT(customLabels.contains(label)); - customLabels.remove(label); - transferList->removeLabelFromRows(label); - // Select first label - labelFilters->setCurrentItem(labelFilters->item(0)); - labelFilters->selectionModel()->select(labelFilters->model()->index(0,0), QItemSelectionModel::Select); - applyLabelFilter(0); - // Un display filter - delete labelFilters->takeItem(row); - // Save custom labels to remember it was deleted - Preferences::instance()->removeTorrentLabel(label); - } - - void applyLabelFilter(int row) { - switch(row) { - case 0: - transferList->applyLabelFilter("all"); - break; - case 1: - transferList->applyLabelFilter("none"); - break; - default: - transferList->applyLabelFilter(labelFilters->labelFromRow(row)); - } - } - - void torrentChangedLabel(TorrentModelItem *torrentItem, QString old_label, QString new_label) { - Q_UNUSED(torrentItem); - qDebug("Torrent label changed from %s to %s", qPrintable(old_label), qPrintable(new_label)); - if (!old_label.isEmpty()) { - if (customLabels.contains(old_label)) { - const int new_count = customLabels.value(old_label, 0) - 1; - Q_ASSERT(new_count >= 0); - customLabels.insert(old_label, new_count); - const int row = labelFilters->rowFromLabel(old_label); - Q_ASSERT(row >= 2); - labelFilters->item(row)->setText(old_label + " ("+ QString::number(new_count) +")"); - } - --nb_labeled; - } - if (!new_label.isEmpty()) { - if (!customLabels.contains(new_label)) - addLabel(new_label); - const int new_count = customLabels.value(new_label, 0) + 1; - Q_ASSERT(new_count >= 1); - customLabels.insert(new_label, new_count); - const int row = labelFilters->rowFromLabel(new_label); - Q_ASSERT(row >= 2); - labelFilters->item(row)->setText(new_label + " ("+ QString::number(new_count) +")"); - ++nb_labeled; - } - updateStickyLabelCounters(); - } - - void handleNewTorrent(TorrentModelItem* torrentItem) { - QString label = torrentItem->data(TorrentModelItem::TR_LABEL).toString(); - qDebug("New torrent was added with label: %s", qPrintable(label)); - if (!label.isEmpty()) { - if (!customLabels.contains(label)) { - addLabel(label); - // addLabel may have changed the label, update the model accordingly. - torrentItem->setData(TorrentModelItem::TR_LABEL, label); - } - // Update label counter - Q_ASSERT(customLabels.contains(label)); - const int new_count = customLabels.value(label, 0) + 1; - customLabels.insert(label, new_count); - const int row = labelFilters->rowFromLabel(label); - qDebug("torrentAdded, Row: %d", row); - Q_ASSERT(row >= 2); - Q_ASSERT(labelFilters->item(row)); - labelFilters->item(row)->setText(label + " ("+ QString::number(new_count) +")"); - ++nb_labeled; - } - ++nb_torrents; - Q_ASSERT(nb_torrents >= 0); - Q_ASSERT(nb_labeled >= 0); - Q_ASSERT(nb_labeled <= nb_torrents); - updateStickyLabelCounters(); - } - - void torrentAboutToBeDeleted(TorrentModelItem* torrentItem) { - Q_ASSERT(torrentItem); - QString label = torrentItem->data(TorrentModelItem::TR_LABEL).toString(); - if (!label.isEmpty()) { - // Update label counter - const int new_count = customLabels.value(label, 0) - 1; - customLabels.insert(label, new_count); - const int row = labelFilters->rowFromLabel(label); - Q_ASSERT(row >= 2); - labelFilters->item(row)->setText(label + " ("+ QString::number(new_count) +")"); - --nb_labeled; - } - --nb_torrents; - qDebug("nb_torrents: %d, nb_labeled: %d", nb_torrents, nb_labeled); - Q_ASSERT(nb_torrents >= 0); - Q_ASSERT(nb_labeled >= 0); - Q_ASSERT(nb_labeled <= nb_torrents); - updateStickyLabelCounters(); - } - - void updateStickyLabelCounters() { - labelFilters->item(0)->setText(tr("All labels") + " ("+QString::number(nb_torrents)+")"); - labelFilters->item(1)->setText(tr("Unlabeled") + " ("+QString::number(nb_torrents-nb_labeled)+")"); - } - + void updateTorrentNumbers(); + void torrentDropped(int row); + void addLabel(QString& label); + void showLabelMenu(QPoint); + void removeSelectedLabel(); + void applyLabelFilter(int row); + void torrentChangedLabel(TorrentModelItem *torrentItem, QString old_label, QString new_label); + void handleNewTorrent(TorrentModelItem* torrentItem); + void torrentAboutToBeDeleted(TorrentModelItem* torrentItem); + void updateStickyLabelCounters(); }; #endif // TRANSFERLISTFILTERSWIDGET_H From 16eb40745314007874d242a4c76bbce69cbf9c6b Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sat, 25 Oct 2014 15:49:57 +0400 Subject: [PATCH 3/5] Split src/torrentpersistentdata into .h and .cpp --- src/addnewtorrentdialog.cpp | 1 + src/properties/propertieswidget.cpp | 1 + src/qtlibtorrent/qbtsession.cpp | 8 +- src/qtlibtorrent/qtorrenthandle.cpp | 1 + src/src.pro | 1 + src/torrentcreator/torrentcreatordlg.cpp | 1 + src/torrentpersistentdata.cpp | 440 ++++++++++++++++++++++ src/torrentpersistentdata.h | 456 +++-------------------- src/transferlistfilterswidget.cpp | 1 + src/transferlistwidget.cpp | 2 + src/webui/btjson.cpp | 2 + src/webui/jsonutils.h | 1 + 12 files changed, 510 insertions(+), 405 deletions(-) create mode 100644 src/torrentpersistentdata.cpp diff --git a/src/addnewtorrentdialog.cpp b/src/addnewtorrentdialog.cpp index 7f4383ac5..1857eea14 100644 --- a/src/addnewtorrentdialog.cpp +++ b/src/addnewtorrentdialog.cpp @@ -41,6 +41,7 @@ #include "autoexpandabledialog.h" #include "messageboxraised.h" +#include #include #include #include diff --git a/src/properties/propertieswidget.cpp b/src/properties/propertieswidget.cpp index 8ce9a7a8c..7d0669232 100644 --- a/src/properties/propertieswidget.cpp +++ b/src/properties/propertieswidget.cpp @@ -28,6 +28,7 @@ * Contact : chris@qbittorrent.org */ +#include #include #include #include diff --git a/src/qtlibtorrent/qbtsession.cpp b/src/qtlibtorrent/qbtsession.cpp index 571c9d92f..607428009 100755 --- a/src/qtlibtorrent/qbtsession.cpp +++ b/src/qtlibtorrent/qbtsession.cpp @@ -28,6 +28,7 @@ * Contact : chris@qbittorrent.org */ +#include #include #include #include @@ -73,6 +74,7 @@ #include #include #include +#include #include #include #include "dnsupdater.h" @@ -82,12 +84,6 @@ #include #endif -//initialize static member variables -QHash TorrentTempData::data = QHash(); -QHash TorrentTempData::torrentMoveStates = QHash(); -QHash HiddenData::data = QHash(); -unsigned int HiddenData::metadata_counter = 0; - using namespace libtorrent; QBtSession* QBtSession::m_instance = 0; diff --git a/src/qtlibtorrent/qtorrenthandle.cpp b/src/qtlibtorrent/qtorrenthandle.cpp index b0b725dd1..967668823 100644 --- a/src/qtlibtorrent/qtorrenthandle.cpp +++ b/src/qtlibtorrent/qtorrenthandle.cpp @@ -28,6 +28,7 @@ * Contact : chris@qbittorrent.org */ +#include #include #include #include diff --git a/src/src.pro b/src/src.pro index dbafe1467..37c9d3fc1 100644 --- a/src/src.pro +++ b/src/src.pro @@ -114,6 +114,7 @@ HEADERS += misc.h \ SOURCES += main.cpp \ downloadthread.cpp \ scannedfoldersmodel.cpp \ + torrentpersistentdata.cpp \ misc.cpp \ fs_utils.cpp \ smtp.cpp \ diff --git a/src/torrentcreator/torrentcreatordlg.cpp b/src/torrentcreator/torrentcreatordlg.cpp index ca2eda942..96743ee84 100644 --- a/src/torrentcreator/torrentcreatordlg.cpp +++ b/src/torrentcreator/torrentcreatordlg.cpp @@ -28,6 +28,7 @@ * Contact : chris@qbittorrent.org */ +#include #include #include diff --git a/src/torrentpersistentdata.cpp b/src/torrentpersistentdata.cpp new file mode 100644 index 000000000..569dcb3dc --- /dev/null +++ b/src/torrentpersistentdata.cpp @@ -0,0 +1,440 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "torrentpersistentdata.h" + +#include +#include + +#include "qinisettings.h" +#include "misc.h" +#include "qtorrenthandle.h" + +#include +#include + +QHash TorrentTempData::data = QHash(); +QHash TorrentTempData::torrentMoveStates = QHash(); +QHash HiddenData::data = QHash(); +unsigned int HiddenData::metadata_counter = 0; + +bool TorrentTempData::hasTempData(const QString &hash) { + return data.contains(hash); +} + +void TorrentTempData::deleteTempData(const QString &hash) { + data.remove(hash); +} + +void TorrentTempData::setFilesPriority(const QString &hash, const std::vector &pp) { + data[hash].files_priority = pp; +} + +void TorrentTempData::setFilesPath(const QString &hash, const QStringList &path_list) { + data[hash].path_list = path_list; +} + +void TorrentTempData::setSavePath(const QString &hash, const QString &save_path) { + data[hash].save_path = save_path; +} + +void TorrentTempData::setLabel(const QString &hash, const QString &label) { + data[hash].label = label; +} + +void TorrentTempData::setSequential(const QString &hash, const bool &sequential) { + data[hash].sequential = sequential; +} + +bool TorrentTempData::isSequential(const QString &hash) { + return data.value(hash).sequential; +} + +void TorrentTempData::setSeedingMode(const QString &hash, const bool &seed) { + data[hash].seed = seed; +} + +bool TorrentTempData::isSeedingMode(const QString &hash) { + return data.value(hash).seed; +} + +QString TorrentTempData::getSavePath(const QString &hash) { + return data.value(hash).save_path; +} + +QStringList TorrentTempData::getFilesPath(const QString &hash) { + return data.value(hash).path_list; +} + +QString TorrentTempData::getLabel(const QString &hash) { + return data.value(hash).label; +} + +void TorrentTempData::getFilesPriority(const QString &hash, std::vector &fp) { + fp = data.value(hash).files_priority; +} + +bool TorrentTempData::isMoveInProgress(const QString &hash) { + return torrentMoveStates.find(hash) != torrentMoveStates.end(); +} + +void TorrentTempData::enqueueMove(const QString &hash, const QString &queuedPath) { + QHash::iterator i = torrentMoveStates.find(hash); + if (i == torrentMoveStates.end()) { + Q_ASSERT(false); + return; + } + i->queuedPath = queuedPath; +} + +void TorrentTempData::startMove(const QString &hash, const QString &oldPath, const QString& newPath) { + QHash::iterator i = torrentMoveStates.find(hash); + if (i != torrentMoveStates.end()) { + Q_ASSERT(false); + return; + } + + torrentMoveStates.insert(hash, TorrentMoveState(oldPath, newPath)); +} + +void TorrentTempData::finishMove(const QString &hash) { + QHash::iterator i = torrentMoveStates.find(hash); + if (i == torrentMoveStates.end()) { + Q_ASSERT(false); + return; + } + torrentMoveStates.erase(i); +} + +QString TorrentTempData::getOldPath(const QString &hash) { + QHash::iterator i = torrentMoveStates.find(hash); + if (i == torrentMoveStates.end()) { + Q_ASSERT(false); + return QString(); + } + return i->oldPath; +} + +QString TorrentTempData::getNewPath(const QString &hash) { + QHash::iterator i = torrentMoveStates.find(hash); + if (i == torrentMoveStates.end()) { + Q_ASSERT(false); + return QString(); + } + return i->newPath; +} + +QString TorrentTempData::getQueuedPath(const QString &hash) { + QHash::iterator i = torrentMoveStates.find(hash); + if (i == torrentMoveStates.end()) { + Q_ASSERT(false); + return QString(); + } + return i->queuedPath; +} + +void HiddenData::addData(const QString &hash) { + data[hash] = false; +} + +bool HiddenData::hasData(const QString &hash) { + return data.contains(hash); +} + +void HiddenData::deleteData(const QString &hash) { + if (data.value(hash, false)) + metadata_counter--; + data.remove(hash); +} + +int HiddenData::getSize() { + return data.size(); +} + +int HiddenData::getDownloadingSize() { + return data.size() - metadata_counter; +} + +void HiddenData::gotMetadata(const QString &hash) { + if (!data.contains(hash)) + return; + data[hash] = true; + metadata_counter++; +} + +bool TorrentPersistentData::isKnownTorrent(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + return all_data.contains(hash); +} + +QStringList TorrentPersistentData::knownTorrents() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + return all_data.keys(); +} + +void TorrentPersistentData::setRatioLimit(const QString &hash, const qreal &ratio) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["max_ratio"] = ratio; + all_data[hash] = data; + settings.setValue("torrents", all_data); +} + +qreal TorrentPersistentData::getRatioLimit(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("max_ratio", USE_GLOBAL_RATIO).toReal(); +} + +bool TorrentPersistentData::hasPerTorrentRatioLimit() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + QHash::ConstIterator it = all_data.constBegin(); + QHash::ConstIterator itend = all_data.constEnd(); + for ( ; it != itend; ++it) { + if (it.value().toHash().value("max_ratio", USE_GLOBAL_RATIO).toReal() >= 0) { + return true; + } + } + return false; +} + +void TorrentPersistentData::setAddedDate(const QString &hash, const QDateTime &time) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + if (!data.contains("add_date")) { + data["add_date"] = time; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } +} + +QDateTime TorrentPersistentData::getAddedDate(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + QDateTime dt = data.value("add_date").toDateTime(); + if (!dt.isValid()) { + setAddedDate(hash); + dt = QDateTime::currentDateTime(); + } + return dt; +} + +void TorrentPersistentData::setErrorState(const QString &hash, const bool has_error) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["has_error"] = has_error; + all_data[hash] = data; + settings.setValue("torrents", all_data); +} + +bool TorrentPersistentData::hasError(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("has_error", false).toBool(); +} + +QDateTime TorrentPersistentData::getSeedDate(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("seed_date").toDateTime(); +} + +void TorrentPersistentData::deletePersistentData(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + if (all_data.contains(hash)) { + all_data.remove(hash); + settings.setValue("torrents", all_data); + } +} + +void TorrentPersistentData::saveTorrentPersistentData(const QTorrentHandle &h, const QString &save_path, const bool is_magnet) { + Q_ASSERT(h.is_valid()); + qDebug("Saving persistent data for %s", qPrintable(h.hash())); + // Save persistent data + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(h.hash()).toHash(); + data["is_magnet"] = is_magnet; + if (is_magnet) { + data["magnet_uri"] = misc::toQString(make_magnet_uri(h)); + } + data["seed"] = h.is_seed(); + data["priority"] = h.queue_position(); + if (save_path.isEmpty()) { + qDebug("TorrentPersistantData: save path is %s", qPrintable(h.save_path())); + data["save_path"] = h.save_path(); + } else { + qDebug("TorrentPersistantData: overriding save path is %s", qPrintable(save_path)); + data["save_path"] = save_path; // Override torrent save path (e.g. because it is a temp dir) + } + // Label + data["label"] = TorrentTempData::getLabel(h.hash()); + // Save data + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", qPrintable(h.save_path()), qPrintable(h.hash())); + // Set Added date + setAddedDate(h.hash()); + // Finally, remove temp data + TorrentTempData::deleteTempData(h.hash()); +} + +void TorrentPersistentData::saveSavePath(const QString &hash, const QString &save_path) { + Q_ASSERT(!hash.isEmpty()); + qDebug("TorrentPersistentData::saveSavePath(%s)", qPrintable(save_path)); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["save_path"] = save_path; + all_data[hash] = data; + settings.setValue("torrents", all_data); + qDebug("TorrentPersistentData: Saving save_path: %s, hash: %s", qPrintable(save_path), qPrintable(hash)); +} + +void TorrentPersistentData::saveLabel(const QString &hash, const QString &label) { + Q_ASSERT(!hash.isEmpty()); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["label"] = label; + all_data[hash] = data; + settings.setValue("torrents", all_data); +} + +void TorrentPersistentData::saveName(const QString &hash, const QString &name) { + Q_ASSERT(!hash.isEmpty()); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["name"] = name; + all_data[hash] = data; + settings.setValue("torrents", all_data); +} + +void TorrentPersistentData::savePriority(const QTorrentHandle &h) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[h.hash()].toHash(); + data["priority"] = h.queue_position(); + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); +} + +void TorrentPersistentData::savePriority(const QString &hash, const int &queue_pos) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[hash].toHash(); + data["priority"] = queue_pos; + all_data[hash] = data; + settings.setValue("torrents", all_data); +} + +void TorrentPersistentData::saveSeedStatus(const QTorrentHandle &h) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[h.hash()].toHash(); + bool was_seed = data.value("seed", false).toBool(); + if (was_seed != h.is_seed()) { + data["seed"] = !was_seed; + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + } +} + +void TorrentPersistentData::saveSeedStatus(const QString &hash, const bool seedStatus) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[hash].toHash(); + data["seed"] = seedStatus; + all_data[hash] = data; + settings.setValue("torrents", all_data); +} + +QString TorrentPersistentData::getSavePath(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + //qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toLocal8Bit().data()); + return data.value("save_path").toString(); +} + +QString TorrentPersistentData::getLabel(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("label", "").toString(); +} + +QString TorrentPersistentData::getName(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("name", "").toString(); +} + +int TorrentPersistentData::getPriority(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("priority", -1).toInt(); +} + +bool TorrentPersistentData::isSeed(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("seed", false).toBool(); +} + +bool TorrentPersistentData::isMagnet(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("is_magnet", false).toBool(); +} + +QString TorrentPersistentData::getMagnetUri(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + Q_ASSERT(data.value("is_magnet", false).toBool()); + return data.value("magnet_uri").toString(); +} diff --git a/src/torrentpersistentdata.h b/src/torrentpersistentdata.h index 130ffac01..56d02ec3a 100644 --- a/src/torrentpersistentdata.h +++ b/src/torrentpersistentdata.h @@ -31,134 +31,37 @@ #ifndef TORRENTPERSISTENTDATA_H #define TORRENTPERSISTENTDATA_H -#include #include -#include -#include -#include -#include "qtorrenthandle.h" -#include "misc.h" -#include -#include "qinisettings.h" #include +#include +#include + +class QTorrentHandle; class TorrentTempData { // This class stores strings w/o modifying separators public: - static bool hasTempData(const QString &hash) { - return data.contains(hash); - } - - static void deleteTempData(const QString &hash) { - data.remove(hash); - } - - static void setFilesPriority(const QString &hash, const std::vector &pp) { - data[hash].files_priority = pp; - } - - static void setFilesPath(const QString &hash, const QStringList &path_list) { - data[hash].path_list = path_list; - } - - static void setSavePath(const QString &hash, const QString &save_path) { - data[hash].save_path = save_path; - } - - static void setLabel(const QString &hash, const QString &label) { - data[hash].label = label; - } - - static void setSequential(const QString &hash, const bool &sequential) { - data[hash].sequential = sequential; - } - - static bool isSequential(const QString &hash) { - return data.value(hash).sequential; - } - - static void setSeedingMode(const QString &hash, const bool &seed) { - data[hash].seed = seed; - } - - static bool isSeedingMode(const QString &hash) { - return data.value(hash).seed; - } - - static QString getSavePath(const QString &hash) { - return data.value(hash).save_path; - } - - static QStringList getFilesPath(const QString &hash) { - return data.value(hash).path_list; - } - - static QString getLabel(const QString &hash) { - return data.value(hash).label; - } - - static void getFilesPriority(const QString &hash, std::vector &fp) { - fp = data.value(hash).files_priority; - } - - static bool isMoveInProgress(const QString &hash) { - return torrentMoveStates.find(hash) != torrentMoveStates.end(); - } - - static void enqueueMove(const QString &hash, const QString &queuedPath) { - QHash::iterator i = torrentMoveStates.find(hash); - if (i == torrentMoveStates.end()) { - Q_ASSERT(false); - return; - } - i->queuedPath = queuedPath; - } - - static void startMove(const QString &hash, const QString &oldPath, const QString& newPath) { - QHash::iterator i = torrentMoveStates.find(hash); - if (i != torrentMoveStates.end()) { - Q_ASSERT(false); - return; - } - - torrentMoveStates.insert(hash, TorrentMoveState(oldPath, newPath)); - } - - static void finishMove(const QString &hash) { - QHash::iterator i = torrentMoveStates.find(hash); - if (i == torrentMoveStates.end()) { - Q_ASSERT(false); - return; - } - torrentMoveStates.erase(i); - } - - static QString getOldPath(const QString &hash) { - QHash::iterator i = torrentMoveStates.find(hash); - if (i == torrentMoveStates.end()) { - Q_ASSERT(false); - return QString(); - } - return i->oldPath; - } - - static QString getNewPath(const QString &hash) { - QHash::iterator i = torrentMoveStates.find(hash); - if (i == torrentMoveStates.end()) { - Q_ASSERT(false); - return QString(); - } - return i->newPath; - } - - static QString getQueuedPath(const QString &hash) { - QHash::iterator i = torrentMoveStates.find(hash); - if (i == torrentMoveStates.end()) { - Q_ASSERT(false); - return QString(); - } - return i->queuedPath; - } + static bool hasTempData(const QString &hash); + static void deleteTempData(const QString &hash); + static void setFilesPriority(const QString &hash, const std::vector &pp); + static void setFilesPath(const QString &hash, const QStringList &path_list); + static void setSavePath(const QString &hash, const QString &save_path); + static void setLabel(const QString &hash, const QString &label); + static void setSequential(const QString &hash, const bool &sequential); + static bool isSequential(const QString &hash); + static void setSeedingMode(const QString &hash, const bool &seed); + static bool isSeedingMode(const QString &hash); + static QString getSavePath(const QString &hash); + static QStringList getFilesPath(const QString &hash); + static QString getLabel(const QString &hash); + static void getFilesPriority(const QString &hash, std::vector &fp); + static bool isMoveInProgress(const QString &hash); + static void enqueueMove(const QString &hash, const QString &queuedPath); + static void startMove(const QString &hash, const QString &oldPath, const QString& newPath); + static void finishMove(const QString &hash); + static QString getOldPath(const QString &hash); + static QString getNewPath(const QString &hash); + static QString getQueuedPath(const QString &hash); private: struct TorrentData { @@ -190,34 +93,12 @@ private: class HiddenData { public: - static void addData(const QString &hash) { - data[hash] = false; - } - - static bool hasData(const QString &hash) { - return data.contains(hash); - } - - static void deleteData(const QString &hash) { - if (data.value(hash, false)) - metadata_counter--; - data.remove(hash); - } - - static int getSize() { - return data.size(); - } - - static int getDownloadingSize() { - return data.size() - metadata_counter; - } - - static void gotMetadata(const QString &hash) { - if (!data.contains(hash)) - return; - data[hash] = true; - metadata_counter++; - } + static void addData(const QString &hash); + static bool hasData(const QString &hash); + static void deleteData(const QString &hash); + static int getSize(); + static int getDownloadingSize(); + static void gotMetadata(const QString &hash); private: static QHash data; @@ -233,259 +114,36 @@ public: }; public: - static bool isKnownTorrent(QString hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - return all_data.contains(hash); - } - - static QStringList knownTorrents() { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - return all_data.keys(); - } - - static void setRatioLimit(const QString &hash, const qreal &ratio) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(hash).toHash(); - data["max_ratio"] = ratio; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } - - static qreal getRatioLimit(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("max_ratio", USE_GLOBAL_RATIO).toReal(); - } - - static bool hasPerTorrentRatioLimit() { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - QHash::ConstIterator it = all_data.constBegin(); - QHash::ConstIterator itend = all_data.constEnd(); - for ( ; it != itend; ++it) { - if (it.value().toHash().value("max_ratio", USE_GLOBAL_RATIO).toReal() >= 0) { - return true; - } - } - return false; - } - - static void setAddedDate(const QString &hash, const QDateTime &time = QDateTime::currentDateTime()) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(hash).toHash(); - if (!data.contains("add_date")) { - data["add_date"] = time; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } - } - - static QDateTime getAddedDate(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - QDateTime dt = data.value("add_date").toDateTime(); - if (!dt.isValid()) { - setAddedDate(hash); - dt = QDateTime::currentDateTime(); - } - return dt; - } - - static void setErrorState(const QString &hash, const bool has_error) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(hash).toHash(); - data["has_error"] = has_error; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } - - static bool hasError(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("has_error", false).toBool(); - } - - static QDateTime getSeedDate(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("seed_date").toDateTime(); - } - - static void deletePersistentData(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - if (all_data.contains(hash)) { - all_data.remove(hash); - settings.setValue("torrents", all_data); - } - } - - static void saveTorrentPersistentData(const QTorrentHandle &h, const QString &save_path = QString::null, const bool is_magnet = false) { - Q_ASSERT(h.is_valid()); - qDebug("Saving persistent data for %s", qPrintable(h.hash())); - // Save persistent data - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(h.hash()).toHash(); - data["is_magnet"] = is_magnet; - if (is_magnet) { - data["magnet_uri"] = misc::toQString(make_magnet_uri(h)); - } - data["seed"] = h.is_seed(); - data["priority"] = h.queue_position(); - if (save_path.isEmpty()) { - qDebug("TorrentPersistantData: save path is %s", qPrintable(h.save_path())); - data["save_path"] = h.save_path(); - } else { - qDebug("TorrentPersistantData: overriding save path is %s", qPrintable(save_path)); - data["save_path"] = save_path; // Override torrent save path (e.g. because it is a temp dir) - } - // Label - data["label"] = TorrentTempData::getLabel(h.hash()); - // Save data - all_data[h.hash()] = data; - settings.setValue("torrents", all_data); - qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", qPrintable(h.save_path()), qPrintable(h.hash())); - // Set Added date - setAddedDate(h.hash()); - // Finally, remove temp data - TorrentTempData::deleteTempData(h.hash()); - } + static bool isKnownTorrent(QString hash); + static QStringList knownTorrents(); + static void setRatioLimit(const QString &hash, const qreal &ratio); + static qreal getRatioLimit(const QString &hash); + static bool hasPerTorrentRatioLimit() ; + static void setAddedDate(const QString &hash, const QDateTime &time = QDateTime::currentDateTime()); + static QDateTime getAddedDate(const QString &hash); + static void setErrorState(const QString &hash, const bool has_error); + static bool hasError(const QString &hash); + static QDateTime getSeedDate(const QString &hash); + static void deletePersistentData(const QString &hash); + static void saveTorrentPersistentData(const QTorrentHandle &h, const QString &save_path = QString::null, const bool is_magnet = false); // Setters - - static void saveSavePath(const QString &hash, const QString &save_path) { - Q_ASSERT(!hash.isEmpty()); - qDebug("TorrentPersistentData::saveSavePath(%s)", qPrintable(save_path)); - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(hash).toHash(); - data["save_path"] = save_path; - all_data[hash] = data; - settings.setValue("torrents", all_data); - qDebug("TorrentPersistentData: Saving save_path: %s, hash: %s", qPrintable(save_path), qPrintable(hash)); - } - - static void saveLabel(const QString &hash, const QString &label) { - Q_ASSERT(!hash.isEmpty()); - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(hash).toHash(); - data["label"] = label; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } - - static void saveName(const QString &hash, const QString &name) { - Q_ASSERT(!hash.isEmpty()); - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data.value(hash).toHash(); - data["name"] = name; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } - - static void savePriority(const QTorrentHandle &h) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data[h.hash()].toHash(); - data["priority"] = h.queue_position(); - all_data[h.hash()] = data; - settings.setValue("torrents", all_data); - } - - static void savePriority(const QString &hash, const int &queue_pos) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data[hash].toHash(); - data["priority"] = queue_pos; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } - - static void saveSeedStatus(const QTorrentHandle &h) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data[h.hash()].toHash(); - bool was_seed = data.value("seed", false).toBool(); - if (was_seed != h.is_seed()) { - data["seed"] = !was_seed; - all_data[h.hash()] = data; - settings.setValue("torrents", all_data); - } - } - - static void saveSeedStatus(const QString &hash, const bool seedStatus) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - QHash all_data = settings.value("torrents").toHash(); - QHash data = all_data[hash].toHash(); - data["seed"] = seedStatus; - all_data[hash] = data; - settings.setValue("torrents", all_data); - } + static void saveSavePath(const QString &hash, const QString &save_path); + static void saveLabel(const QString &hash, const QString &label); + static void saveName(const QString &hash, const QString &name); + static void savePriority(const QTorrentHandle &h); + static void savePriority(const QString &hash, const int &queue_pos); + static void saveSeedStatus(const QTorrentHandle &h); + static void saveSeedStatus(const QString &hash, const bool seedStatus); // Getters - static QString getSavePath(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - //qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toLocal8Bit().data()); - return data.value("save_path").toString(); - } - - static QString getLabel(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("label", "").toString(); - } - - static QString getName(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("name", "").toString(); - } - - static int getPriority(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("priority", -1).toInt(); - } - - static bool isSeed(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("seed", false).toBool(); - } - - static bool isMagnet(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - return data.value("is_magnet", false).toBool(); - } - - static QString getMagnetUri(const QString &hash) { - QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); - const QHash all_data = settings.value("torrents").toHash(); - const QHash data = all_data.value(hash).toHash(); - Q_ASSERT(data.value("is_magnet", false).toBool()); - return data.value("magnet_uri").toString(); - } - + static QString getSavePath(const QString &hash); + static QString getLabel(const QString &hash); + static QString getName(const QString &hash); + static int getPriority(const QString &hash); + static bool isSeed(const QString &hash); + static bool isMagnet(const QString &hash); + static QString getMagnetUri(const QString &hash); }; #endif // TORRENTPERSISTENTDATA_H diff --git a/src/transferlistfilterswidget.cpp b/src/transferlistfilterswidget.cpp index b3d553f6f..21618c429 100644 --- a/src/transferlistfilterswidget.cpp +++ b/src/transferlistfilterswidget.cpp @@ -30,6 +30,7 @@ #include "transferlistfilterswidget.h" +#include #include #include #include diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index e98fa2bf5..6b22ca885 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -28,6 +28,7 @@ * Contact : chris@qbittorrent.org */ +#include #include #include #include @@ -42,6 +43,7 @@ #include #include +#include #include #include diff --git a/src/webui/btjson.cpp b/src/webui/btjson.cpp index 735e68893..4272e1650 100644 --- a/src/webui/btjson.cpp +++ b/src/webui/btjson.cpp @@ -35,6 +35,8 @@ #include "torrentpersistentdata.h" #include "jsonutils.h" +#include +#include #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) #include #endif diff --git a/src/webui/jsonutils.h b/src/webui/jsonutils.h index b08cfb0d8..82c720579 100644 --- a/src/webui/jsonutils.h +++ b/src/webui/jsonutils.h @@ -31,6 +31,7 @@ #ifndef JSONUTILS_H #define JSONUTILS_H +#include #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #include #include From 8f0d49bb1bf0b4f61e7c6b212af3023e354ff490 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sat, 25 Oct 2014 16:11:18 +0400 Subject: [PATCH 4/5] Remove default argument from TorrentPersistentData::setAddedDate() --- src/torrentpersistentdata.cpp | 5 +++-- src/torrentpersistentdata.h | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/torrentpersistentdata.cpp b/src/torrentpersistentdata.cpp index 569dcb3dc..5144a7a4c 100644 --- a/src/torrentpersistentdata.cpp +++ b/src/torrentpersistentdata.cpp @@ -30,6 +30,7 @@ #include "torrentpersistentdata.h" +#include #include #include @@ -247,7 +248,7 @@ QDateTime TorrentPersistentData::getAddedDate(const QString &hash) { const QHash data = all_data.value(hash).toHash(); QDateTime dt = data.value("add_date").toDateTime(); if (!dt.isValid()) { - setAddedDate(hash); + setAddedDate(hash, QDateTime::currentDateTime()); dt = QDateTime::currentDateTime(); } return dt; @@ -312,7 +313,7 @@ void TorrentPersistentData::saveTorrentPersistentData(const QTorrentHandle &h, c settings.setValue("torrents", all_data); qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", qPrintable(h.save_path()), qPrintable(h.hash())); // Set Added date - setAddedDate(h.hash()); + setAddedDate(h.hash(), QDateTime::currentDateTime()); // Finally, remove temp data TorrentTempData::deleteTempData(h.hash()); } diff --git a/src/torrentpersistentdata.h b/src/torrentpersistentdata.h index 56d02ec3a..b5ef335bb 100644 --- a/src/torrentpersistentdata.h +++ b/src/torrentpersistentdata.h @@ -31,11 +31,14 @@ #ifndef TORRENTPERSISTENTDATA_H #define TORRENTPERSISTENTDATA_H -#include #include #include #include +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + class QTorrentHandle; class TorrentTempData { @@ -119,7 +122,7 @@ public: static void setRatioLimit(const QString &hash, const qreal &ratio); static qreal getRatioLimit(const QString &hash); static bool hasPerTorrentRatioLimit() ; - static void setAddedDate(const QString &hash, const QDateTime &time = QDateTime::currentDateTime()); + static void setAddedDate(const QString &hash, const QDateTime &time); static QDateTime getAddedDate(const QString &hash); static void setErrorState(const QString &hash, const bool has_error); static bool hasError(const QString &hash); From 9771cb796c0d9fe60f4c28e41e7879ba3f92f6e1 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 2 Nov 2014 15:35:57 +0300 Subject: [PATCH 5/5] Unused include --- src/torrentpersistentdata.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/torrentpersistentdata.cpp b/src/torrentpersistentdata.cpp index 5144a7a4c..bb562214b 100644 --- a/src/torrentpersistentdata.cpp +++ b/src/torrentpersistentdata.cpp @@ -38,7 +38,6 @@ #include "misc.h" #include "qtorrenthandle.h" -#include #include QHash TorrentTempData::data = QHash();