diff --git a/README b/README index 71a4ab2f..78367c1e 100644 --- a/README +++ b/README @@ -40,7 +40,7 @@ In torrent view: Left - Back to main - Right - View peer + Right - View files 1 - Decrease max uploads 2 - Increase max uploads @@ -51,4 +51,12 @@ In torrent view: 5 - Decrease max peers connected 6 - Increase max peers connected - T - Query tracker \ No newline at end of file + T - Query tracker + +In file view: + + Up/Down - Select file + + Left - Back to torrent view + + SpaceBar - Change file priority diff --git a/src/core/curl_stack.cc b/src/core/curl_stack.cc index ca8ff968..73dc8b73 100644 --- a/src/core/curl_stack.cc +++ b/src/core/curl_stack.cc @@ -41,7 +41,7 @@ CurlStack::perform() { CURLMsg* msg = curl_multi_info_read((CURLM*)m_handle, &t); CurlGetList::iterator itr = std::find_if(m_getList.begin(), m_getList.end(), - func::equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); + utils::equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); if (itr == m_getList.end()) throw torrent::client_error("Could not find CurlGet with the right easy_handle"); diff --git a/src/core/download_list.cc b/src/core/download_list.cc index bde65232..f1a2fa90 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -32,7 +32,7 @@ DownloadList::erase(iterator itr) { void DownloadList::clear() { - std::for_each(begin(), end(), func::call_delete()); + std::for_each(begin(), end(), utils::call_delete()); Base::clear(); } diff --git a/src/core/hash_queue.cc b/src/core/hash_queue.cc index 6ea2605a..c5c9e0c5 100644 --- a/src/core/hash_queue.cc +++ b/src/core/hash_queue.cc @@ -15,7 +15,7 @@ HashQueue::insert(Download* d, Slot s) { if (d->get_download().is_hash_checking()) return; - if (std::find_if(begin(), end(), func::equal(d, std::mem_fun(&HashQueueNode::get_download))) != end()) + if (std::find_if(begin(), end(), utils::equal(d, std::mem_fun(&HashQueueNode::get_download))) != end()) throw std::logic_error("core::HashQueue::insert(...) received a Download that is already queued"); if (d->get_download().is_hash_checked()) { @@ -32,7 +32,7 @@ HashQueue::insert(Download* d, Slot s) { void HashQueue::remove(Download* d) { - iterator itr = std::find_if(begin(), end(), func::equal(d, std::mem_fun(&HashQueueNode::get_download))); + iterator itr = std::find_if(begin(), end(), utils::equal(d, std::mem_fun(&HashQueueNode::get_download))); if (itr == end()) return; diff --git a/src/core/log.cc b/src/core/log.cc index 5a915b2f..f1deee4b 100644 --- a/src/core/log.cc +++ b/src/core/log.cc @@ -17,7 +17,7 @@ Log::push_front(const std::string& msg) { Log::iterator Log::find_older(utils::Timer t) { return std::find_if(begin(), end(), - func::on(func::mem_ptr_ref(&Type::first), std::bind2nd(std::less_equal(), t))); + utils::on(utils::mem_ptr_ref(&Type::first), std::bind2nd(std::less_equal(), t))); } } diff --git a/src/display/manager.cc b/src/display/manager.cc index 58cfbf5c..63aa9143 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -26,8 +26,8 @@ Manager::adjust_layout() { int countDynamic = 0; int staticHeight = 0; - std::for_each(begin(), end(), func::if_then(std::mem_fun(&Window::is_active), func::accumulate(staticHeight, std::mem_fun(&Window::get_min_height)))); - std::for_each(begin(), end(), func::if_then(std::mem_fun(&Window::is_active), func::accumulate(countDynamic, std::mem_fun(&Window::is_dynamic)))); + std::for_each(begin(), end(), utils::if_then(std::mem_fun(&Window::is_active), utils::accumulate(staticHeight, std::mem_fun(&Window::get_min_height)))); + std::for_each(begin(), end(), utils::if_then(std::mem_fun(&Window::is_active), utils::accumulate(countDynamic, std::mem_fun(&Window::is_dynamic)))); int dynamic = std::max(0, Canvas::get_screen_height() - staticHeight); int height = 0, h; @@ -56,9 +56,9 @@ void Manager::do_update() { Canvas::refresh_std(); - std::for_each(begin(), end(), func::if_then(std::mem_fun(&Window::is_active), func::if_then(std::mem_fun(&Window::is_dirty), + std::for_each(begin(), end(), utils::if_then(std::mem_fun(&Window::is_active), utils::if_then(std::mem_fun(&Window::is_dirty), std::mem_fun(&Window::redraw)))); - std::for_each(begin(), end(), func::if_then(std::mem_fun(&Window::is_active), std::mem_fun(&Window::refresh))); + std::for_each(begin(), end(), utils::if_then(std::mem_fun(&Window::is_active), std::mem_fun(&Window::refresh))); Canvas::do_update(); } diff --git a/src/display/window_file_list.cc b/src/display/window_file_list.cc index e4738fd1..0e017fad 100644 --- a/src/display/window_file_list.cc +++ b/src/display/window_file_list.cc @@ -6,7 +6,7 @@ namespace display { -WindowFileList::WindowFileList(core::Download* d, int* focus) : +WindowFileList::WindowFileList(core::Download* d, unsigned int* focus) : Window(new Canvas, true), m_download(d), m_focus(focus) { @@ -27,8 +27,8 @@ WindowFileList::redraw() { ++y1; - int files = m_download->get_download().get_entry_size(); - int index = std::min(std::max(*m_focus - (y2 - y1) / 2, 0), files - (y2 - y1)); + unsigned int files = m_download->get_download().get_entry_size(); + unsigned int index = std::min(std::max((int)*m_focus - (y2 - y1) / 2, 0), (int)files - (y2 - y1)); while (index < files && y1 < y2) { torrent::Entry e = m_download->get_download().get_entry(index); diff --git a/src/display/window_file_list.h b/src/display/window_file_list.h index 30e71578..e6ff1383 100644 --- a/src/display/window_file_list.h +++ b/src/display/window_file_list.h @@ -17,7 +17,7 @@ namespace display { class WindowFileList : public Window { public: - WindowFileList(core::Download* d, int* focus); + WindowFileList(core::Download* d, unsigned int* focus); virtual void redraw(); @@ -26,7 +26,7 @@ private: core::Download* m_download; - int* m_focus; + unsigned int* m_focus; }; } diff --git a/src/display/window_http_queue.cc b/src/display/window_http_queue.cc index 074cb922..7fc1fa8b 100644 --- a/src/display/window_http_queue.cc +++ b/src/display/window_http_queue.cc @@ -105,7 +105,7 @@ WindowHttpQueue::receive_insert(core::CurlGet* h) { void WindowHttpQueue::receive_erase(core::CurlGet* h) { Container::iterator itr = std::find_if(m_container.begin(), m_container.end(), - func::equal(h, std::mem_fun_ref(&Node::get_http))); + utils::equal(h, std::mem_fun_ref(&Node::get_http))); if (itr == m_container.end()) throw std::logic_error("WindowHttpQueue::receive_erase(...) tried to remove an object we don't have"); diff --git a/src/display/window_peer_list.cc b/src/display/window_peer_list.cc index b2bccec3..fa551a77 100644 --- a/src/display/window_peer_list.cc +++ b/src/display/window_peer_list.cc @@ -3,6 +3,7 @@ #include #include "core/download.h" +#include "utils/algorithm.h" #include "canvas.h" #include "window_peer_list.h" diff --git a/src/main.cc b/src/main.cc index 26843fad..7e0debf4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -193,7 +193,8 @@ void print_help() { std::cout << "Rakshasa's Torrent client. " << std::endl; std::cout << std::endl; - std::cout << "All value pairs (f.ex rate and queue size) will be in the UP/DOWN order." << std::endl; + std::cout << "All value pairs (f.ex rate and queue size) will be in the UP/DOWN" << std::endl; + std::cout << "order. Use the up/down/left/right arrow keys to move between screens." << std::endl; std::cout << std::endl; std::cout << "Usage: rtorrent [OPTIONS]... [FILE]... [URL]..." << std::endl; std::cout << " -h Display this very helpful text" << std::endl; @@ -209,9 +210,11 @@ print_help() { std::cout << " a,s,d,z,x,c Adjust throttle" << std::endl; std::cout << std::endl; std::cout << "Download view keys:" << std::endl; + std::cout << " spacebar Depends on the current view" << std::endl; std::cout << " 1,2 Adjust max uploads" << std::endl; std::cout << " 3,4,5,6 Adjust min/max connected peers" << std::endl; std::cout << " t Query tracker for more peers" << std::endl; + std::cout << " p View peer information" << std::endl; std::cout << std::endl; std::cout << "Report bugs to ." << std::endl; diff --git a/src/ui/download.cc b/src/ui/download.cc index b688eeeb..af48464e 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -104,8 +104,8 @@ Download::activate_display(Display d) { case DISPLAY_MAIN: *m_window = wpl = new WPeerList(m_download, &m_peers, &m_focus); - (*m_bindings)[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER); - (*m_bindings)['p'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_FILE_LIST); + (*m_bindings)['p'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER); + (*m_bindings)[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_FILE_LIST); break; case DISPLAY_PEER: @@ -116,8 +116,8 @@ Download::activate_display(Display d) { case DISPLAY_FILE_LIST: m_uiFileList->activate(m_window); + m_uiFileList->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_MAIN); - (*m_bindings)[' '] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_MAIN); break; default: @@ -145,7 +145,6 @@ Download::disable_display() { case DISPLAY_FILE_LIST: m_uiFileList->disable(); - m_bindings->erase(' '); *m_window = NULL; return; diff --git a/src/ui/file_list.cc b/src/ui/file_list.cc index c0837a32..56ad8e8f 100644 --- a/src/ui/file_list.cc +++ b/src/ui/file_list.cc @@ -15,6 +15,7 @@ FileList::FileList(Control* c, core::Download* d) : m_control(c), m_focus(0) { + m_bindings[' '] = sigc::mem_fun(*this, &FileList::receive_priority); m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &FileList::receive_next); m_bindings[KEY_UP] = sigc::mem_fun(*this, &FileList::receive_prev); } @@ -45,7 +46,7 @@ FileList::receive_next() { if (m_window == NULL) throw std::logic_error("ui::FileList::receive_next(...) called on a disabled object"); - if (++m_focus >= (int)m_download->get_download().get_entry_size()) + if (++m_focus >= m_download->get_download().get_entry_size()) m_focus = 0; m_window->mark_dirty(); @@ -56,8 +57,44 @@ FileList::receive_prev() { if (m_window == NULL) throw std::logic_error("ui::FileList::receive_prev(...) called on a disabled object"); - if (--m_focus < 0) - m_focus = std::max(0, (int)m_download->get_download().get_entry_size() - 1); + if (m_download->get_download().get_entry_size() == 0) + return; + + if (m_focus != 0) + --m_focus; + else + m_focus = m_download->get_download().get_entry_size() - 1; + + m_window->mark_dirty(); +} + +void +FileList::receive_priority() { + if (m_window == NULL) + throw std::logic_error("ui::FileList::receive_prev(...) called on a disabled object"); + + if (m_focus >= m_download->get_download().get_entry_size()) + return; + + torrent::Entry e = m_download->get_download().get_entry(m_focus); + + switch (e.get_priority()) { + case torrent::Entry::STOPPED: + e.set_priority(torrent::Entry::HIGH); + break; + + case torrent::Entry::NORMAL: + e.set_priority(torrent::Entry::STOPPED); + break; + + case torrent::Entry::HIGH: + e.set_priority(torrent::Entry::NORMAL); + break; + + default: + e.set_priority(torrent::Entry::NORMAL); + break; + }; m_window->mark_dirty(); } diff --git a/src/ui/file_list.h b/src/ui/file_list.h index d4decfe5..7c1885ea 100644 --- a/src/ui/file_list.h +++ b/src/ui/file_list.h @@ -23,10 +23,14 @@ public: void activate(MItr mItr); void disable(); + input::Bindings& get_bindings() { return m_bindings; } + private: void receive_next(); void receive_prev(); + void receive_priority(); + core::Download* m_download; WFileList* m_window; @@ -34,7 +38,7 @@ private: input::Bindings m_bindings; // Change to unsigned, please. - int m_focus; + unsigned int m_focus; }; } diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index 0bc35760..194296ad 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libsub_utils.a libsub_utils_a_SOURCES = \ + algorithm.h \ directory.cc \ directory.h \ functional.h \ diff --git a/src/utils/algorithm.h b/src/utils/algorithm.h new file mode 100644 index 00000000..a540968c --- /dev/null +++ b/src/utils/algorithm.h @@ -0,0 +1,23 @@ +#ifndef RTORRENT_UTILS_ALGORITHM_H +#define RTORRENT_UTILS_ALGORITHM_H + +#include + +namespace utils { + +template +_Function for_each_pre(_InputIter __first, _InputIter __last, _Function __f) { + _InputIter __tmp; + + while (__first != __last) { + __tmp = first++; + + __f(*__tmp); + } + + return __f; +} + +} + +#endif diff --git a/src/utils/functional.h b/src/utils/functional.h index a4fbbe38..9011876e 100644 --- a/src/utils/functional.h +++ b/src/utils/functional.h @@ -1,20 +1,9 @@ -#ifndef RTORRENT_FUNCTIONAL_H -#define RTORRENT_FUNCTIONAL_H +#ifndef RTORRENT_UTILS_FUNCTIONAL_H +#define RTORRENT_UTILS_FUNCTIONAL_H #include -namespace func { - -template -inline void for_each(Iterator first, Iterator last, Ftor ftor) { - Iterator tmp; - - while (first != last) { - tmp = first++; - - ftor(*tmp); - } -} +namespace utils { template struct _accumulate {