diff options
Diffstat (limited to 'ui_pyroscope.cc')
-rw-r--r-- | ui_pyroscope.cc | 111 |
1 files changed, 87 insertions, 24 deletions
diff --git a/ui_pyroscope.cc b/ui_pyroscope.cc index 06db8c6725c7..d9dd1edd00a8 100644 --- a/ui_pyroscope.cc +++ b/ui_pyroscope.cc @@ -385,35 +385,38 @@ torrent::Object ui_canvas_color_set(const torrent::Object::string_type& arg) { int64_t cmd_d_message_alert(core::Download* d) { int64_t alert = ps::ALERT_NORMAL; + const std::string& msg = d->message(); - if (!d->message().empty()) { + if (!msg.empty()) { alert = ps::ALERT_GENERIC; - if (d->message().find("Tried all trackers") != std::string::npos) + if (msg.find("Tried all trackers") != std::string::npos) alert = ps::ALERT_NORMAL_CYCLING; - else if (d->message().find("Timeout was reached") != std::string::npos - || d->message().find("Timed out") != std::string::npos) + else if (msg.find("no data") != std::string::npos) + alert = ps::ALERT_NORMAL_GHOST; + else if (msg.find("Timeout was reached") != std::string::npos + || msg.find("Timed out") != std::string::npos) alert = ps::ALERT_TIMEOUT; - else if (d->message().find("Connecting to") != std::string::npos) + else if (msg.find("Connecting to") != std::string::npos) alert = ps::ALERT_CONNECT; - else if (d->message().find("Could not parse bencoded data") != std::string::npos - || d->message().find("Failed sending data") != std::string::npos - || d->message().find("Server returned nothing") != std::string::npos - || d->message().find("Couldn't connect to server") != std::string::npos) + else if (msg.find("Could not parse bencoded data") != std::string::npos + || msg.find("Failed sending data") != std::string::npos + || msg.find("Server returned nothing") != std::string::npos + || msg.find("Couldn't connect to server") != std::string::npos) alert = ps::ALERT_REQUEST; - else if (d->message().find("not registered") != std::string::npos - || d->message().find("torrent cannot be found") != std::string::npos - || d->message().find("nregistered") != std::string::npos) + else if (msg.find("not registered") != std::string::npos + || msg.find("torrent cannot be found") != std::string::npos + || msg.find("nregistered") != std::string::npos) alert = ps::ALERT_GONE; - else if (d->message().find("not authorized") != std::string::npos - || d->message().find("blocked from") != std::string::npos - || d->message().find("denied") != std::string::npos - || d->message().find("limit exceeded") != std::string::npos - || d->message().find("active torrents are enough") != std::string::npos) + else if (msg.find("not authorized") != std::string::npos + || msg.find("blocked from") != std::string::npos + || msg.find("denied") != std::string::npos + || msg.find("limit exceeded") != std::string::npos + || msg.find("active torrents are enough") != std::string::npos) alert = ps::ALERT_PERMS; - else if (d->message().find("tracker is down") != std::string::npos) + else if (msg.find("tracker is down") != std::string::npos) alert = ps::ALERT_DOWN; - else if (d->message().find("n't resolve host name") != std::string::npos) + else if (msg.find("n't resolve host name") != std::string::npos) alert = ps::ALERT_DNS; } @@ -438,7 +441,7 @@ torrent::Object cmd_d_tracker_alias(core::Download* download) { static void decorate_download_title(Window* window, display::Canvas* canvas, core::View* view, - int pos, Range& range, int x_title) { + int pos, Range& range, int x_title, size_t hilite, size_t hilen) { int offset = row_offset(view, range); core::Download* item = *range.first; bool active = item->is_open() && item->is_active(); @@ -455,6 +458,10 @@ static void decorate_download_title(Window* window, display::Canvas* canvas, cor title_col = (active ? D_INFO(item)->down_rate()->rate() ? ps::COL_LEECHING : ps::COL_INCOMPLETE : ps::COL_QUEUED) + offset; canvas->set_attr(x_title, pos, -1, attr_map[title_col] | focus_attr, title_col); + if (hilen && hilite != std::string::npos && x_title + hilite < int(canvas->width())) { + canvas->set_attr(x_title + hilite, pos, std::min(hilen, int(canvas->width()) - x_title - hilite), + (attr_map[title_col] | focus_attr | A_REVERSE) ^ A_BOLD, title_col); + } // show label for active tracker (a/k/a in focus tracker) if (int(canvas->width()) <= x_title + NAME_RESERVED_WIDTH + 3) return; @@ -505,7 +512,7 @@ void ui_pyroscope_download_list_redraw_item(Window* window, display::Canvas* can } } - decorate_download_title(window, canvas, view, pos, range, 2); + decorate_download_title(window, canvas, view, pos, range, 2, -1, 0); // better handling for trail of line 2 (ratio etc.) int status_pos = 91; @@ -763,7 +770,8 @@ int render_columns(bool headers, bool narrow, rpc::target_type target, core::Dow case ps::COL_ALERT: // COL_ALARM is the actual color, this is the dynamic one bool has_alert = !item->message().empty() && item->message().find("Tried all trackers") == std::string::npos; - attr_idx = has_alert ? ps::COL_ALARM : ps::COL_INFO; + bool no_data = item->message().find("no data") != std::string::npos; + attr_idx = no_data ? ps::COL_PROGRESS0 : has_alert ? ps::COL_ALARM : ps::COL_INFO; break; } } @@ -810,6 +818,8 @@ bool ui_pyroscope_download_list_redraw(Window* window, display::Canvas* canvas, const torrent::Object::map_type& column_defs = control->object_storage()->get_str("ui.column.render").as_map(); int pos = 1, x_base = 2, column = x_base; bool narrow = false; + std::string find_term = rpc::call_command_string("ui.find.term"); + std::transform(find_term.begin(), find_term.end(), find_term.begin(), ::tolower); // Render header line canvas->print(0, pos, "⇳ "); @@ -864,7 +874,13 @@ bool ui_pyroscope_download_list_redraw(Window* window, display::Canvas* canvas, canvas->print(column, pos, " %s", u8_chop(displayname.empty() ? d->info()->name() : displayname.c_str(), canvas->width() - column - 1).c_str()); - decorate_download_title(window, canvas, view, pos, range, column + 1); + size_t hilite = std::string::npos; + if (!find_term.empty()) { + if (displayname.empty()) displayname = d->info()->name(); + std::transform(displayname.begin(), displayname.end(), displayname.begin(), ::tolower); + hilite = displayname.find(find_term); + } + decorate_download_title(window, canvas, view, pos, range, column + 1, hilite, find_term.length()); } // Colorize focus marker @@ -1054,6 +1070,46 @@ torrent::Object apply_magnitude(const torrent::Object::list_type& args) { } +torrent::Object ui_find_next() { + std::string term = rpc::call_command_string("ui.find.term"); + if (term.empty()) + return torrent::Object(); // no current search term set + std::transform(term.begin(), term.end(), term.begin(), ::tolower); + + ui::DownloadList* dl_list = control->ui()->download_list(); + core::View* dl_view = dl_list->current_view(); + + if (dl_view->empty_visible()) { + control->core()->push_log("This view is empty, nothing to find!"); + } else { + core::View::iterator itr = dl_view->focus() == dl_view->end_visible() ? + dl_view->begin_visible() : dl_view->focus(); + bool found = false; + + do { + if (++itr == dl_view->end_visible()) + itr = dl_view->begin_visible(); + + // In C++11, this can be done more efficiently using std::search; + // we only use this interactively, so meh. + std::string name = get_custom_string(*itr, "displayname"); + if (name.empty()) name = (*itr)->info()->name(); + std::transform(name.begin(), name.end(), name.begin(), ::tolower); + found = name.find(term) != std::string::npos; + } while (!found && itr != dl_view->focus()); + + if (!found) { + control->core()->push_log(("Cannot find anything matching '" + term + "'").c_str()); + } else if (itr != dl_view->focus()) { + dl_view->set_focus(itr); + dl_view->set_last_changed(); + } + } + + return torrent::Object(); +} + + // register our commands void initialize_command_ui_pyroscope() { #define PS_VARIABLE_COLOR(key, value) \ @@ -1091,6 +1147,9 @@ void initialize_command_ui_pyroscope() { CMD2_ANY("ui.column.sacrificial.list", _cxxstd_::bind(&display::ui_column_sacrificial_list)); CMD2_VAR_VALUE("ui.column.sacrificed", 0); + CMD2_ANY ("ui.find.next", _cxxstd_::bind(&ui_find_next)); + CMD2_VAR_STRING("ui.find.term", ""); + PS_VARIABLE_COLOR("ui.color.progress0", "red"); PS_VARIABLE_COLOR("ui.color.progress20", "bold bright red"); PS_VARIABLE_COLOR("ui.color.progress40", "bold bright magenta"); @@ -1162,6 +1221,10 @@ void initialize_command_ui_pyroscope() { "schedule2 = collapsed_view_toggle, 0, 0, ((ui.bind_key, download_list, *, \"" "view.collapsed.toggle= ; ui.current_view.set = (ui.current_view)\"))\n" + // Bind 'F' / F3 to find the next item for 'ui.find.term' + "schedule2 = ui_find_next_f, 0, 0, ((ui.bind_key, download_list, F, \"ui.find.next=\"))\n" + "schedule2 = ui_find_next_f3, 0, 0, ((ui.bind_key, download_list, 0413, \"ui.find.next=\"))\n" + // Collapse built-in views "view.collapsed.toggle = main\n" "view.collapsed.toggle = name\n" @@ -1213,7 +1276,7 @@ void initialize_command_ui_pyroscope() { // Status flags (❢ ☢ ☍ ⌘) "method.set_key = ui.column.render, \"100:3C95/2:❢ \"," - " ((array.at, {\" \", \"♺ \", \"⚠ \", \"◔ \", \"⚡ \", \"↯ \", \"¿?\"," + " ((array.at, {\" \", \"♺ \", \"ʘ \", \"⚠ \", \"◔ \", \"⚡ \", \"↯ \", \"¿?\"," " \"⨂ \", \"⋫ \", \"☡ \"}, ((d.message.alert)) ))\n" "method.set_key = ui.column.render, \"110:2C92/2:☢ \"," " ((string.map, ((cat, ((d.is_open)), ((d.is_active)))), {00, \"▪ \"}, {01, \"▪ \"}, {10, \"╍ \"}, {11, \"▹ \"}))\n" |