FEATURE: Added "Added/Completed On" columns to transfer list

This commit is contained in:
Christophe Dumez 2010-01-30 16:28:07 +00:00
parent ba27191b2a
commit fb79146ae6
6 changed files with 128 additions and 60 deletions

View file

@ -1,7 +1,7 @@
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0 * Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0
- FEATURE: User can set alternative speed limits for fast toggling - FEATURE: User can set alternative speed limits for fast toggling
- FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period) - 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 <chris@qbittorrent.org> - v2.1.0 * Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
- FEATURE: Graphical User Interface can be disabled at compilation time (headless running) - FEATURE: Graphical User Interface can be disabled at compilation time (headless running)

View file

@ -1948,6 +1948,8 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(h.is_valid()){ if(h.is_valid()){
QString hash = h.hash(); QString hash = h.hash();
qDebug("%s have just finished checking", hash.toLocal8Bit().data()); qDebug("%s have just finished checking", hash.toLocal8Bit().data());
// Save seed status
TorrentPersistentData::saveSeedStatus(h);
// Move to temp directory if necessary // Move to temp directory if necessary
if(!h.is_seed() && !defaultTempPath.isEmpty()) { if(!h.is_seed() && !defaultTempPath.isEmpty()) {
// Check if directory is different // Check if directory is different

View file

@ -494,6 +494,8 @@ void QTorrentHandle::prioritize_files(std::vector<int> v) {
if(v.size() != (unsigned int)h.get_torrent_info().num_files()) if(v.size() != (unsigned int)h.get_torrent_info().num_files())
return; return;
h.prioritize_files(v); h.prioritize_files(v);
// Save seed status
TorrentPersistentData::saveSeedStatus(*this);
} }
void QTorrentHandle::set_ratio(float ratio) const { 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 { void QTorrentHandle::file_priority(int index, int priority) const {
Q_ASSERT(h.is_valid()); Q_ASSERT(h.is_valid());
h.file_priority(index, priority); h.file_priority(index, priority);
// Save seed status
TorrentPersistentData::saveSeedStatus(*this);
} }
#ifdef LIBTORRENT_0_15 #ifdef LIBTORRENT_0_15

View file

@ -202,6 +202,48 @@ public:
return all_data.keys(); return all_data.keys();
} }
static void setAddedDate(QString hash) {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
QHash<QString, QVariant> 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<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
QHash<QString, QVariant> 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<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
QHash<QString, QVariant> 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<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
QHash<QString, QVariant> data = all_data[hash].toHash();
return data.value("seed_date", QDateTime()).toDateTime();
}
static void deletePersistentData(QString hash) { static void deletePersistentData(QString hash) {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash(); QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
@ -232,6 +274,8 @@ public:
all_data[h.hash()] = data; all_data[h.hash()] = data;
settings.setValue("torrents", all_data); settings.setValue("torrents", all_data);
qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", h.save_path().toLocal8Bit().data(), h.hash().toLocal8Bit().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 // Setters
@ -283,6 +327,8 @@ public:
data["seed"] = h.is_seed(); data["seed"] = h.is_seed();
all_data[h.hash()] = data; all_data[h.hash()] = data;
settings.setValue("torrents", all_data); settings.setValue("torrents", all_data);
// Save completion date
saveSeedDate(h);
} }
// Getters // Getters

View file

@ -42,7 +42,7 @@
// Defines for download list list columns // 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 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 { class TransferListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
@ -83,78 +83,83 @@ public:
int state = index.data().toInt(); int state = index.data().toInt();
QString display = ""; QString display = "";
switch(state) { switch(state) {
case STATE_DOWNLOADING: case STATE_DOWNLOADING:
display = tr("Downloading"); display = tr("Downloading");
break; break;
case STATE_PAUSED_DL: case STATE_PAUSED_DL:
case STATE_PAUSED_UP: case STATE_PAUSED_UP:
display = tr("Paused"); display = tr("Paused");
break; break;
case STATE_QUEUED_DL: case STATE_QUEUED_DL:
case STATE_QUEUED_UP: case STATE_QUEUED_UP:
display = tr("Queued", "i.e. torrent is queued"); display = tr("Queued", "i.e. torrent is queued");
break; break;
case STATE_SEEDING: case STATE_SEEDING:
case STATE_STALLED_UP: case STATE_STALLED_UP:
display = tr("Seeding", "Torrent is complete and in upload-only mode"); display = tr("Seeding", "Torrent is complete and in upload-only mode");
break; break;
case STATE_STALLED_DL: case STATE_STALLED_DL:
display = tr("Stalled", "Torrent is waiting for download to begin"); display = tr("Stalled", "Torrent is waiting for download to begin");
break; break;
case STATE_CHECKING_DL: case STATE_CHECKING_DL:
case STATE_CHECKING_UP: case STATE_CHECKING_UP:
display = tr("Checking", "Torrent local data is being checked"); display = tr("Checking", "Torrent local data is being checked");
} }
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
QItemDelegate::drawDisplay(painter, opt, opt.rect, display); QItemDelegate::drawDisplay(painter, opt, opt.rect, display);
break; break;
} }
case TR_UPSPEED: case TR_UPSPEED:
case TR_DLSPEED:{ case TR_DLSPEED:{
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
qulonglong speed = index.data().toULongLong(); qulonglong speed = index.data().toULongLong();
opt.displayAlignment = Qt::AlignRight; opt.displayAlignment = Qt::AlignRight;
QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)")); QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)"));
break; break;
} }
case TR_RATIO:{ case TR_ADD_DATE:
QItemDelegate::drawBackground(painter, opt, index); case TR_SEED_DATE:
opt.displayAlignment = Qt::AlignRight; QItemDelegate::drawBackground(painter, opt, index);
double ratio = index.data().toDouble(); QItemDelegate::drawDisplay(painter, opt, opt.rect, index.data().toDateTime().toLocalTime().toString(Qt::DefaultLocaleShortDate));
if(ratio > 100.) break;
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("")); case TR_RATIO:{
else QItemDelegate::drawBackground(painter, opt, index);
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1)); opt.displayAlignment = Qt::AlignRight;
break; double ratio = index.data().toDouble();
} if(ratio > 100.)
case TR_PRIORITY: { QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8(""));
int priority = index.data().toInt(); else
if(priority >= 0) { QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1));
opt.displayAlignment = Qt::AlignRight; break;
QItemDelegate::paint(painter, opt, index); }
} else { case TR_PRIORITY: {
QItemDelegate::drawBackground(painter, opt, index); int priority = index.data().toInt();
opt.displayAlignment = Qt::AlignRight; if(priority >= 0) {
QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); opt.displayAlignment = Qt::AlignRight;
} QItemDelegate::paint(painter, opt, index);
break; } else {
} QItemDelegate::drawBackground(painter, opt, index);
case TR_PROGRESS:{ opt.displayAlignment = Qt::AlignRight;
QStyleOptionProgressBarV2 newopt; QItemDelegate::drawDisplay(painter, opt, opt.rect, "*");
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);
} }
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 { QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const {

View file

@ -59,7 +59,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, GUI *main_window, Bittor
setItemDelegate(listDelegate); setItemDelegate(listDelegate);
// Create transfer list model // 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_NAME, Qt::Horizontal, tr("Name", "i.e: torrent name"));
listModel->setHeaderData(TR_PRIORITY, Qt::Horizontal, "#"); listModel->setHeaderData(TR_PRIORITY, Qt::Horizontal, "#");
listModel->horizontalHeaderItem(TR_PRIORITY)->setTextAlignment(Qt::AlignRight); 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->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_ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
listModel->setHeaderData(TR_LABEL, Qt::Horizontal, tr("Label")); 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 // Set Sort/Filter proxy
labelFilterModel = new QSortFilterProxyModel(); 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_ETA), QVariant((qlonglong)-1));
listModel->setData(listModel->index(row, TR_SEEDS), QVariant((double)0.0)); 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_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()); QString label = TorrentPersistentData::getLabel(h.hash());
listModel->setData(listModel->index(row, TR_LABEL), QVariant(label)); listModel->setData(listModel->index(row, TR_LABEL), QVariant(label));
if(BTSession->isQueueingEnabled()) 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_DLSPEED), QVariant((double)0.));
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)1.)); 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_PRIORITY), QVariant((int)-1));
listModel->setData(listModel->index(row, TR_SEED_DATE), QVariant(TorrentPersistentData::getSeedDate(h.hash())));
} }
} catch(invalid_handle e) { } catch(invalid_handle e) {
if(row >= 0) { if(row >= 0) {
@ -799,6 +805,7 @@ void TransferListWidget::saveHiddenColumns() {
for(short i=0; i<nbColumns; ++i){ for(short i=0; i<nbColumns; ++i){
if(isColumnHidden(i)) { if(isColumnHidden(i)) {
qDebug("Column named %s is hidden.", listModel->headerData(i, Qt::Horizontal).toString().toLocal8Bit().data());
ishidden_list << "0"; ishidden_list << "0";
} else { } else {
ishidden_list << "1"; ishidden_list << "1";
@ -810,8 +817,7 @@ void TransferListWidget::saveHiddenColumns() {
// load the previous settings, and hide the columns // load the previous settings, and hide the columns
bool TransferListWidget::loadHiddenColumns() { bool TransferListWidget::loadHiddenColumns() {
QSettings settings("qBittorrent", "qBittorrent"); QSettings settings("qBittorrent", "qBittorrent");
QString line = settings.value("TransferListColsHoS", QString()).toString(); QString line = settings.value("TransferListColsHoS", "").toString();
if(line.isEmpty()) return false;
bool loaded = false; bool loaded = false;
QStringList ishidden_list; QStringList ishidden_list;
ishidden_list = line.split(' '); ishidden_list = line.split(' ');
@ -824,6 +830,11 @@ bool TransferListWidget::loadHiddenColumns() {
} }
loaded = true; loaded = true;
} }
// As a default, hide date columns
if(!loaded) {
setColumnHidden(TR_ADD_DATE, true);
setColumnHidden(TR_SEED_DATE, true);
}
return loaded; return loaded;
} }