mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-04 21:29:21 +00:00
Allow functions and lists of functions to be passed to view.event_{added,removed}.
This commit is contained in:
+7
-29
@@ -53,8 +53,7 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "command_helpers.h"
|
#include "command_helpers.h"
|
||||||
|
|
||||||
typedef void (core::ViewManager::*view_cfilter_slot)(const std::string&, const torrent::Object&);
|
typedef void (core::ViewManager::*view_event_slot)(const std::string&, const torrent::Object&);
|
||||||
typedef void (core::ViewManager::*view_event_slot)(const std::string&, const std::string&);
|
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_view_filter_on(const torrent::Object::list_type& args) {
|
apply_view_filter_on(const torrent::Object::list_type& args) {
|
||||||
@@ -76,33 +75,12 @@ apply_view_filter_on(const torrent::Object::list_type& args) {
|
|||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::Object
|
|
||||||
apply_view_cfilter(view_cfilter_slot viewFilterSlot, const torrent::Object::list_type& args) {
|
|
||||||
if (args.size() != 2)
|
|
||||||
throw torrent::input_error("Too few arguments.");
|
|
||||||
|
|
||||||
const std::string& name = args.front().as_string();
|
|
||||||
|
|
||||||
if (name.empty())
|
|
||||||
throw torrent::input_error("First argument must be a string.");
|
|
||||||
|
|
||||||
(control->view_manager()->*viewFilterSlot)(name, args.back());
|
|
||||||
|
|
||||||
return torrent::Object();
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_view_event(view_event_slot viewFilterSlot, const torrent::Object::list_type& args) {
|
apply_view_event(view_event_slot viewFilterSlot, const torrent::Object::list_type& args) {
|
||||||
if (args.size() != 2)
|
if (args.size() != 2)
|
||||||
throw torrent::input_error("Too few arguments.");
|
throw torrent::input_error("Wrong argument count.");
|
||||||
|
|
||||||
const std::string& name = args.front().as_string();
|
|
||||||
|
|
||||||
if (name.empty())
|
|
||||||
throw torrent::input_error("First argument must be a string.");
|
|
||||||
|
|
||||||
(control->view_manager()->*viewFilterSlot)(name, args.back().as_string());
|
|
||||||
|
|
||||||
|
(control->view_manager()->*viewFilterSlot)(args.front().as_string(), args.back());
|
||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +450,7 @@ torrent::Object
|
|||||||
cmd_view_persistent(const torrent::Object::string_type& args) {
|
cmd_view_persistent(const torrent::Object::string_type& args) {
|
||||||
core::View* view = *control->view_manager()->find_throw(args);
|
core::View* view = *control->view_manager()->find_throw(args);
|
||||||
|
|
||||||
if (!view->get_filter().is_empty() || !view->get_event_added().empty() || !view->get_event_removed().empty())
|
if (!view->get_filter().is_empty() || !view->event_added().is_empty() || !view->event_removed().is_empty())
|
||||||
throw torrent::input_error("Cannot set modified views as persitent.");
|
throw torrent::input_error("Cannot set modified views as persitent.");
|
||||||
|
|
||||||
view->set_filter("d.views.has=" + args);
|
view->set_filter("d.views.has=" + args);
|
||||||
@@ -546,12 +524,12 @@ initialize_command_ui() {
|
|||||||
CMD2_ANY_L ("view.list", tr1::bind(&apply_view_list));
|
CMD2_ANY_L ("view.list", tr1::bind(&apply_view_list));
|
||||||
CMD2_ANY_LIST("view.set", tr1::bind(&apply_view_set, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.set", tr1::bind(&apply_view_set, tr1::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_LIST("view.filter", tr1::bind(&apply_view_cfilter, &core::ViewManager::set_filter, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.filter", tr1::bind(&apply_view_event, &core::ViewManager::set_filter, tr1::placeholders::_2));
|
||||||
CMD2_ANY_LIST("view.filter_on", tr1::bind(&apply_view_filter_on, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.filter_on", tr1::bind(&apply_view_filter_on, tr1::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_LIST("view.sort", tr1::bind(&apply_view_sort, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.sort", tr1::bind(&apply_view_sort, tr1::placeholders::_2));
|
||||||
CMD2_ANY_LIST("view.sort_new", tr1::bind(&apply_view_cfilter, &core::ViewManager::set_sort_new, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.sort_new", tr1::bind(&apply_view_event, &core::ViewManager::set_sort_new, tr1::placeholders::_2));
|
||||||
CMD2_ANY_LIST("view.sort_current", tr1::bind(&apply_view_cfilter, &core::ViewManager::set_sort_current, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.sort_current", tr1::bind(&apply_view_event, &core::ViewManager::set_sort_current, tr1::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_LIST("view.event_added", tr1::bind(&apply_view_event, &core::ViewManager::set_event_added, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.event_added", tr1::bind(&apply_view_event, &core::ViewManager::set_event_added, tr1::placeholders::_2));
|
||||||
CMD2_ANY_LIST("view.event_removed", tr1::bind(&apply_view_event, &core::ViewManager::set_event_removed, tr1::placeholders::_2));
|
CMD2_ANY_LIST("view.event_removed", tr1::bind(&apply_view_event, &core::ViewManager::set_event_removed, tr1::placeholders::_2));
|
||||||
|
|||||||
+11
-9
@@ -184,7 +184,7 @@ View::erase(Download* download) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
erase_internal(itr);
|
erase_internal(itr);
|
||||||
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
|
rpc::call_object_nothrow(m_event_removed, rpc::make_target(download));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ View::set_visible(Download* download) {
|
|||||||
base_type::erase(itr);
|
base_type::erase(itr);
|
||||||
insert_visible(download);
|
insert_visible(download);
|
||||||
|
|
||||||
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
|
rpc::call_object_nothrow(m_event_added, rpc::make_target(download));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -218,7 +218,7 @@ View::set_not_visible(Download* download) {
|
|||||||
base_type::erase(itr);
|
base_type::erase(itr);
|
||||||
base_type::push_back(download);
|
base_type::push_back(download);
|
||||||
|
|
||||||
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
|
rpc::call_object_nothrow(m_event_removed, rpc::make_target(download));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -275,11 +275,13 @@ View::filter() {
|
|||||||
// done by using a base_type* member variable, and making sure we
|
// done by using a base_type* member variable, and making sure we
|
||||||
// set the elements to NULL as we trigger commands on them. Or
|
// set the elements to NULL as we trigger commands on them. Or
|
||||||
// perhaps always clear them, thus not throwing anything.
|
// perhaps always clear them, thus not throwing anything.
|
||||||
if (!m_eventRemoved.empty())
|
if (!m_event_removed.is_empty())
|
||||||
std::for_each(changed.begin(), splitChanged, rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventRemoved));
|
std::for_each(changed.begin(), splitChanged,
|
||||||
|
tr1::bind(&rpc::call_object_d_nothrow, m_event_removed, tr1::placeholders::_1));
|
||||||
|
|
||||||
if (!m_eventAdded.empty())
|
if (!m_event_added.is_empty())
|
||||||
std::for_each(splitChanged, changed.end(), rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventAdded));
|
std::for_each(changed.begin(), splitChanged,
|
||||||
|
tr1::bind(&rpc::call_object_d_nothrow, m_event_added, tr1::placeholders::_1));
|
||||||
|
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
@@ -297,7 +299,7 @@ View::filter_download(core::Download* download) {
|
|||||||
erase_internal(itr);
|
erase_internal(itr);
|
||||||
insert_visible(download);
|
insert_visible(download);
|
||||||
|
|
||||||
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
|
rpc::call_object_nothrow(m_event_added, rpc::make_target(download));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// This makes sure the download is sorted even if it is
|
// This makes sure the download is sorted even if it is
|
||||||
@@ -315,7 +317,7 @@ View::filter_download(core::Download* download) {
|
|||||||
erase_internal(itr);
|
erase_internal(itr);
|
||||||
base_type::push_back(download);
|
base_type::push_back(download);
|
||||||
|
|
||||||
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
|
rpc::call_object_nothrow(m_event_removed, rpc::make_target(download));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_changed();
|
emit_changed();
|
||||||
|
|||||||
+6
-6
@@ -127,10 +127,10 @@ public:
|
|||||||
|
|
||||||
void clear_filter_on();
|
void clear_filter_on();
|
||||||
|
|
||||||
const std::string& get_event_added() const { return m_eventAdded; }
|
const torrent::Object& event_added() const { return m_event_added; }
|
||||||
const std::string& get_event_removed() const { return m_eventRemoved; }
|
const torrent::Object& event_removed() const { return m_event_removed; }
|
||||||
void set_event_added(const std::string& cmd) { m_eventAdded = cmd; }
|
void set_event_added(const torrent::Object& cmd) { m_event_added = cmd; }
|
||||||
void set_event_removed(const std::string& cmd) { m_eventRemoved = cmd; }
|
void set_event_removed(const torrent::Object& cmd) { m_event_removed = cmd; }
|
||||||
|
|
||||||
// The time of the last change to the view, semantics of this is
|
// The time of the last change to the view, semantics of this is
|
||||||
// user-dependent. Used by f.ex. ViewManager to decide if it should
|
// user-dependent. Used by f.ex. ViewManager to decide if it should
|
||||||
@@ -171,8 +171,8 @@ private:
|
|||||||
|
|
||||||
torrent::Object m_filter;
|
torrent::Object m_filter;
|
||||||
|
|
||||||
std::string m_eventAdded;
|
torrent::Object m_event_added;
|
||||||
std::string m_eventRemoved;
|
torrent::Object m_event_removed;
|
||||||
|
|
||||||
rak::timer m_lastChanged;
|
rak::timer m_lastChanged;
|
||||||
|
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ public:
|
|||||||
void set_filter(const std::string& name, const torrent::Object& cmd);
|
void set_filter(const std::string& name, const torrent::Object& cmd);
|
||||||
void set_filter_on(const std::string& name, const filter_args& args);
|
void set_filter_on(const std::string& name, const filter_args& args);
|
||||||
|
|
||||||
void set_event_added(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_event_added(cmd); }
|
void set_event_added(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_event_added(cmd); }
|
||||||
void set_event_removed(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_event_removed(cmd); }
|
void set_event_removed(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_event_removed(cmd); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DownloadList* m_list;
|
DownloadList* m_list;
|
||||||
|
|||||||
+5
-5
@@ -293,7 +293,7 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
"group.insert = seeding,seeding\n"
|
"group.insert = seeding,seeding\n"
|
||||||
|
|
||||||
"session.name.set = \"$cat=$system.hostname=,:,$system.pid=\"\n"
|
"session.name.set = (cat,(system.hostname),:,(system.pid))\n"
|
||||||
|
|
||||||
// Currently not doing any sorting on main.
|
// Currently not doing any sorting on main.
|
||||||
"view.add = main\n"
|
"view.add = main\n"
|
||||||
@@ -308,13 +308,13 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
"view.add = started\n"
|
"view.add = started\n"
|
||||||
"view.filter = started,((false))\n"
|
"view.filter = started,((false))\n"
|
||||||
"view.event_added = started,\"view.set_not_visible=stopped ;d.state.set=1 ;scheduler.simple.added=\"\n"
|
"view.event_added = started,{(view.set_not_visible,stopped),(d.state.set,1),(scheduler.simple.added)}\n"
|
||||||
"view.event_removed = started,\"view.set_visible=stopped ;scheduler.simple.removed=\"\n"
|
"view.event_removed = started,{(view.set_visible,stopped),(scheduler.simple.removed)}\n"
|
||||||
|
|
||||||
"view.add = stopped\n"
|
"view.add = stopped\n"
|
||||||
"view.filter = stopped,((false))\n"
|
"view.filter = stopped,((false))\n"
|
||||||
"view.event_added = stopped,\"d.state.set=0 ;view.set_not_visible=started\"\n"
|
"view.event_added = stopped,{(d.state.set,0),(view.set_not_visible,started)}\n"
|
||||||
"view.event_removed = stopped,view.set_visible=started\n"
|
"view.event_removed = stopped,((view.set_visible,started))\n"
|
||||||
|
|
||||||
"view.add = complete\n"
|
"view.add = complete\n"
|
||||||
"view.filter = complete,((d.complete))\n"
|
"view.filter = complete,((d.complete))\n"
|
||||||
|
|||||||
@@ -97,24 +97,7 @@ CommandScheduler::call_item(value_type item) {
|
|||||||
// removed.
|
// removed.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (item->command().is_string()) {
|
rpc::call_object(item->command());
|
||||||
rpc::parse_command_multiple_std(item->command().as_string());
|
|
||||||
|
|
||||||
} else if (item->command().is_dict_key()) {
|
|
||||||
// This can/should be optimized...
|
|
||||||
torrent::Object tmp_command = item->command();
|
|
||||||
|
|
||||||
// Unquote the root function object so 'parse_command_execute'
|
|
||||||
// doesn't end up calling it.
|
|
||||||
//
|
|
||||||
// TODO: Only call this if mask_function is set?
|
|
||||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
|
||||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
|
||||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
|
||||||
|
|
||||||
rpc::parse_command_execute(rpc::make_target(), &tmp_command);
|
|
||||||
rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj());
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (torrent::input_error& e) {
|
} catch (torrent::input_error& e) {
|
||||||
if (m_slotErrorMessage.is_valid())
|
if (m_slotErrorMessage.is_valid())
|
||||||
|
|||||||
@@ -239,6 +239,39 @@ parse_command_file(const std::string& path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
call_object(const torrent::Object& command, target_type target) {
|
||||||
|
switch (command.type()) {
|
||||||
|
case torrent::Object::TYPE_STRING:
|
||||||
|
parse_command_multiple(target, command.as_string().c_str(), command.as_string().c_str() + command.as_string().size());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case torrent::Object::TYPE_LIST:
|
||||||
|
for (torrent::Object::list_const_iterator itr = command.as_list().begin(), last = command.as_list().end(); itr != last; itr++)
|
||||||
|
call_object(*itr, target);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case torrent::Object::TYPE_DICT_KEY:
|
||||||
|
{
|
||||||
|
// This can/should be optimized...
|
||||||
|
torrent::Object tmp_command = command;
|
||||||
|
|
||||||
|
// Unquote the root function object so 'parse_command_execute'
|
||||||
|
// doesn't end up calling it.
|
||||||
|
//
|
||||||
|
// TODO: Only call this if mask_function is set?
|
||||||
|
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||||
|
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||||
|
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||||
|
|
||||||
|
parse_command_execute(make_target(), &tmp_command);
|
||||||
|
commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -124,6 +124,18 @@ call_command_d_range(const char* key, core::Download* download, torrent::Object:
|
|||||||
return commands.call_command_d(key, download, rawArgs);
|
return commands.call_command_d(key, download, rawArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void call_object(const torrent::Object& command, target_type target = make_target());
|
||||||
|
|
||||||
|
inline void
|
||||||
|
call_object_nothrow(const torrent::Object& command, target_type target = make_target()) {
|
||||||
|
try { call_object(command, target); } catch (torrent::input_error& e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
call_object_d_nothrow(const torrent::Object& command, core::Download* download) {
|
||||||
|
try { call_object(command, make_target(download)); } catch (torrent::input_error& e) {}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user