From 8fbaca61b1ac36de43064c62dd328c7ba2031d8d Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sun, 23 Mar 2008 12:16:18 +0000 Subject: [PATCH] * Refactoring to change the DownloadList events to commands. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1046 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_download.cc | 21 ++++++++++++++++--- src/command_helpers.h | 14 +++++++++++++ src/command_ui.cc | 12 +++++++++++ src/core/download_list.cc | 14 +++++++++++++ src/core/manager.cc | 26 +++-------------------- src/core/manager.h | 4 ++++ src/core/view.cc | 43 ++++++++++++++++++++++++++++++++++----- src/core/view.h | 3 +++ src/main.cc | 12 +++++------ src/ui/download_list.cc | 22 ++++++++++++-------- src/ui/download_list.h | 4 ++-- 11 files changed, 127 insertions(+), 48 deletions(-) diff --git a/src/command_download.cc b/src/command_download.cc index 6d6b1f7d..d55be354 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -245,6 +245,18 @@ retrieve_d_local_id_html(core::Download* download) { return torrent::Object(rak::copy_escape_html(hashString->begin(), hashString->end())); } +// Just a helper function atm. +torrent::Object +cmd_d_initialize_logs(core::Download* download) { + download->download()->signal_network_log(sigc::mem_fun(control->core(), &core::Manager::push_log_complete)); + download->download()->signal_storage_error(sigc::mem_fun(control->core(), &core::Manager::push_log_complete)); + + if (!rpc::call_command_string("get_tracker_dump").empty()) + download->download()->signal_tracker_dump(sigc::ptr_fun(&core::receive_tracker_dump)); + + return torrent::Object(); +} + torrent::Object f_multicall(core::Download* download, const torrent::Object& rawArgs) { const torrent::Object::list_type& args = rawArgs.as_list(); @@ -530,7 +542,10 @@ initialize_command_download() { ADD_CD_VALUE_BI("priority", std::mem_fun(&core::Download::set_priority), std::mem_fun(&core::Download::priority)); ADD_CD_STRING_UNI("priority_str", std::ptr_fun(&retrieve_d_priority_str)); - ADD_CD_SLOT_PUBLIC("f.multicall", call_list, rak::ptr_fn(&f_multicall), "i:", "") - ADD_CD_SLOT_PUBLIC("p.multicall", call_list, rak::ptr_fn(&p_multicall), "i:", "") - ADD_CD_SLOT_PUBLIC("t.multicall", call_list, rak::ptr_fn(&t_multicall), "i:", "") + ADD_CD_SLOT_PUBLIC("f.multicall", call_list, rak::ptr_fn(&f_multicall), "i:", ""); + ADD_CD_SLOT_PUBLIC("p.multicall", call_list, rak::ptr_fn(&p_multicall), "i:", ""); + ADD_CD_SLOT_PUBLIC("t.multicall", call_list, rak::ptr_fn(&t_multicall), "i:", ""); + + // NEWISH: + CMD_D_VOID("d.initialize_logs", &cmd_d_initialize_logs); } diff --git a/src/command_helpers.h b/src/command_helpers.h index ae9bcffa..b659d641 100644 --- a/src/command_helpers.h +++ b/src/command_helpers.h @@ -171,4 +171,18 @@ add_variable(key, NULL, NULL, &rpc::CommandVariable::get_string, NULL, std::stri #define ADD_COMMAND_NONE_L(key, slot) \ ADD_COMMAND_SLOT(key, call_unknown, slot, "A:", "") +// +// DOWNLOAD RELATED COMMANDS +// + +#define CMD_D_SLOT(key, function, slot, parm, doc) \ + commandDownloadSlotsItr->set_slot(slot); \ + rpc::commands.insert_type(key, commandDownloadSlotsItr++, &rpc::CommandSlot::function, rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, parm, doc); + +#define CMD_D_ANY_NONE(key, slot) \ + CMD_D_SLOT(key, call_unknown, slot, "i:", "") + +#define CMD_D_VOID(key, slot) \ + CMD_D_SLOT(key, call_unknown, rpc::object_fn(slot), "i:", "") + #endif diff --git a/src/command_ui.cc b/src/command_ui.cc index b180d064..5a45f388 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -378,6 +378,13 @@ apply_if(int flags, rpc::target_type target, const torrent::Object& rawArgs) { } } +torrent::Object +cmd_ui_unfocus_download(core::Download* download, const torrent::Object& rawArgs) { + control->ui()->download_list()->unfocus_download(download); + + return torrent::Object(); +} + void initialize_command_ui() { ADD_VARIABLE_STRING("key_layout", "qwerty"); @@ -396,6 +403,11 @@ initialize_command_ui() { ADD_COMMAND_LIST("view_event_added", rak::bind_ptr_fn(&apply_view_cfilter, &core::ViewManager::set_event_added)); ADD_COMMAND_LIST("view_event_removed", rak::bind_ptr_fn(&apply_view_cfilter, &core::ViewManager::set_event_removed)); + // Commands that affect the default rtorrent UI. + +// ADD_ANY_NONE("ui.focus", rak::ptr_fn(&cmd_ui_focus)); + CMD_D_ANY_NONE("ui.unfocus_download", rak::ptr_fn(&cmd_ui_unfocus_download)); + // Move. ADD_ANY_NONE("print", rak::ptr_fn(&apply_print)); diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 3a09a707..fb1cb753 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -54,6 +54,8 @@ #include "control.h" #include "globals.h" #include "manager.h" +#include "view.h" +#include "view_manager.h" #include "dht_manager.h" #include "download.h" @@ -315,6 +317,9 @@ DownloadList::start_normal(Download* download) { download->set_hash_failed(false); rpc::call_command("d.set_state", (int64_t)1, rpc::make_target(download)); + (*control->view_manager()->find_throw("stopped"))->set_not_visible(download); + (*control->view_manager()->find_throw("started"))->set_visible(download); + resume(download); } @@ -332,6 +337,9 @@ DownloadList::start_try(Download* download) { // etc. rpc::call_command("d.set_state", (int64_t)1, rpc::make_target(download)); + (*control->view_manager()->find_throw("stopped"))->set_not_visible(download); + (*control->view_manager()->find_throw("started"))->set_visible(download); + resume(download); return true; } @@ -342,6 +350,9 @@ DownloadList::stop_normal(Download* download) { rpc::call_command("d.set_state", (int64_t)0, rpc::make_target(download)); + (*control->view_manager()->find_throw("started"))->set_not_visible(download); + (*control->view_manager()->find_throw("stopped"))->set_visible(download); + pause(download); } @@ -354,6 +365,9 @@ DownloadList::stop_try(Download* download) { rpc::call_command("d.set_state", (int64_t)0, rpc::make_target(download)); + (*control->view_manager()->find_throw("started"))->set_not_visible(download); + (*control->view_manager()->find_throw("stopped"))->set_visible(download); + pause(download); return true; } diff --git a/src/core/manager.cc b/src/core/manager.cc index 7f115b50..3a61d97a 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -74,24 +74,7 @@ namespace core { -static void -connect_signal_network_log(Download* d, torrent::Download::slot_string_type s) { - d->download()->signal_network_log(s); -} - -static void -connect_signal_storage_log(Download* d, torrent::Download::slot_string_type s) { - d->download()->signal_storage_error(s); -} - -// Need a proper logging class for this. -static void -connect_signal_tracker_dump(Download* d, torrent::Download::slot_dump_type s) { - if (!rpc::call_command_string("get_tracker_dump").empty()) - d->download()->signal_tracker_dump(s); -} - -static void +void receive_tracker_dump(const std::string& url, const char* data, size_t size) { const std::string& filename = rpc::call_command_string("get_tracker_dump"); @@ -229,11 +212,8 @@ Manager::initialize_second() { // Register slots to be called when a download is inserted/erased, // opened or closed. - m_downloadList->slot_map_insert()["1_connect_network_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_network_log), sigc::mem_fun(m_logComplete, &Log::push_front)); - m_downloadList->slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front)); - m_downloadList->slot_map_insert()["1_connect_tracker_dump"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_dump), sigc::ptr_fun(&receive_tracker_dump)); - - m_downloadList->slot_map_erase()["9_delete_tied"] = sigc::bind<0>(&rpc::call_command_d_v_void, "d.delete_tied"); + m_downloadList->slot_map_insert()["1_connect_logs"] = sigc::bind(&rpc::parse_command_d_single_std, "d.initialize_logs="); + m_downloadList->slot_map_erase()["9_delete_tied"] = sigc::bind(&rpc::parse_command_d_single_std, "d.delete_tied="); torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log)); } diff --git a/src/core/manager.h b/src/core/manager.h index 77f18f6d..e656aa09 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -103,6 +103,7 @@ public: void push_log(const char* msg); void push_log_std(const std::string& msg) { m_logImportant.push_front(msg); m_logComplete.push_front(msg); } + void push_log_complete(const std::string& msg) { m_logComplete.push_front(msg); } void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); @@ -139,6 +140,9 @@ private: Log m_logComplete; }; +// Meh, cleanup. +extern void receive_tracker_dump(const std::string& url, const char* data, size_t size); + } #endif diff --git a/src/core/view.cc b/src/core/view.cc index 74fec0b0..9f2d1c24 100644 --- a/src/core/view.cc +++ b/src/core/view.cc @@ -86,6 +86,36 @@ View::initialize(const std::string& name, core::DownloadList* dlist) { set_last_changed(rak::timer()); } +void +View::set_visible(Download* download) { + iterator itr = std::find(begin_filtered(), end_filtered(), download); + + if (itr == end_filtered()) + return; + + // Don't optimize erase since we want to keep the order of the + // non-visible elements. + base_type::erase(itr); + insert_visible(download); + + rpc::parse_command_multiple_d_nothrow(download, m_eventAdded); +} + +void +View::set_not_visible(Download* download) { + iterator itr = std::find(begin_visible(), end_visible(), download); + + if (itr == end_visible()) + return; + + // Don't optimize erase since we want to keep the order of the + // non-visible elements. + base_type::erase(itr); + base_type::push_back(download); + + rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved); +} + void View::next_focus() { if (empty()) @@ -253,6 +283,7 @@ View::received(core::Download* download, int event) { } else { base_type::insert(end_filtered(), download); + return; } if (m_focus > m_size) @@ -261,6 +292,11 @@ View::received(core::Download* download, int event) { break; case DownloadList::SLOTS_ERASE: + if (itr >= end_visible()) { + erase(itr); + return; + } + erase(itr); rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved); @@ -273,17 +309,14 @@ View::received(core::Download* download, int event) { if (view_downloads_filter(m_filter)(download)) { if (itr >= end_visible()) { - // Erase even if it is in visible so that the download is - // re-sorted. - // - // This isn't the best solution... erase(itr); insert_visible(download); rpc::parse_command_multiple_d_nothrow(download, m_eventAdded); } else { - // Should we really sort it here, or just return? + // This makes sure the download is sorted even if it is + // already visible. erase(itr); insert_visible(download); } diff --git a/src/core/view.h b/src/core/view.h index dab8795e..b24503fb 100644 --- a/src/core/view.h +++ b/src/core/view.h @@ -102,6 +102,9 @@ public: const_iterator focus() const { return begin() + m_focus; } void set_focus(iterator itr) { m_focus = position(itr); m_signalChanged.emit(); } + void set_visible(Download* download); + void set_not_visible(Download* download); + void next_focus(); void prev_focus(); diff --git a/src/main.cc b/src/main.cc index 415292fa..b1b5d2da 100644 --- a/src/main.cc +++ b/src/main.cc @@ -185,15 +185,15 @@ main(int argc, char** argv) { "view_add = started\n" "view_filter = started,d.get_state=\n" - "view_filter_on = started,start,stop\n" - "view_sort_new = started,less=d.get_name=\n" - "view_sort_current = started,less=d.get_name=\n" +// "view_filter_on = started,start,stop\n" +// "view_sort_new = started,less=d.get_name=\n" +// "view_sort_current = started,less=d.get_name=\n" "view_add = stopped\n" "view_filter = stopped,not=$d.get_state=\n" - "view_filter_on = stopped,start,stop\n" - "view_sort_new = stopped,less=d.get_name=\n" - "view_sort_current = stopped,less=d.get_name=\n" +// "view_filter_on = stopped,start,stop\n" +// "view_sort_new = stopped,less=d.get_name=\n" +// "view_sort_current = stopped,less=d.get_name=\n" "view_add = complete\n" "view_filter = complete,d.get_complete=\n" diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index 8ec98d16..94918e33 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -98,7 +98,7 @@ DownloadList::activate(display::Frame* frame, bool focus) { m_frame = frame; control->input()->push_back(&m_bindings); - control->core()->download_list()->slot_map_erase()["0_download_list"] = sigc::mem_fun(this, &DownloadList::receive_download_erased); + control->core()->download_list()->slot_map_erase()["0_download_list"] = sigc::bind(&rpc::parse_command_d_single_std, "ui.unfocus_download="); activate_display(DISPLAY_DOWNLOAD_LIST); } @@ -121,6 +121,18 @@ DownloadList::current_view() { return dynamic_cast(m_uiArray[DISPLAY_DOWNLOAD_LIST])->view(); } +// This should also do focus_next() or something. +void +DownloadList::unfocus_download(core::Download* d) { + if (current_view()->focus() >= current_view()->end_visible() || *current_view()->focus() != d) + return; + + if (m_state == DISPLAY_DOWNLOAD) + activate_display(DISPLAY_DOWNLOAD_LIST); + + current_view()->next_focus(); +} + void DownloadList::activate_display(Display displayType) { if (!is_active()) @@ -316,14 +328,6 @@ DownloadList::receive_exit_input(Input type) { delete input; } -void -DownloadList::receive_download_erased(core::Download* d) { - if (m_state != DISPLAY_DOWNLOAD || current_view()->focus() == current_view()->end_visible() || *current_view()->focus() != d) - return; - - activate_display(DISPLAY_DOWNLOAD_LIST); -} - void DownloadList::setup_keys() { m_bindings['\x7f'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_DEFAULT); diff --git a/src/ui/download_list.h b/src/ui/download_list.h index 0464726f..a485fc17 100644 --- a/src/ui/download_list.h +++ b/src/ui/download_list.h @@ -104,6 +104,8 @@ public: void slot_open_uri(SlotOpenUri s) { m_slotOpenUri = s; } + void unfocus_download(core::Download* d); + private: DownloadList(const DownloadList&); void operator = (const DownloadList&); @@ -111,8 +113,6 @@ private: void receive_view_input(Input type); void receive_exit_input(Input type); - void receive_download_erased(core::Download* d); - void setup_keys(); void setup_input();