From 7534b028150208e8228f1ac202c2e6db18fb25e3 Mon Sep 17 00:00:00 2001 From: kannibalox Date: Fri, 13 Dec 2024 16:40:00 -0500 Subject: [PATCH] Add page up/down and home/end bindings to download list --- src/command_ui.cc | 2 + src/core/view.cc | 69 ++++++-------- src/core/view.h | 43 +-------- src/display/window_download_list.cc | 46 +++++---- src/display/window_download_list.h | 3 + src/ui/element_download_list.cc | 139 ++++++++++++++-------------- src/ui/element_download_list.h | 80 +++++----------- 7 files changed, 163 insertions(+), 219 deletions(-) diff --git a/src/command_ui.cc b/src/command_ui.cc index 99040d08..c93a3366 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -816,6 +816,8 @@ initialize_command_ui() { CMD2_VAR_VALUE ("ui.throttle.global.step.medium", 50); CMD2_VAR_VALUE ("ui.throttle.global.step.large", 500); + CMD2_VAR_VALUE ("ui.focus.page_size", 0); + CMD2_ANY_LIST ("ui.status.throttle.up.set", std::bind(&cmd_status_throttle_names, true, std::placeholders::_2)); CMD2_ANY_LIST ("ui.status.throttle.down.set", std::bind(&cmd_status_throttle_names, false, std::placeholders::_2)); diff --git a/src/core/view.cc b/src/core/view.cc index e975ed85..7d28af65 100644 --- a/src/core/view.cc +++ b/src/core/view.cc @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -236,20 +200,45 @@ View::set_not_visible(Download* download) { } void -View::next_focus() { +View::next_focus(unsigned int i) { if (empty()) return; - m_focus = (m_focus + 1) % (size() + 1); + // If at the boundary, roll over + if (m_focus == size() - 1) { + m_focus = size(); + emit_changed(); + return; + } + + // Move forward, stop at the boundary + if (m_focus == size()) // Needs special handling to ensure it's not off by one + m_focus = i - 1; + else + m_focus += i; + if (m_focus > size() - 1) + m_focus = size() - 1; + emit_changed(); } void -View::prev_focus() { +View::prev_focus(unsigned int i) { if (empty()) return; - m_focus = (m_focus - 1 + size() + 1) % (size() + 1); + // If at the boundary, roll over + if (m_focus == size()) { + m_focus = size() - 1; + emit_changed(); + return; + } + + // Move backward, stop at the boundary + m_focus -= i; + if (m_focus < 0 || m_focus > size()) + m_focus = size(); + emit_changed(); } diff --git a/src/core/view.h b/src/core/view.h index 837acb6b..1fe6f2be 100644 --- a/src/core/view.h +++ b/src/core/view.h @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - // Provides a filtered and sorted list of downloads that can be // updated auto-magically. // @@ -114,8 +78,11 @@ public: void set_visible(Download* download); void set_not_visible(Download* download); - void next_focus(); - void prev_focus(); + void next_focus(unsigned int i); + void prev_focus(unsigned int i); + + void next_focus() { next_focus(1); } + void prev_focus() { prev_focus(1); } void sort(); diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc index 428b786d..981829a6 100644 --- a/src/display/window_download_list.cc +++ b/src/display/window_download_list.cc @@ -15,14 +15,14 @@ namespace display { WindowDownloadList::WindowDownloadList() : - Window(new Canvas, 0, 120, 1, extent_full, extent_full), - m_view(NULL) { + Window(new Canvas, 0, 120, 1, extent_full, extent_full), + m_view(NULL) { } WindowDownloadList::~WindowDownloadList() { if (m_view != NULL) m_view->signal_changed().erase(m_changed_itr); - + m_view = NULL; } @@ -52,6 +52,27 @@ WindowDownloadList::get_attr_color(core::View::iterator selected) { return std::make_pair(m_canvas->attr_map().at(title_color) | focus_attr, title_color); } +int +WindowDownloadList::page_size(const std::string layout_name) { + // Calculate the page size for torrents. This is a public method + // because it's also used to determine the default size for page + // up/down actions. + int layout_height; + if (layout_name == "full") { + layout_height = 3; + } else if (layout_name == "compact") { + layout_height = 1; + } else { + return 0; + } + return m_canvas->height() / layout_height; +} + +int +WindowDownloadList::page_size() { + return page_size(rpc::call_command_string("ui.torrent_list.layout")); +} + void WindowDownloadList::redraw() { if (m_canvas->daemon()) @@ -64,7 +85,7 @@ WindowDownloadList::redraw() { if (m_view == NULL) return; - m_canvas->print("%s", ("[View: " + m_view->name() + (m_view->get_filter_temp().is_empty() ? "" : " (filtered)") + "]").c_str()); + m_canvas->print(0, 0, "%s", ("[View: " + m_view->name() + (m_view->get_filter_temp().is_empty() ? "" : " (filtered)") + "]").c_str()); if (m_view->empty_visible() || m_canvas->width() < 5 || m_canvas->height() < 2) return; @@ -83,19 +104,12 @@ WindowDownloadList::redraw() { int layout_height; const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout"); - if (layout_name == "full") { - layout_height = 3; - } else if (layout_name == "compact") { - layout_height = 1; - } else { - m_canvas->print(0, 0, "INVALID ui.torrent_list.layout '%s'", layout_name.c_str()); - return; - } + typedef std::pair Range; - ViewRange range = rak::advance_bidirectional(m_view->begin_visible(), - m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(), - m_view->end_visible(), - m_canvas->height() / layout_height); + Range range = rak::advance_bidirectional(m_view->begin_visible(), + m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(), + m_view->end_visible(), + page_size(layout_name)); // Make sure we properly fill out the last lines so it looks like // there are more torrents, yet don't hide it if we got the last one diff --git a/src/display/window_download_list.h b/src/display/window_download_list.h index 897d7c25..8133c4a0 100644 --- a/src/display/window_download_list.h +++ b/src/display/window_download_list.h @@ -20,6 +20,9 @@ public: void set_view(core::View* l); + int page_size(const std::string layout_name); + int page_size(); + private: core::View* m_view; diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index 90a769ab..5c92984c 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -55,8 +19,8 @@ namespace ui { ElementDownloadList::ElementDownloadList() : - m_window(NULL), - m_view(NULL) { + m_window(NULL), + m_view(NULL) { receive_change_view("main"); @@ -67,40 +31,42 @@ ElementDownloadList::ElementDownloadList() : m_bindings['\x04'] = std::bind(&ElementDownloadList::receive_command, this, "branch=d.state=,d.stop=,d.erase="); m_bindings['\x0B'] = std::bind(&ElementDownloadList::receive_command, this, "d.ignore_commands.set=1; d.stop=; d.close="); m_bindings['\x12'] = std::bind(&ElementDownloadList::receive_command, this, "d.complete.set=0; d.check_hash="); - m_bindings['\x05'] = std::bind(&ElementDownloadList::receive_command, this, - "f.multicall=,f.set_create_queued=0,f.set_resize_queued=0; print=\"Queued create/resize of files in torrent.\""); + m_bindings['\x05'] = std::bind(&ElementDownloadList::receive_command, this, "f.multicall=,f.set_create_queued=0,f.set_resize_queued=0; print=\"Queued create/resize of files in torrent.\""); - m_bindings['+'] = std::bind(&ElementDownloadList::receive_next_priority, this); - m_bindings['-'] = std::bind(&ElementDownloadList::receive_prev_priority, this); - m_bindings['T'-'@']= std::bind(&ElementDownloadList::receive_cycle_throttle, this); - m_bindings['I'] = std::bind(&ElementDownloadList::receive_command, this, - "branch=d.ignore_commands=," - "{d.ignore_commands.set=0, print=\"Torrent set to heed commands.\"}," - "{d.ignore_commands.set=1, print=\"Torrent set to ignore commands.\"}"); - m_bindings['B'-'@']= std::bind(&ElementDownloadList::receive_command, this, - "branch=d.is_active=," - "{print=\"Cannot enable initial seeding on an active download.\"}," - "{d.connection_seed.set=initial_seed, print=\"Enabled initial seeding for the selected download.\"}"); + m_bindings['+'] = std::bind(&ElementDownloadList::receive_next_priority, this); + m_bindings['-'] = std::bind(&ElementDownloadList::receive_prev_priority, this); + m_bindings['T' - '@'] = std::bind(&ElementDownloadList::receive_cycle_throttle, this); + m_bindings['I'] = std::bind(&ElementDownloadList::receive_command, this, "branch=d.ignore_commands=," + "{d.ignore_commands.set=0, print=\"Torrent set to heed commands.\"}," + "{d.ignore_commands.set=1, print=\"Torrent set to ignore commands.\"}"); + m_bindings['B' - '@'] = std::bind(&ElementDownloadList::receive_command, this, "branch=d.is_active=," + "{print=\"Cannot enable initial seeding on an active download.\"}," + "{d.connection_seed.set=initial_seed, print=\"Enabled initial seeding for the selected download.\"}"); - m_bindings['U'] = std::bind(&ElementDownloadList::receive_command, this, - "d.delete_tied=; print=\"Cleared tied to file association for the selected download.\""); + m_bindings['U'] = std::bind(&ElementDownloadList::receive_command, this, "d.delete_tied=; print=\"Cleared tied to file association for the selected download.\""); // These should also be commands. - m_bindings['1'] = std::bind(&ElementDownloadList::receive_change_view, this, "main"); - m_bindings['2'] = std::bind(&ElementDownloadList::receive_change_view, this, "name"); - m_bindings['3'] = std::bind(&ElementDownloadList::receive_change_view, this, "started"); - m_bindings['4'] = std::bind(&ElementDownloadList::receive_change_view, this, "stopped"); - m_bindings['5'] = std::bind(&ElementDownloadList::receive_change_view, this, "complete"); - m_bindings['6'] = std::bind(&ElementDownloadList::receive_change_view, this, "incomplete"); - m_bindings['7'] = std::bind(&ElementDownloadList::receive_change_view, this, "hashing"); - m_bindings['8'] = std::bind(&ElementDownloadList::receive_change_view, this, "seeding"); - m_bindings['9'] = std::bind(&ElementDownloadList::receive_change_view, this, "leeching"); - m_bindings['0'] = std::bind(&ElementDownloadList::receive_change_view, this, "active"); + m_bindings['1'] = std::bind(&ElementDownloadList::receive_change_view, this, "main"); + m_bindings['2'] = std::bind(&ElementDownloadList::receive_change_view, this, "name"); + m_bindings['3'] = std::bind(&ElementDownloadList::receive_change_view, this, "started"); + m_bindings['4'] = std::bind(&ElementDownloadList::receive_change_view, this, "stopped"); + m_bindings['5'] = std::bind(&ElementDownloadList::receive_change_view, this, "complete"); + m_bindings['6'] = std::bind(&ElementDownloadList::receive_change_view, this, "incomplete"); + m_bindings['7'] = std::bind(&ElementDownloadList::receive_change_view, this, "hashing"); + m_bindings['8'] = std::bind(&ElementDownloadList::receive_change_view, this, "seeding"); + m_bindings['9'] = std::bind(&ElementDownloadList::receive_change_view, this, "leeching"); + m_bindings['0'] = std::bind(&ElementDownloadList::receive_change_view, this, "active"); - m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::bind(&ElementDownloadList::receive_prev, this); + m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::bind(&ElementDownloadList::receive_prev, this); m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::bind(&ElementDownloadList::receive_next, this); - m_bindings['L'] = std::bind(&ElementDownloadList::toggle_layout, this); + m_bindings[KEY_PPAGE] = m_bindings['U' - '@'] = [this] { receive_pageprev(); }; + m_bindings[KEY_NPAGE] = m_bindings['H' - '@'] = [this] { receive_pagenext(); }; + + m_bindings[KEY_HOME] = m_bindings['A' - '@'] = [this] { receive_home(); }; + m_bindings[KEY_END] = m_bindings['E' - '@'] = [this] { receive_end(); }; + + m_bindings['L'] = std::bind(&ElementDownloadList::toggle_layout, this); } void @@ -172,6 +138,41 @@ ElementDownloadList::receive_prev() { m_view->set_last_changed(); } +int +ElementDownloadList::page_size() { + int rpc_page_size = rpc::call_command_value("ui.focus.page_size"); + if (rpc_page_size > 0) + return rpc_page_size; + int auto_page_size = m_window->page_size() - 1; + if (auto_page_size > 0) + return auto_page_size; + return 50; +} + +void +ElementDownloadList::receive_pagenext() { + m_view->next_focus(page_size()); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_pageprev() { + m_view->prev_focus(page_size()); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_home() { + m_view->set_focus(m_view->begin_visible()); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_end() { + m_view->set_focus(m_view->end_visible() - 1); + m_view->set_last_changed(); +} + void ElementDownloadList::receive_next_priority() { if (m_view->focus() == m_view->end_visible()) @@ -222,12 +223,10 @@ ElementDownloadList::receive_change_view(const std::string& name) { std::string old_name = view() ? view()->name() : ""; if (!old_name.empty()) - rpc::commands.call_catch("event.view.hide", rpc::make_target(), name, - "View hide event action failed: "); + rpc::commands.call_catch("event.view.hide", rpc::make_target(), name, "View hide event action failed: "); set_view(*itr); if (!old_name.empty()) - rpc::commands.call_catch("event.view.show", rpc::make_target(), old_name, - "View show event action failed: "); + rpc::commands.call_catch("event.view.show", rpc::make_target(), old_name, "View show event action failed: "); } void @@ -240,4 +239,4 @@ ElementDownloadList::toggle_layout() { rpc::call_command("ui.torrent_list.layout.set", "full"); } } -} +} // namespace ui diff --git a/src/ui/element_download_list.h b/src/ui/element_download_list.h index 5bf4f08f..67585dbc 100644 --- a/src/ui/element_download_list.h +++ b/src/ui/element_download_list.h @@ -1,43 +1,6 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef RTORRENT_UI_ELEMENT_DOWNLOAD_LIST_H #define RTORRENT_UI_ELEMENT_DOWNLOAD_LIST_H -#include "core/download_list.h" #include "display/window_download_list.h" #include "element_base.h" @@ -45,7 +8,7 @@ class Control; namespace core { - class View; +class View; } namespace ui { @@ -56,34 +19,41 @@ public: ElementDownloadList(); - void activate(display::Frame* frame, bool focus = true); - void disable(); + void activate(display::Frame* frame, bool focus = true); + void disable(); - core::View* view() { return m_view; } - void set_view(core::View* l); + core::View* view() { return m_view; } + void set_view(core::View* l); - void receive_command(const char* cmd); + void receive_command(const char* cmd); - void receive_next(); - void receive_prev(); + void receive_next(); + void receive_prev(); - void receive_stop_download(); - void receive_close_download(); + int page_size(); + void receive_pagenext(); + void receive_pageprev(); - void receive_next_priority(); - void receive_prev_priority(); + void receive_home(); + void receive_end(); - void receive_cycle_throttle(); + void receive_stop_download(); + void receive_close_download(); - void receive_change_view(const std::string& name); + void receive_next_priority(); + void receive_prev_priority(); - void toggle_layout(); + void receive_cycle_throttle(); + + void receive_change_view(const std::string& name); + + void toggle_layout(); private: - WDownloadList* m_window; - core::View* m_view; + WDownloadList* m_window; + core::View* m_view; }; -} +} // namespace ui #endif