diff --git a/configure.ac b/configure.ac index 23a7d979..6ef45bcc 100644 --- a/configure.ac +++ b/configure.ac @@ -8,6 +8,8 @@ TORRENT_ENABLE_DEBUG() TORRENT_ENABLE_EXTRA_DEBUG() TORRENT_ENABLE_WERROR() +TORRENT_DISABLE_IPV6 + AC_PROG_CXX AC_PROG_LIBTOOL AC_SYS_LARGEFILE diff --git a/scripts/common.m4 b/scripts/common.m4 index 7c3d32a1..cb38fc2d 100644 --- a/scripts/common.m4 +++ b/scripts/common.m4 @@ -168,6 +168,7 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [ ]) ]) + AC_DEFUN([TORRENT_ENABLE_ALIGNED], [ AC_ARG_ENABLE(aligned, [ --enable-aligned enable alignment safe code [[default=check]]], @@ -179,3 +180,14 @@ AC_DEFUN([TORRENT_ENABLE_ALIGNED], [ TORRENT_CHECK_ALIGNED ]) ]) + + +AC_DEFUN([TORRENT_DISABLE_IPV6], [ + AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 disable ipv6 [[default=no]]], + [ + if test "$enableval" = "yes"; then + AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff) + fi + ]) +]) diff --git a/src/core/manager.cc b/src/core/manager.cc index 2ff63fd7..d2f16abe 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -291,8 +291,6 @@ Manager::set_local_address(const std::string& addr) { torrent::connection_manager()->set_local_address(ai->address()->c_sockaddr()); rak::address_info::free_address_info(ai); - m_pollManager->get_http_stack()->set_bind_address(addr); - } catch (torrent::input_error& e) { rak::address_info::free_address_info(ai); throw e; diff --git a/src/core/view_downloads.cc b/src/core/view_downloads.cc index a5fc984a..685cda90 100644 --- a/src/core/view_downloads.cc +++ b/src/core/view_downloads.cc @@ -75,10 +75,10 @@ ViewDownloads::initialize(const std::string& name, core::DownloadList* list) { m_list = list; m_focus = 0; + std::for_each(m_list->begin(), m_list->end(), std::bind1st(std::mem_fun(&ViewDownloads::received_insert), this)); + m_list->slot_map_insert()[key] = sigc::mem_fun(this, &ViewDownloads::received_insert); m_list->slot_map_erase()[key] = sigc::mem_fun(this, &ViewDownloads::received_erase); - - // Add from download, do various stuff to them. } void @@ -101,11 +101,22 @@ ViewDownloads::prev_focus() { m_signalChanged.emit(); } +// Also add focus thingie here. +struct view_downloads_compare : std::binary_function { + view_downloads_compare(const ViewSort* s) : m_sort(s) {} + + bool operator () (Download* d1, Download* d2) const { + return m_sort->compare(d1, d2); + } + + const ViewSort* m_sort; +}; + void -ViewDownloads::sort(sort_slot s) { +ViewDownloads::sort(const ViewSort* s) { Download* curFocus = focus() != end() ? *focus() : NULL; - std::sort(begin(), end(), std::ptr_fun(s)); + std::sort(begin(), end(), view_downloads_compare(s)); m_focus = position(std::find(begin(), end(), curFocus)); m_signalChanged.emit(); @@ -113,9 +124,7 @@ ViewDownloads::sort(sort_slot s) { void ViewDownloads::received_insert(core::Download* d) { - iterator itr = m_sortNew != NULL ? - std::find_if(begin(), end(), std::bind1st(std::ptr_fun(m_sortNew), d)) : - end(); + iterator itr = std::find_if(begin(), end(), std::bind1st(view_downloads_compare(m_sortNew), d)); if (m_focus >= position(itr)) m_focus++; diff --git a/src/core/view_downloads.h b/src/core/view_downloads.h index b5654e06..d26b394c 100644 --- a/src/core/view_downloads.h +++ b/src/core/view_downloads.h @@ -46,6 +46,7 @@ #ifndef RTORRENT_CORE_VIEW_DOWNLOADS_H #define RTORRENT_CORE_VIEW_DOWNLOADS_H +#include #include #include #include @@ -54,18 +55,13 @@ namespace core { class Download; class DownloadList; +class ViewSort; class ViewDownloads : public std::vector { public: typedef std::vector base_type; typedef sigc::signal0 signal_type; - // Switch with a base class that defines some function. We might - // want to include some parameters etc. - // - // Also, it should be possible to check the focus index etc. - typedef bool (*sort_slot)(core::Download* d1, core::Download* d2); - using base_type::iterator; using base_type::const_iterator; using base_type::reverse_iterator; @@ -95,10 +91,14 @@ public: void next_focus(); void prev_focus(); - void sort(sort_slot s); + void sort(const ViewSort* s); - void set_sort_new(sort_slot s) { m_sortNew = s; } + // This is set to ViewNone by default by ViewManager before + // initialize is called. + void set_sort_new(const ViewSort* s) { m_sortNew = s; } + // Don't connect any slots until after initialize else it get's + // triggered when adding the Download's in DownloadList. signal_type& signal_changed() { return m_signalChanged; } private: @@ -117,13 +117,25 @@ private: core::DownloadList* m_list; size_type m_focus; - sort_slot m_sortNew; + const ViewSort* m_sortNew; // Timer, last changed. signal_type m_signalChanged; }; +class ViewSort { +public: + virtual ~ViewSort() {} + + // Add various extra stuff here, like bool flags for can sort new, + // normal etc. + + // How to take focus into account? + + virtual bool compare(Download* d1, Download* d2) const = 0; +}; + } #endif diff --git a/src/core/view_manager.cc b/src/core/view_manager.cc index b842ba87..9dc0b56f 100644 --- a/src/core/view_manager.cc +++ b/src/core/view_manager.cc @@ -46,13 +46,83 @@ namespace core { +class ViewSortFirst : public ViewSort { +public: + virtual bool compare(Download* d1, Download* d2) const { + return true; + } +}; + +class ViewSortName : public ViewSort { +public: + virtual bool compare(Download* d1, Download* d2) const { + return d1->download()->name() < d2->download()->name(); + } +}; + +class ViewSortVariable : public ViewSort { +public: + ViewSortVariable(const std::string& name, const std::string& value) : + m_name(name), m_value(value) {} + + virtual bool compare(Download* d1, Download* d2) const { + return + d1->variable()->get_string(m_name) == m_value || + d2->variable()->get_string(m_name) != m_value; + } + +private: + std::string m_name; + std::string m_value; +}; + +class ViewSortReverse : public ViewSort { +public: + ViewSortReverse(ViewSort* s) : m_sort(s) {} + ~ViewSortReverse() { delete m_sort; } + + virtual bool compare(Download* d1, Download* d2) const { + return m_sort->compare(d2, d1); + } + +private: + ViewSort* m_sort; +}; + +// Hmm, use a list in ViewDownloads instead? +class ViewSortAnd : public ViewSort { +public: + ViewSortAnd(ViewSort* s1, ViewSort* s2) : m_sort1(s1), m_sort2(s2) {} + ~ViewSortAnd() { delete m_sort1; delete m_sort2; } + + virtual bool compare(Download* d1, Download* d2) const { + return m_sort1->compare(d1, d2) && m_sort2->compare(d1, d2); + } + +private: + ViewSort* m_sort1; + ViewSort* m_sort2; +}; + ViewManager::ViewManager(DownloadList* dl) : m_list(dl) { + + m_sort["first"] = new ViewSortFirst(); + m_sort["last"] = new ViewSortReverse(new ViewSortFirst()); + m_sort["name"] = new ViewSortName(); + m_sort["name_reverse"] = new ViewSortReverse(new ViewSortName()); + + m_sort["started"] = new ViewSortVariable("state", "started"); + m_sort["started_name"] = new ViewSortAnd(new ViewSortVariable("state", "started"), new ViewSortName()); + + m_sort["stopped"] = new ViewSortVariable("state", "stopped"); + m_sort["stopped_name"] = new ViewSortAnd(new ViewSortVariable("state", "stopped"), new ViewSortName()); } void ViewManager::clear() { std::for_each(begin(), end(), rak::call_delete()); + std::for_each(m_sort.begin(), m_sort.end(), rak::on(rak::mem_ptr_ref(&sort_map::value_type::second), rak::call_delete())); base_type::clear(); } @@ -63,6 +133,8 @@ ViewManager::insert(const std::string& name) { throw torrent::internal_error("ViewManager::insert(...) name already inserted."); ViewDownloads* view = new ViewDownloads(); + + view->set_sort_new(m_sort["last"]); view->initialize(name, m_list); return base_type::insert(end(), view); @@ -83,51 +155,28 @@ ViewManager::find_throw(const std::string& name) { return itr; } -// Put this somewhere else. -bool -view_sort_name(core::Download* d1, core::Download* d2) { - return d1->download()->name() < d2->download()->name(); -} - -bool -view_sort_name_reverse(core::Download* d1, core::Download* d2) { - return d1->download()->name() > d2->download()->name(); -} - void ViewManager::sort(const std::string& name, const std::string& sort) { - iterator itr = find_throw(name); + iterator viewItr = find_throw(name); - // Quick and dirty hack. - if (sort == "none") - (*itr)->sort(NULL); + sort_map::const_iterator sortItr = m_sort.find(sort); - else if (sort == "name") - (*itr)->sort(&view_sort_name); - - else if (sort == "name_reverse") - (*itr)->sort(&view_sort_name_reverse); - - else + if (sortItr == m_sort.end()) throw torrent::input_error("Invalid sorting identifier."); + + (*viewItr)->sort(sortItr->second); } void ViewManager::set_sort_new(const std::string& name, const std::string& sort) { - iterator itr = find_throw(name); + iterator viewItr = find_throw(name); - // Quick and dirty hack. - if (sort == "none") - (*itr)->set_sort_new(NULL); + sort_map::const_iterator sortItr = m_sort.find(sort); - else if (sort == "name") - (*itr)->set_sort_new(&view_sort_name); - - else if (sort == "name_reverse") - (*itr)->set_sort_new(&view_sort_name_reverse); - - else + if (sortItr == m_sort.end()) throw torrent::input_error("Invalid sorting identifier."); + + (*viewItr)->set_sort_new(sortItr->second); } } diff --git a/src/core/view_manager.h b/src/core/view_manager.h index 6de14f6b..bc961259 100644 --- a/src/core/view_manager.h +++ b/src/core/view_manager.h @@ -37,15 +37,19 @@ #ifndef RTORRENT_CORE_VIEW_MANAGER_H #define RTORRENT_CORE_VIEW_MANAGER_H +#include +#include #include namespace core { class ViewDownloads; +class ViewSort; class ViewManager : public rak::unordered_vector { public: typedef rak::unordered_vector base_type; + typedef std::map sort_map; using base_type::iterator; using base_type::const_iterator; @@ -86,6 +90,8 @@ public: private: DownloadList* m_list; + + sort_map m_sort; }; } diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index 830974ae..f370f4f0 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -225,7 +225,6 @@ void initialize_option_handler(Control* c) { utils::VariableMap* variables = control->variable(); - // Cleaned up. variables->insert("check_hash", new utils::VariableBool(true)); variables->insert("use_udp_trackers", new utils::VariableBool(true)); variables->insert("port_open", new utils::VariableBool(true)); @@ -266,8 +265,7 @@ initialize_option_handler(Control* c) { variables->insert("max_open_files", new utils::VariableValueSlot(rak::ptr_fn(&torrent::max_open_files), rak::ptr_fn(&torrent::set_max_open_files))); variables->insert("max_open_sockets", new utils::VariableValueSlot(rak::ptr_fn(&torrent::max_open_sockets), rak::ptr_fn(&torrent::set_max_open_sockets))); - variables->insert("print", new utils::VariableStringSlot(rak::value_fn(std::string()), - rak::mem_fn(control->core(), &core::Manager::push_log))); + variables->insert("print", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::mem_fn(control->core(), &core::Manager::push_log))); variables->insert("import", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::mem_fn(control->variable(), &utils::VariableMap::process_file_throw))); variables->insert("try_import", new utils::VariableStringSlot(rak::value_fn(std::string()), @@ -293,8 +291,7 @@ initialize_option_handler(Control* c) { variables->insert("hash_read_ahead", new utils::VariableValueSlot(rak::ptr_fn(torrent::hash_read_ahead), rak::bind_ptr_fn(&apply_hash_read_ahead, c))); variables->insert("hash_interval", new utils::VariableValueSlot(rak::ptr_fn(torrent::hash_interval), rak::bind_ptr_fn(&apply_hash_interval, c))); - variables->insert("umask", new utils::VariableValueSlot(rak::mem_fn(control, &Control::umask), - rak::mem_fn(control, &Control::set_umask), 8)); + variables->insert("umask", new utils::VariableValueSlot(rak::mem_fn(control, &Control::umask), rak::mem_fn(control, &Control::set_umask), 8)); variables->insert("working_directory", new utils::VariableStringSlot(rak::mem_fn(control, &Control::working_directory), rak::mem_fn(control, &Control::set_working_directory)));