From fb79146ae6a63920f3ffe404e4f5f132c92849d8 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sat, 30 Jan 2010 16:28:07 +0000 Subject: [PATCH] FEATURE: Added "Added/Completed On" columns to transfer list --- Changelog | 2 +- src/bittorrent.cpp | 2 + src/qtorrenthandle.cpp | 4 ++ src/torrentpersistentdata.h | 46 ++++++++++++++ src/transferlistdelegate.h | 117 +++++++++++++++++++----------------- src/transferlistwidget.cpp | 17 +++++- 6 files changed, 128 insertions(+), 60 deletions(-) diff --git a/Changelog b/Changelog index ee2a09224..e0d129c42 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,7 @@ * Unreleased - Christophe Dumez - v2.2.0 - FEATURE: User can set alternative speed limits for fast toggling - FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period) - - FEATURE: Added back file prioritizing in a torrent + - FEATURE: Added "Added/Completed On" columns to transfer list * Mon Jan 18 2010 - Christophe Dumez - v2.1.0 - FEATURE: Graphical User Interface can be disabled at compilation time (headless running) diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 6f0ec8fd2..7a9645032 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -1948,6 +1948,8 @@ void Bittorrent::addConsoleMessage(QString msg, QString) { if(h.is_valid()){ QString hash = h.hash(); qDebug("%s have just finished checking", hash.toLocal8Bit().data()); + // Save seed status + TorrentPersistentData::saveSeedStatus(h); // Move to temp directory if necessary if(!h.is_seed() && !defaultTempPath.isEmpty()) { // Check if directory is different diff --git a/src/qtorrenthandle.cpp b/src/qtorrenthandle.cpp index 9bdabf1ba..16e274834 100644 --- a/src/qtorrenthandle.cpp +++ b/src/qtorrenthandle.cpp @@ -494,6 +494,8 @@ void QTorrentHandle::prioritize_files(std::vector v) { if(v.size() != (unsigned int)h.get_torrent_info().num_files()) return; h.prioritize_files(v); + // Save seed status + TorrentPersistentData::saveSeedStatus(*this); } void QTorrentHandle::set_ratio(float ratio) const { @@ -551,6 +553,8 @@ void QTorrentHandle::move_storage(QString new_path) const { void QTorrentHandle::file_priority(int index, int priority) const { Q_ASSERT(h.is_valid()); h.file_priority(index, priority); + // Save seed status + TorrentPersistentData::saveSeedStatus(*this); } #ifdef LIBTORRENT_0_15 diff --git a/src/torrentpersistentdata.h b/src/torrentpersistentdata.h index afebbd1a0..3c82dffc8 100644 --- a/src/torrentpersistentdata.h +++ b/src/torrentpersistentdata.h @@ -202,6 +202,48 @@ public: return all_data.keys(); } + static void setAddedDate(QString hash) { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents", QHash()).toHash(); + QHash data = all_data[hash].toHash(); + if(!data.contains("add_date")) { + data.insert("add_date", QDateTime::currentDateTime()); + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + } + + static QDateTime getAddedDate(QString hash) { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents", QHash()).toHash(); + QHash data = all_data[hash].toHash(); + QDateTime dt = data.value("add_date", QDateTime()).toDateTime(); + if(!dt.isValid()) { + setAddedDate(hash); + dt = QDateTime::currentDateTime(); + } + return dt; + } + + static void saveSeedDate(QTorrentHandle h) { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents", QHash()).toHash(); + QHash data = all_data[h.hash()].toHash(); + if(h.is_seed()) + data.insert("seed_date", QDateTime::currentDateTime()); + else + data.insert("seed_date", QDateTime()); + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + } + + static QDateTime getSeedDate(QString hash) { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents", QHash()).toHash(); + QHash data = all_data[hash].toHash(); + return data.value("seed_date", QDateTime()).toDateTime(); + } + static void deletePersistentData(QString hash) { QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); QHash all_data = settings.value("torrents", QHash()).toHash(); @@ -232,6 +274,8 @@ public: all_data[h.hash()] = data; settings.setValue("torrents", all_data); qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", h.save_path().toLocal8Bit().data(), h.hash().toLocal8Bit().data()); + // Set Added date + setAddedDate(h.hash()); } // Setters @@ -283,6 +327,8 @@ public: data["seed"] = h.is_seed(); all_data[h.hash()] = data; settings.setValue("torrents", all_data); + // Save completion date + saveSeedDate(h); } // Getters diff --git a/src/transferlistdelegate.h b/src/transferlistdelegate.h index 84eb9be8c..62a203616 100644 --- a/src/transferlistdelegate.h +++ b/src/transferlistdelegate.h @@ -42,7 +42,7 @@ // Defines for download list list columns enum TorrentState {STATE_DOWNLOADING, STATE_STALLED_DL, STATE_STALLED_UP, STATE_SEEDING, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_INVALID}; -enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_HASH}; +enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_HASH}; class TransferListDelegate: public QItemDelegate { Q_OBJECT @@ -83,78 +83,83 @@ public: int state = index.data().toInt(); QString display = ""; switch(state) { - case STATE_DOWNLOADING: + case STATE_DOWNLOADING: display = tr("Downloading"); break; - case STATE_PAUSED_DL: - case STATE_PAUSED_UP: + case STATE_PAUSED_DL: + case STATE_PAUSED_UP: display = tr("Paused"); break; - case STATE_QUEUED_DL: - case STATE_QUEUED_UP: + case STATE_QUEUED_DL: + case STATE_QUEUED_UP: display = tr("Queued", "i.e. torrent is queued"); break; - case STATE_SEEDING: - case STATE_STALLED_UP: + case STATE_SEEDING: + case STATE_STALLED_UP: display = tr("Seeding", "Torrent is complete and in upload-only mode"); break; - case STATE_STALLED_DL: + case STATE_STALLED_DL: display = tr("Stalled", "Torrent is waiting for download to begin"); break; - case STATE_CHECKING_DL: - case STATE_CHECKING_UP: + case STATE_CHECKING_DL: + case STATE_CHECKING_UP: display = tr("Checking", "Torrent local data is being checked"); } QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawDisplay(painter, opt, opt.rect, display); break; } - case TR_UPSPEED: - case TR_DLSPEED:{ - QItemDelegate::drawBackground(painter, opt, index); - 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 TR_RATIO:{ - QItemDelegate::drawBackground(painter, opt, index); - opt.displayAlignment = Qt::AlignRight; - double ratio = index.data().toDouble(); - if(ratio > 100.) - QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞")); - else - QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1)); - break; - } - case TR_PRIORITY: { - int priority = index.data().toInt(); - if(priority >= 0) { - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::paint(painter, opt, index); - } else { - QItemDelegate::drawBackground(painter, opt, index); - opt.displayAlignment = Qt::AlignRight; - QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); - } - break; - } - case TR_PROGRESS:{ - QStyleOptionProgressBarV2 newopt; - double progress = index.data().toDouble()*100.; - newopt.rect = opt.rect; - newopt.text = QString::number(progress, 'f', 1)+"%"; - newopt.progress = (int)progress; - newopt.maximum = 100; - newopt.minimum = 0; - newopt.state |= QStyle::State_Enabled; - newopt.textVisible = true; - QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); - break; - } - default: - QItemDelegate::paint(painter, option, index); + case TR_UPSPEED: + case TR_DLSPEED:{ + QItemDelegate::drawBackground(painter, opt, index); + 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 TR_ADD_DATE: + case TR_SEED_DATE: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, opt.rect, index.data().toDateTime().toLocalTime().toString(Qt::DefaultLocaleShortDate)); + break; + case TR_RATIO:{ + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + double ratio = index.data().toDouble(); + if(ratio > 100.) + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞")); + else + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1)); + break; + } + case TR_PRIORITY: { + int priority = index.data().toInt(); + if(priority >= 0) { + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::paint(painter, opt, index); + } else { + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); } + break; + } + case TR_PROGRESS:{ + QStyleOptionProgressBarV2 newopt; + double progress = index.data().toDouble()*100.; + newopt.rect = opt.rect; + newopt.text = QString::number(progress, 'f', 1)+"%"; + newopt.progress = (int)progress; + newopt.maximum = 100; + newopt.minimum = 0; + newopt.state |= QStyle::State_Enabled; + newopt.textVisible = true; + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); + break; + } + default: + QItemDelegate::paint(painter, option, index); + } } QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index 1afffa979..7fafb7177 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -59,7 +59,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, GUI *main_window, Bittor setItemDelegate(listDelegate); // Create transfer list model - listModel = new QStandardItemModel(0,13); + listModel = new QStandardItemModel(0,15); listModel->setHeaderData(TR_NAME, Qt::Horizontal, tr("Name", "i.e: torrent name")); listModel->setHeaderData(TR_PRIORITY, Qt::Horizontal, "#"); listModel->horizontalHeaderItem(TR_PRIORITY)->setTextAlignment(Qt::AlignRight); @@ -80,6 +80,9 @@ TransferListWidget::TransferListWidget(QWidget *parent, GUI *main_window, Bittor listModel->horizontalHeaderItem(TR_RATIO)->setTextAlignment(Qt::AlignRight); listModel->setHeaderData(TR_ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left")); listModel->setHeaderData(TR_LABEL, Qt::Horizontal, tr("Label")); + listModel->setHeaderData(TR_ADD_DATE, Qt::Horizontal, tr("Added on", "Torrent was added to transfer list on 01/01/2010 08:00")); + listModel->setHeaderData(TR_SEED_DATE, Qt::Horizontal, tr("Completed on", "Torrent was completed on 01/01/2010 08:00")); + // Set Sort/Filter proxy labelFilterModel = new QSortFilterProxyModel(); @@ -163,6 +166,8 @@ void TransferListWidget::addTorrent(QTorrentHandle& h) { listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)-1)); listModel->setData(listModel->index(row, TR_SEEDS), QVariant((double)0.0)); listModel->setData(listModel->index(row, TR_PEERS), QVariant((double)0.0)); + listModel->setData(listModel->index(row, TR_ADD_DATE), QVariant(TorrentPersistentData::getAddedDate(h.hash()))); + listModel->setData(listModel->index(row, TR_SEED_DATE), QVariant(TorrentPersistentData::getSeedDate(h.hash()))); QString label = TorrentPersistentData::getLabel(h.hash()); listModel->setData(listModel->index(row, TR_LABEL), QVariant(label)); if(BTSession->isQueueingEnabled()) @@ -429,6 +434,7 @@ void TransferListWidget::setFinished(QTorrentHandle &h) { listModel->setData(listModel->index(row, TR_DLSPEED), QVariant((double)0.)); listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)1.)); listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)-1)); + listModel->setData(listModel->index(row, TR_SEED_DATE), QVariant(TorrentPersistentData::getSeedDate(h.hash()))); } } catch(invalid_handle e) { if(row >= 0) { @@ -799,6 +805,7 @@ void TransferListWidget::saveHiddenColumns() { for(short i=0; iheaderData(i, Qt::Horizontal).toString().toLocal8Bit().data()); ishidden_list << "0"; } else { ishidden_list << "1"; @@ -810,8 +817,7 @@ void TransferListWidget::saveHiddenColumns() { // load the previous settings, and hide the columns bool TransferListWidget::loadHiddenColumns() { QSettings settings("qBittorrent", "qBittorrent"); - QString line = settings.value("TransferListColsHoS", QString()).toString(); - if(line.isEmpty()) return false; + QString line = settings.value("TransferListColsHoS", "").toString(); bool loaded = false; QStringList ishidden_list; ishidden_list = line.split(' '); @@ -824,6 +830,11 @@ bool TransferListWidget::loadHiddenColumns() { } loaded = true; } + // As a default, hide date columns + if(!loaded) { + setColumnHidden(TR_ADD_DATE, true); + setColumnHidden(TR_SEED_DATE, true); + } return loaded; }