diff --git a/Changelog b/Changelog index 0934d6b4c..aa289dfed 100644 --- a/Changelog +++ b/Changelog @@ -17,7 +17,7 @@ - FEATURE: Display trackers status as well as error/warning messages - FEATURE: Display the number of peers returned by each tracker & DHT - FEATURE: Global upload/download speeds can be capped from status bar (µTorrent behavior) - - FEATURE: Added option to download first and last piece of a torrent first (for preview) + - FEATURE: Added option to download first and last piece of a torrent main file first (for preview) - FEATURE: Dropped Qt 4.3 support (Qt >= 4.4 is now required) - FEATURE: Added per-torrent super seeding mode (libtorrent >= v0.15 only) - FEATURE: Support for storing symbolic links in .torrent files (libtorrent >= v0.15 only) diff --git a/src/qtorrenthandle.cpp b/src/qtorrenthandle.cpp index 6f5656cdf..5f13eaaaa 100644 --- a/src/qtorrenthandle.cpp +++ b/src/qtorrenthandle.cpp @@ -33,9 +33,11 @@ #include #include #include +#include #include "misc.h" #include "qtorrenthandle.h" #include +#include QTorrentHandle::QTorrentHandle(torrent_handle h): h(h) {} @@ -136,7 +138,31 @@ void QTorrentHandle::get_peer_info(std::vector& v) const { bool QTorrentHandle::first_last_piece_first() const { Q_ASSERT(h.is_valid()); - return (h.piece_priority(0) == 7) && (h.piece_priority(h.get_torrent_info().num_pieces()-1) == 7); + // Detect main file + int rank=0; + int main_file_index = 0; + file_entry main_file = h.get_torrent_info().file_at(0); + torrent_info::file_iterator it = h.get_torrent_info().begin_files(); + it++; ++rank; + while(it != h.get_torrent_info().end_files()) { + if(it->size > main_file.size) { + main_file = *it; + main_file_index = rank; + } + it++; + ++rank; + } + qDebug("Main file in the torrent is %s", main_file.path.string().c_str()); + int piece_size = h.get_torrent_info().piece_length(); + Q_ASSERT(piece_size>0); + int first_piece = floor((main_file.offset+1)/(double)piece_size); + Q_ASSERT(first_piece >= 0 && first_piece < h.get_torrent_info().num_pieces()); + qDebug("First piece of the file is %d/%d", first_piece, h.get_torrent_info().num_pieces()-1); + int num_pieces_in_file = ceil(main_file.size/(double)piece_size); + int last_piece = first_piece+num_pieces_in_file-1; + Q_ASSERT(last_piece >= 0 && last_piece < h.get_torrent_info().num_pieces()); + qDebug("last piece of the file is %d/%d", last_piece, h.get_torrent_info().num_pieces()-1); + return (h.piece_priority(first_piece) == 7) && (h.piece_priority(last_piece) == 7); } size_type QTorrentHandle::total_wanted_done() const { @@ -539,10 +565,36 @@ void QTorrentHandle::add_tracker(announce_entry const& url) { void QTorrentHandle::prioritize_first_last_piece(bool b) { Q_ASSERT(h.is_valid()); - int prio = 1; - if(b) prio = 7; - h.piece_priority(0, prio); - h.piece_priority(h.get_torrent_info().num_pieces()-1, prio); + // Detect main file + int rank=0; + int main_file_index = 0; + file_entry main_file = h.get_torrent_info().file_at(0); + torrent_info::file_iterator it = h.get_torrent_info().begin_files(); + it++; ++rank; + while(it != h.get_torrent_info().end_files()) { + if(it->size > main_file.size) { + main_file = *it; + main_file_index = rank; + } + it++; + ++rank; + } + qDebug("Main file in the torrent is %s", main_file.path.string().c_str()); + // Determine the priority to set + int prio = 7; // MAX + if(!b) prio = h.file_priority(main_file_index); + // Determine the first and last piece of the main file + int piece_size = h.get_torrent_info().piece_length(); + Q_ASSERT(piece_size>0); + int first_piece = floor((main_file.offset+1)/(double)piece_size); + Q_ASSERT(first_piece >= 0 && first_piece < h.get_torrent_info().num_pieces()); + qDebug("First piece of the file is %d/%d", first_piece, h.get_torrent_info().num_pieces()-1); + int num_pieces_in_file = ceil(main_file.size/(double)piece_size); + int last_piece = first_piece+num_pieces_in_file-1; + Q_ASSERT(last_piece >= 0 && last_piece < h.get_torrent_info().num_pieces()); + qDebug("last piece of the file is %d/%d", last_piece, h.get_torrent_info().num_pieces()-1); + h.piece_priority(first_piece, prio); + h.piece_priority(last_piece, prio); } // diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index d465ded96..269b4d03e 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -782,7 +782,7 @@ void TransferListWidget::displayListMenu(const QPoint&) { bool has_pause = false, has_start = false, has_preview = false; bool all_same_super_seeding = true, all_same_sequential_download_mode = true, all_same_prio_firstlast = true; bool super_seeding_mode = false, sequential_download_mode = false, prioritize_first_last = false; - bool one_has_metadata = false, one_not_seed = false, one_has_single_file = false;; + bool one_has_metadata = false, one_not_seed = false; bool first = true; QTorrentHandle h; qDebug("Displaying menu"); @@ -807,7 +807,6 @@ void TransferListWidget::displayListMenu(const QPoint&) { all_same_prio_firstlast = false; } } - if(h.num_files() == 1) one_has_single_file = true; } else { if(!one_not_seed && all_same_super_seeding) { if(first) { @@ -870,7 +869,7 @@ void TransferListWidget::displayListMenu(const QPoint&) { listMenu.addAction(&actionSequential_download); added_preview_action = true; } - if(all_same_prio_firstlast && one_has_single_file) { + if(all_same_prio_firstlast) { QIcon ico; if(prioritize_first_last) { ico = QIcon(":/Icons/oxygen/button_ok.png");