* Made pause/resume trigger on insertion into the started queue.

git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1047 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2008-03-24 19:30:56 +00:00
parent 8fbaca61b1
commit e8e5ef337b
11 changed files with 193 additions and 183 deletions
+2
View File
@@ -431,6 +431,8 @@ initialize_command_download() {
ADD_CD_F_VOID("start", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::start_normal));
ADD_CD_F_VOID("stop", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::stop_normal));
ADD_CD_F_VOID("resume", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::resume_default));
ADD_CD_F_VOID("pause", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::pause_default));
ADD_CD_F_VOID("open", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::open_throw));
ADD_CD_F_VOID("close", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::close_throw));
ADD_CD_F_VOID("erase", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::erase_ptr));
+1 -1
View File
@@ -73,7 +73,7 @@ apply_on_state_change(core::DownloadList::slot_map* slotMap, const torrent::Obje
if (args.size() == 1)
slotMap->erase(key);
else
(*slotMap)[key] = sigc::bind(sigc::ptr_fun(&rpc::parse_command_d_multiple_std), args.back().as_string());
(*slotMap)[key] = args.back().as_string();
return torrent::Object();
}
+4 -1
View File
@@ -179,9 +179,12 @@ add_variable(key, NULL, NULL, &rpc::CommandVariable::get_string, NULL, std::stri
commandDownloadSlotsItr->set_slot(slot); \
rpc::commands.insert_type(key, commandDownloadSlotsItr++, &rpc::CommandSlot<core::Download*>::function, rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, parm, doc);
#define CMD_D_ANY_NONE(key, slot) \
#define CMD_D_ANY(key, slot) \
CMD_D_SLOT(key, call_unknown, slot, "i:", "")
#define CMD_D_STRING(key, slot) \
CMD_D_SLOT(key, call_string, slot, "i:", "")
#define CMD_D_VOID(key, slot) \
CMD_D_SLOT(key, call_unknown, rpc::object_fn(slot), "i:", "")
+12 -1
View File
@@ -385,6 +385,13 @@ cmd_ui_unfocus_download(core::Download* download, const torrent::Object& rawArgs
return torrent::Object();
}
torrent::Object
cmd_view_filter_download(core::Download* download, const torrent::Object& rawArgs) {
(*control->view_manager()->find_throw(rawArgs.as_string()))->filter_download(download);
return torrent::Object();
}
void
initialize_command_ui() {
ADD_VARIABLE_STRING("key_layout", "qwerty");
@@ -403,10 +410,14 @@ 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));
// Cleanup and add . to view.
CMD_D_STRING("view.filter_download", rak::ptr_fn(&cmd_view_filter_download));
// 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));
CMD_D_ANY("ui.unfocus_download", rak::ptr_fn(&cmd_ui_unfocus_download));
// Move.
+11 -7
View File
@@ -77,7 +77,7 @@ struct download_list_call {
void operator () (const DownloadList::slot_map::value_type& s) {
try {
s.second(m_download);
rpc::parse_command_d_multiple_std(m_download, s.second);
} catch (torrent::input_error& e) {
control->core()->push_log((std::string("Download event action failed: ") + e.what()).c_str());
}
@@ -166,6 +166,11 @@ DownloadList::insert(Download* download) {
(*itr)->download()->signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::received_finished), download));
(*itr)->download()->signal_hash_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::hash_done), download));
// This needs to be separated into two different calls to ensure
// the download remains in the view.
std::for_each(control->view_manager()->begin(), control->view_manager()->end(), std::bind2nd(std::mem_fun(&View::insert), download));
std::for_each(control->view_manager()->begin(), control->view_manager()->end(), std::bind2nd(std::mem_fun(&View::filter_download), download));
std::for_each(slot_map_insert().begin(), slot_map_insert().end(), download_list_call(*itr));
} catch (torrent::local_error& e) {
@@ -195,6 +200,7 @@ DownloadList::erase(iterator itr) {
control->core()->download_store()->remove(*itr);
std::for_each(slot_map_erase().begin(), slot_map_erase().end(), download_list_call(*itr));
std::for_each(control->view_manager()->begin(), control->view_manager()->end(), std::bind2nd(std::mem_fun(&View::erase), *itr));
torrent::download_remove(*(*itr)->download());
delete *itr;
@@ -246,6 +252,10 @@ DownloadList::close_try(Download* download) {
return false;
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);
close_throw(download);
return true;
@@ -319,8 +329,6 @@ DownloadList::start_normal(Download* download) {
(*control->view_manager()->find_throw("stopped"))->set_not_visible(download);
(*control->view_manager()->find_throw("started"))->set_visible(download);
resume(download);
}
bool
@@ -340,7 +348,6 @@ DownloadList::start_try(Download* download) {
(*control->view_manager()->find_throw("stopped"))->set_not_visible(download);
(*control->view_manager()->find_throw("started"))->set_visible(download);
resume(download);
return true;
}
@@ -352,8 +359,6 @@ DownloadList::stop_normal(Download* download) {
(*control->view_manager()->find_throw("started"))->set_not_visible(download);
(*control->view_manager()->find_throw("stopped"))->set_visible(download);
pause(download);
}
bool
@@ -368,7 +373,6 @@ DownloadList::stop_try(Download* download) {
(*control->view_manager()->find_throw("started"))->set_not_visible(download);
(*control->view_manager()->find_throw("stopped"))->set_visible(download);
pause(download);
return true;
}
+3 -3
View File
@@ -59,9 +59,8 @@ class Download;
class DownloadList : private std::list<Download*> {
public:
typedef std::list<Download*> base_type;
typedef sigc::slot1<void, Download*> slot_type;
typedef std::map<std::string, slot_type> slot_map;
typedef std::list<Download*> base_type;
typedef std::map<std::string, std::string> slot_map;
using base_type::iterator;
using base_type::const_iterator;
@@ -117,6 +116,7 @@ public:
void resume(Download* d, int flags = 0);
void pause(Download* d, int flags = 0);
void resume_default(Download* d) { resume(d); }
void pause_default(Download* d) { pause(d); }
void check_hash(Download* d);
+2 -2
View File
@@ -212,8 +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_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=");
m_downloadList->slot_map_insert()["1_connect_logs"] = "d.initialize_logs=";
m_downloadList->slot_map_erase()["9_delete_tied"] = "d.delete_tied=";
torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log));
}
+150 -158
View File
@@ -51,92 +51,6 @@
namespace core {
View::~View() {
if (m_name.empty())
return;
std::for_each(m_list->slot_map_begin(), m_list->slot_map_end(), rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
}
void
View::initialize(const std::string& name, core::DownloadList* dlist) {
if (!m_name.empty())
throw torrent::internal_error("View::initialize(...) called on an already initialized view.");
if (name.empty())
throw torrent::internal_error("View::initialize(...) called with an empty name.");
std::string key = "0_view_" + name;
if (dlist->has_slot_insert(key) || dlist->has_slot_erase(key))
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
m_name = name;
m_list = dlist;
// Urgh, wrong. No filtering being done.
std::for_each(m_list->begin(), m_list->end(), rak::bind1st(std::mem_fun(&View::push_back), this));
m_size = base_type::size();
m_focus = 0;
m_list->slot_map_insert()[key] = sigc::bind(sigc::mem_fun(this, &View::received), (int)DownloadList::SLOTS_INSERT);
m_list->slot_map_erase()[key] = sigc::bind(sigc::mem_fun(this, &View::received), (int)DownloadList::SLOTS_ERASE);
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())
return;
m_focus = (m_focus + 1) % (size() + 1);
m_signalChanged.emit();
}
void
View::prev_focus() {
if (empty())
return;
m_focus = (m_focus - 1 + size() + 1) % (size() + 1);
m_signalChanged.emit();
}
// Need to use wrapper-functors so it will properly call the virtual
// functions.
// Also add focus thingie here?
struct view_downloads_compare : std::binary_function<Download*, Download*, bool> {
view_downloads_compare(const std::string& cmd) : m_command(cmd) {}
@@ -188,6 +102,117 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
const std::string& m_command;
};
View::~View() {
if (m_name.empty())
return;
std::for_each(m_list->slot_map_begin(), m_list->slot_map_end(), rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
}
void
View::initialize(const std::string& name, core::DownloadList* dlist) {
if (!m_name.empty())
throw torrent::internal_error("View::initialize(...) called on an already initialized view.");
if (name.empty())
throw torrent::internal_error("View::initialize(...) called with an empty name.");
std::string key = "0_view_" + name;
if (dlist->has_slot_insert(key) || dlist->has_slot_erase(key))
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
m_name = name;
m_list = dlist;
// Urgh, wrong. No filtering being done.
std::for_each(m_list->begin(), m_list->end(), rak::bind1st(std::mem_fun(&View::push_back), this));
m_size = base_type::size();
m_focus = 0;
set_last_changed(rak::timer());
}
void
View::insert(Download* download) {
// if (view_downloads_filter(m_filter)(download)) {
// insert_visible(download);
// rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
// } else {
// base_type::insert(end_filtered(), download);
// }
// We can't make the download visible until after it has been added
// to every single View, as it might trigger a command too early.
base_type::insert(base_type::end(), download);
}
void
View::erase(Download* download) {
iterator itr = std::find(base_type::begin(), base_type::end(), download);
if (itr >= end_visible()) {
erase_internal(itr);
} else {
erase_internal(itr);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
}
}
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;
m_size--;
m_focus -= (m_focus > position(itr));
// 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())
return;
m_focus = (m_focus + 1) % (size() + 1);
m_signalChanged.emit();
}
void
View::prev_focus() {
if (empty())
return;
m_focus = (m_focus - 1 + size() + 1) % (size() + 1);
m_signalChanged.emit();
}
void
View::sort() {
Download* curFocus = focus() != end_visible() ? *focus() : NULL;
@@ -231,12 +256,49 @@ View::filter() {
std::for_each(splitChanged, changed.end(), rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventAdded));
}
void
View::filter_download(core::Download* download) {
iterator itr = std::find(base_type::begin(), base_type::end(), download);
if (itr == base_type::end())
throw torrent::internal_error("View::filter_download(...) could not find download.");
if (view_downloads_filter(m_filter)(download)) {
if (itr >= end_visible()) {
erase_internal(itr);
insert_visible(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
} else {
// This makes sure the download is sorted even if it is
// already visible.
//
// Consider removing this.
erase_internal(itr);
insert_visible(download);
}
} else {
if (itr >= end_visible())
return;
erase_internal(itr);
base_type::push_back(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
}
m_signalChanged.emit();
}
void
View::set_filter_on(int event) {
if (event == DownloadList::SLOTS_INSERT || event == DownloadList::SLOTS_ERASE || event >= DownloadList::SLOTS_MAX_SIZE)
throw torrent::internal_error("View::filter_on(...) invalid event.");
m_list->slots(event)["0_view_" + m_name] = sigc::bind(sigc::mem_fun(this, &View::received), event);
m_list->slots(event)["0_view_" + m_name] = "view.filter_download=" + m_name;
}
void
@@ -257,7 +319,7 @@ View::insert_visible(Download* d) {
}
inline void
View::erase(iterator itr) {
View::erase_internal(iterator itr) {
if (itr == end_filtered())
throw torrent::internal_error("View::erase_visible(...) iterator out of range.");
@@ -267,74 +329,4 @@ View::erase(iterator itr) {
base_type::erase(itr);
}
void
View::received(core::Download* download, int event) {
iterator itr = std::find(base_type::begin(), base_type::end(), download);
switch (event) {
case DownloadList::SLOTS_INSERT:
if (itr != base_type::end())
throw torrent::internal_error("View::received(..., SLOTS_INSERT) already inserted.");
if (view_downloads_filter(m_filter)(download)) {
insert_visible(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
} else {
base_type::insert(end_filtered(), download);
return;
}
if (m_focus > m_size)
throw torrent::internal_error("View::received(...) m_focus > m_size.");
break;
case DownloadList::SLOTS_ERASE:
if (itr >= end_visible()) {
erase(itr);
return;
}
erase(itr);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
break;
default:
if (itr == end_filtered())
throw torrent::internal_error("View::received(..., SLOTS_*) could not find download.");
if (view_downloads_filter(m_filter)(download)) {
if (itr >= end_visible()) {
erase(itr);
insert_visible(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
} else {
// This makes sure the download is sorted even if it is
// already visible.
erase(itr);
insert_visible(download);
}
} else {
if (itr >= end_visible())
return;
erase(itr);
base_type::push_back(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
}
break;
}
m_signalChanged.emit();
}
}
+5 -3
View File
@@ -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 insert(Download* download);
void erase(Download* download);
void set_visible(Download* download);
void set_not_visible(Download* download);
@@ -115,6 +118,7 @@ public:
// Need to explicity trigger filtering.
void filter();
void filter_download(core::Download* download);
void set_filter(const std::string& s) { m_filter = s; }
void set_filter_on(int event);
@@ -144,9 +148,7 @@ private:
void push_back(Download* d) { base_type::push_back(d); }
inline void insert_visible(Download* d);
inline void erase(iterator itr);
void received(Download* d, int event);
inline void erase_internal(iterator itr);
size_type position(const_iterator itr) const { return itr - begin(); }
+2 -6
View File
@@ -185,15 +185,11 @@ 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_event_added = started,d.resume=\n"
"view_event_removed = started,d.pause=\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_add = complete\n"
"view_filter = complete,d.get_complete=\n"
+1 -1
View File
@@ -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::bind(&rpc::parse_command_d_single_std, "ui.unfocus_download=");
control->core()->download_list()->slot_map_erase()["0_download_list"] = "ui.unfocus_download=";
activate_display(DISPLAY_DOWNLOAD_LIST);
}