diff --git a/doc/rtorrent.1.xml b/doc/rtorrent.1.xml
index e84a21b4..fee2a2eb 100644
--- a/doc/rtorrent.1.xml
+++ b/doc/rtorrent.1.xml
@@ -199,12 +199,23 @@ Close a torrent and its files.
-
- I
-
- Toggle whether torrent ignores ratio settings.
+
+ U
+
+
+Delete the file the torrent is tied to, and clear the association.
+
-
+
+
+
+ I
+
+
+Toggle whether torrent ignores ratio settings.
+
+
+
@@ -246,6 +257,15 @@ Close a torrent and its files.
+
+ u
+
+
+Display transfering blocks.
+
+
+
+
i
@@ -569,6 +589,15 @@ Delete id from the scheduler.
+
+ start_tied =
+
+
+Start torrents that are tied to filenames that have been re-added.
+
+
+
+
stop_untied =
close_untied =
@@ -576,8 +605,7 @@ Delete id from the scheduler.
Stop, close or remove the torrents that are tied to filenames that
-have been deleted, the association with the file is then cleared so
-the event will not trigger more than once.
+have been deleted. Clear the association with the 'U' key.
@@ -645,7 +673,7 @@ torrent::input_error exception on bad input.
- DISPLAY SETTINGS
+ USER-INTERFACE SETTINGS
Display related settings.
@@ -700,7 +728,7 @@ number of criteria, including zero, from the following:
Set a list of filter to apply when new new downloads are added and
-when view_sort gets called. All filters must
+when view_sort is called. All filters must
match for the download to be included.
@@ -711,6 +739,15 @@ match for the download to be included.
+
+ key_layout = querty|azerty
+
+
+Change the key-bindings.
+
+
+
+
diff --git a/src/core/download_list.cc b/src/core/download_list.cc
index 31448cfe..11eb8f82 100644
--- a/src/core/download_list.cc
+++ b/src/core/download_list.cc
@@ -283,9 +283,11 @@ DownloadList::resume(Download* download) {
// 'hashing' was set.
if (!download->is_hash_checked()) {
// If the hash failed flag wasn't cleared then hashing won't be
- // initiated. The check here is just for convenience so the hash
- // queue doesn't need to check it.
- if (!download->is_hash_failed() && download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
+ // initiated.
+ if (download->is_hash_failed())
+ return;
+
+ if (download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
download->variable()->set("hashing", Download::variable_hashing_initial);
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
diff --git a/src/core/manager.cc b/src/core/manager.cc
index f77c6440..f58f2c79 100644
--- a/src/core/manager.cc
+++ b/src/core/manager.cc
@@ -384,12 +384,48 @@ Manager::try_create_download_expand(const std::string& uri, bool start, bool pri
// hashing view and starts hashing if nessesary.
void
Manager::receive_hashing_changed() {
- if (m_hashingView->empty_visible() ||
- std::find_if(m_hashingView->begin_visible(), m_hashingView->end_visible(), std::mem_fun(&Download::is_hash_checking)) != m_hashingView->end_visible())
+ bool foundHashing = false;
+
+ // Try quick hashing all those with hashing == initial, set them to
+ // something else when failed.
+ for (View::iterator itr = m_hashingView->begin_visible(), last = m_hashingView->end_visible(); itr != last; ++itr)
+ try {
+
+ if ((*itr)->is_hash_checking()) {
+ foundHashing = true;
+ continue;
+ }
+
+ if ((*itr)->is_hash_checked())
+ throw torrent::client_error("core::Manager::receive_hashing_changed() hash already checked or checking.");
+
+ if ((*itr)->is_hash_failed() || (*itr)->variable()->get_value("hashing") != Download::variable_hashing_initial)
+ continue;
+
+ m_downloadList->open_throw(*itr);
+ torrent::resume_load_progress(*(*itr)->download(), (*itr)->download()->bencode()->get_key("libtorrent_resume"));
+
+ if ((*itr)->download()->hash_check(true)) {
+ // Set this to exit the function so that the delayed hash done
+ // signal gets triggered before we try any real hashing.
+ foundHashing = true;
+
+ } else {
+ // Temporary hack.
+ (*itr)->download()->hash_stop();
+ }
+
+ (*itr)->variable()->set_value("hashing", Download::variable_hashing_rehash);
+
+ } catch (torrent::local_error& e) {
+ (*itr)->set_hash_failed(true);
+ push_log(e.what());
+ }
+
+ if (foundHashing)
return;
- for (View::iterator itr = m_hashingView->begin_visible(), last = m_hashingView->end_visible(); itr != last; ++itr) {
-
+ for (View::iterator itr = m_hashingView->begin_visible(), last = m_hashingView->end_visible(); itr != last; ++itr)
try {
if ((*itr)->is_hash_checked() || (*itr)->is_hash_checking())
@@ -399,9 +435,9 @@ Manager::receive_hashing_changed() {
continue;
m_downloadList->open_throw(*itr);
-
torrent::resume_load_progress(*(*itr)->download(), (*itr)->download()->bencode()->get_key("libtorrent_resume"));
- (*itr)->download()->hash_check();
+
+ (*itr)->download()->hash_check(false);
return;
@@ -409,7 +445,6 @@ Manager::receive_hashing_changed() {
(*itr)->set_hash_failed(true);
push_log(e.what());
}
- }
}
}
diff --git a/src/display/client_info.cc b/src/display/client_info.cc
index af7f1138..75057d6e 100644
--- a/src/display/client_info.cc
+++ b/src/display/client_info.cc
@@ -52,7 +52,7 @@ struct client_info_equal {
bool operator () (const ClientInfo::value_type& v) const {
for (ClientInfo::size_type i = 0; i < m_size; ++i)
if (v.first[i] != m_key[i])
- return false;
+ return false;
return true;
}
@@ -65,16 +65,18 @@ ClientInfo::ClientInfo() {
m_containers[TYPE_AZUREUS].reserve(30);
insert(TYPE_AZUREUS, "AZ", "Azureus");
+ insert(TYPE_AZUREUS, "BB", "BitBuddy");
insert(TYPE_AZUREUS, "BC", "BitComet");
insert(TYPE_AZUREUS, "UT", "uTorrent");
insert(TYPE_AZUREUS, "lt", "libTorrent");
- insert(TYPE_AZUREUS, "BB", "BitBuddy");
insert(TYPE_AZUREUS, "CT", "CTorrent");
insert(TYPE_AZUREUS, "MT", "MoonlightTorrent");
insert(TYPE_AZUREUS, "LT", "libtorrent");
+ insert(TYPE_AZUREUS, "KT", "KTorrent");
insert(TYPE_AZUREUS, "BX", "Bittorrent X");
insert(TYPE_AZUREUS, "TS", "Torrentstorm");
insert(TYPE_AZUREUS, "TN", "TorrentDotNET");
+ insert(TYPE_AZUREUS, "TR", "Transmission");
insert(TYPE_AZUREUS, "SS", "SwarmScope");
insert(TYPE_AZUREUS, "XT", "XanTorrent");
insert(TYPE_AZUREUS, "BS", "BTSlave");
diff --git a/src/display/window_peer_list.cc b/src/display/window_peer_list.cc
index acc0d7c7..b6f6c3ec 100644
--- a/src/display/window_peer_list.cc
+++ b/src/display/window_peer_list.cc
@@ -74,7 +74,8 @@ WindowPeerList::redraw() {
m_canvas->print(x, y, "QS"); x += 6;
m_canvas->print(x, y, "DONE"); x += 6;
m_canvas->print(x, y, "REQ"); x += 6;
- m_canvas->print(x, y, "SNUB");
+ m_canvas->print(x, y, "SNUB"); x += 6;
+ m_canvas->print(x, y, "FAILED");
++y;
@@ -129,7 +130,12 @@ WindowPeerList::redraw() {
if (p.is_snubbed())
m_canvas->print(x, y, "*");
- x += 5;
+ x += 6;
+
+ if (p.failed_counter() != 0)
+ m_canvas->print(x, y, "%u", p.failed_counter());
+
+ x += 7;
char buf[128];
control->client_info()->print(buf, buf + 128, p.id().c_str());
diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc
index fbc3f3fc..e50c256f 100644
--- a/src/option_handler_rules.cc
+++ b/src/option_handler_rules.cc
@@ -468,6 +468,8 @@ initialize_option_handler(Control* c) {
variables->insert("view_sort_new", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_view_sort_new, c)));
variables->insert("view_sort_current", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_view_sort_current, c)));
+ variables->insert("key_layout", new utils::VariableAny(std::string("qwerty")));
+
variables->insert("schedule", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::mem_fn(c->command_scheduler(), &CommandScheduler::parse)));
variables->insert("schedule_remove", new utils::VariableStringSlot(rak::value_fn(std::string()),
rak::mem_fn(c->command_scheduler(), &CommandScheduler::erase)));
diff --git a/src/ui/root.cc b/src/ui/root.cc
index da4efea1..74b062d4 100644
--- a/src/ui/root.cc
+++ b/src/ui/root.cc
@@ -37,11 +37,13 @@
#include "config.h"
#include
+#include
#include
#include
#include "display/window_statusbar.h"
#include "input/manager.h"
+#include "utils/variable_map.h"
#include "control.h"
#include "download_list.h"
@@ -94,17 +96,26 @@ void
Root::setup_keys() {
m_control->input()->push_back(&m_bindings);
- m_bindings['a'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), 1);
- m_bindings['z'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), -1);
+ if (strcasecmp(control->variable()->get_string("key_layout").c_str(), "azerty") == 0) {
+ m_bindings['q'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), 1);
+ m_bindings['w'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), -1);
+ m_bindings['Q'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), 1);
+ m_bindings['W'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), -1);
+
+ } else {
+ m_bindings['a'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), 1);
+ m_bindings['z'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), -1);
+ m_bindings['A'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), 1);
+ m_bindings['Z'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), -1);
+ }
+
m_bindings['s'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), 5);
m_bindings['x'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), -5);
- m_bindings['d'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), 50);
- m_bindings['c'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), -50);
-
- m_bindings['A'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), 1);
- m_bindings['Z'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), -1);
m_bindings['S'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), 5);
m_bindings['X'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), -5);
+
+ m_bindings['d'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), 50);
+ m_bindings['c'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_up_throttle), -50);
m_bindings['D'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), 50);
m_bindings['C'] = sigc::bind(sigc::mem_fun(*this, &Root::adjust_down_throttle), -50);