mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-07 22:59:21 +00:00
All patches in this commit were from Josef Drexler.
* Fixes a segfault when configure finds execinfo.h. * Fix compile errors and warnings with g++ 4.3.x. * Fixes an interoperability issue in the get_peers handling, now it behaves according to the clarified BEP-0005. Also fixes a minor issue of not being able to generate error packets. * Fix a crash in scgi_local or scgi_port when calling freeaddrinfo with a NULL pointer. * Only check the filename cache for loading tied torrents (e.g. from watch dirs) but not manually loaded ones via <enter>/<bs>, to allow loading those again (ticket #1227). * Fix display of multi-byte characters with attributes (i.e. utf-8 filenames in the file list), and make the list aware of characters occupying two screen positions. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1064 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#ifndef RAK_FUNCTIONAL_H
|
||||
#define RAK_FUNCTIONAL_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
namespace rak {
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ AC_DEFUN([TORRENT_CHECK_MADVISE], [
|
||||
AC_DEFUN([TORRENT_CHECK_EXECINFO], [
|
||||
AC_MSG_CHECKING(for execinfo.h)
|
||||
|
||||
AC_RUN_IFELSE(
|
||||
AC_LINK_IFELSE(
|
||||
[[#include <execinfo.h>
|
||||
int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
|
||||
]],
|
||||
|
||||
@@ -261,10 +261,10 @@ apply_scgi(const std::string& arg, int type) {
|
||||
break;
|
||||
}
|
||||
|
||||
rak::address_info::free_address_info(ai);
|
||||
if (ai != NULL) rak::address_info::free_address_info(ai);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
rak::address_info::free_address_info(ai);
|
||||
if (ai != NULL) rak::address_info::free_address_info(ai);
|
||||
|
||||
throw torrent::input_error(e.what());
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <rak/functional.h>
|
||||
#include <rak/functional_fun.h>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
|
||||
@@ -84,11 +84,12 @@ Download::~Download() {
|
||||
void
|
||||
Download::enable_udp_trackers(bool state) {
|
||||
for (torrent::TrackerList::iterator itr = m_download.tracker_list()->begin(), last = m_download.tracker_list()->end(); itr != last; ++itr)
|
||||
if ((*itr)->type() == torrent::Tracker::TRACKER_UDP)
|
||||
if ((*itr)->type() == torrent::Tracker::TRACKER_UDP) {
|
||||
if (state)
|
||||
(*itr)->enable();
|
||||
else
|
||||
(*itr)->disable();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
@@ -71,11 +71,12 @@ DownloadStore::enable(bool lock) {
|
||||
else
|
||||
m_lockfile.set_path(std::string());
|
||||
|
||||
if (!m_lockfile.try_lock())
|
||||
if (!m_lockfile.try_lock()) {
|
||||
if (rak::error_number::current().is_bad_path())
|
||||
throw torrent::input_error("Could not lock session directory: \"" + m_path + "\", " + rak::error_number::current().c_str());
|
||||
else
|
||||
throw torrent::input_error("Could not lock session directory: \"" + m_path + "\", held by \"" + m_lockfile.locked_by_as_string() + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+2
-1
@@ -383,7 +383,8 @@ Manager::receive_http_failed(std::string msg) {
|
||||
void
|
||||
Manager::try_create_download(const std::string& uri, int flags, const command_list_type& commands) {
|
||||
// If the path was attempted loaded before, skip it.
|
||||
if (!(flags & create_raw_data) &&
|
||||
if ((flags & create_tied) &&
|
||||
!(flags & create_raw_data) &&
|
||||
!is_network_uri(uri) &&
|
||||
!file_status_cache()->insert(uri, 0))
|
||||
return;
|
||||
|
||||
+18
-4
@@ -57,17 +57,31 @@ void
|
||||
Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) {
|
||||
move(x, y);
|
||||
|
||||
attr_t org_attr;
|
||||
short org_pair;
|
||||
wattr_get(m_window, &org_attr, &org_pair, NULL);
|
||||
|
||||
attributes_list::const_iterator attrItr = attributes->begin();
|
||||
Attributes current = Attributes(first, Attributes::a_normal, Attributes::color_default);
|
||||
wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL);
|
||||
|
||||
while (first != last) {
|
||||
if (attrItr != attributes->end() && first >= attrItr->position())
|
||||
current = *attrItr++;
|
||||
const char* next = last;
|
||||
|
||||
waddch(m_window, *first++ | current.attributes());
|
||||
if (attrItr != attributes->end()) {
|
||||
next = attrItr->position();
|
||||
|
||||
if (first >= next) {
|
||||
wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL);
|
||||
++attrItr;
|
||||
}
|
||||
}
|
||||
|
||||
print("%.*s", next - first, first);
|
||||
first = next;
|
||||
}
|
||||
|
||||
// Reset the color.
|
||||
wattr_set(m_window, org_attr, org_pair, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
// since the string shall always be a C string choosen at
|
||||
// compiletime. Might cause extra copying of the string?
|
||||
|
||||
void print(const char* str, ...);
|
||||
void print(unsigned int x, unsigned int y, const char* str, ...);
|
||||
|
||||
void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes);
|
||||
@@ -95,6 +96,8 @@ public:
|
||||
|
||||
void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { mvwchgat(m_window, y, x, n, attr, color, NULL); }
|
||||
|
||||
void set_default_attributes(int attr) { wattrset(m_window, attr); }
|
||||
|
||||
// Initialize stdscr.
|
||||
static void initialize();
|
||||
static void cleanup();
|
||||
@@ -115,6 +118,15 @@ private:
|
||||
WINDOW* m_window;
|
||||
};
|
||||
|
||||
inline void
|
||||
Canvas::print(const char* str, ...) {
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, str);
|
||||
vw_printw(m_window, const_cast<char*>(str), arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::print(unsigned int x, unsigned int y, const char* str, ...) {
|
||||
va_list arglist;
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "globals.h"
|
||||
#include "text_element_value.h"
|
||||
|
||||
|
||||
@@ -57,22 +57,61 @@ WindowFileList::WindowFileList(const ui::ElementFileList* element) :
|
||||
m_element(element) {
|
||||
}
|
||||
|
||||
/*
|
||||
// Convert std::string to std::wstring of given width (in screen positions),
|
||||
// taking into account that some characters may be occupying two screen positions.
|
||||
std::wstring
|
||||
hack_wstring(const std::string& src) {
|
||||
size_t length = ::mbstowcs(NULL, src.c_str(), src.size());
|
||||
wstring_width(const std::string& i_str, int width) {
|
||||
wchar_t result[width + 1];
|
||||
size_t length = std::mbstowcs(result, i_str.c_str(), width);
|
||||
|
||||
if (length == (size_t)-1)
|
||||
return std::wstring(L"<invalid>");
|
||||
// If not valid UTF-8 encoding, at least copy the printable characters.
|
||||
if (length == (size_t)-1) {
|
||||
wchar_t* out = result;
|
||||
|
||||
std::wstring dest;
|
||||
dest.resize(length);
|
||||
|
||||
::mbstowcs(&*dest.begin(), src.c_str(), src.size());
|
||||
for (std::string::const_iterator itr = i_str.begin(); itr != i_str.end(); ++itr)
|
||||
if (!std::isprint(*itr, std::locale::classic()))
|
||||
*out++ = '?';
|
||||
else
|
||||
*out++ = *itr;
|
||||
|
||||
return dest;
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
int swidth = wcswidth(result, width);
|
||||
|
||||
// Limit to width if it's too wide already.
|
||||
if (swidth == -1 || swidth > width) {
|
||||
length = swidth = 0;
|
||||
|
||||
while (result[length]) {
|
||||
int next = ::wcwidth(result[length]);
|
||||
|
||||
// Unprintable character?
|
||||
if (next == -1) {
|
||||
result[length] = '?';
|
||||
next = 1;
|
||||
}
|
||||
|
||||
if (swidth + next > width) {
|
||||
result[length] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
length++;
|
||||
swidth += next;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad with spaces to given width.
|
||||
while (swidth < width && length <= (unsigned int)width) {
|
||||
result[length++] = ' ';
|
||||
swidth++;
|
||||
}
|
||||
|
||||
result[length] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
WindowFileList::redraw() {
|
||||
@@ -115,6 +154,8 @@ WindowFileList::redraw() {
|
||||
}
|
||||
|
||||
unsigned int pos = 0;
|
||||
int filenameWidth = m_canvas->width() - 16;
|
||||
|
||||
m_canvas->print(0, pos++, "Cmp Pri Size Filename");
|
||||
|
||||
while (pos != m_canvas->height()) {
|
||||
@@ -123,20 +164,19 @@ WindowFileList::redraw() {
|
||||
if (itr == iterator(fl->end()))
|
||||
break;
|
||||
|
||||
m_canvas->set_default_attributes(itr == m_element->selected() ? is_focused() ? A_REVERSE : A_BOLD : A_NORMAL);
|
||||
|
||||
if (itr.is_empty()) {
|
||||
m_canvas->print(16, pos, "EMPTY");
|
||||
m_canvas->print(0, pos, "%*c%-*s", 16, ' ', filenameWidth, "EMPTY");
|
||||
|
||||
} else if (itr.is_entering()) {
|
||||
m_canvas->print(16 + itr.depth(), pos, "\\ %s",
|
||||
itr.depth() < (*itr)->path()->size() ? (*itr)->path()->at(itr.depth()).c_str() : "UNKNOWN");
|
||||
m_canvas->print(0, pos, "%*c %ls", 16 + itr.depth(), '\\',
|
||||
itr.depth() < (*itr)->path()->size() ? wstring_width((*itr)->path()->at(itr.depth()), filenameWidth - itr.depth() - 1).c_str() : L"UNKNOWN");
|
||||
|
||||
} else if (itr.is_leaving()) {
|
||||
m_canvas->print(16 + itr.depth() - 1, pos, "/");
|
||||
m_canvas->print(0, pos, "%*c %-*s", 16 + (itr.depth() - 1), '/', filenameWidth - (itr.depth() - 1), "");
|
||||
|
||||
} else if (itr.is_file()) {
|
||||
char buffer[std::max<unsigned int>(m_canvas->width() + 1, 256)];
|
||||
Canvas::attributes_list attributes;
|
||||
|
||||
torrent::File* e = *itr;
|
||||
|
||||
const char* priority;
|
||||
@@ -148,33 +188,26 @@ WindowFileList::redraw() {
|
||||
default: priority = "BUG"; break;
|
||||
};
|
||||
|
||||
sprintf(buffer, "%3d %s ", done_percentage(e), priority);
|
||||
m_canvas->print(0, pos, "%3d %s ", done_percentage(e), priority);
|
||||
|
||||
int64_t val = e->size_bytes();
|
||||
|
||||
if (val < (int64_t(1000) << 20))
|
||||
sprintf(buffer + 8, "%5.1f M", (double)val / (int64_t(1) << 20));
|
||||
if (val < (int64_t(1000) << 10))
|
||||
m_canvas->print(8, pos, "%5.1f K", (double)val / (int64_t(1) << 10));
|
||||
else if (val < (int64_t(1000) << 20))
|
||||
m_canvas->print(8, pos, "%5.1f M", (double)val / (int64_t(1) << 20));
|
||||
else if (val < (int64_t(1000) << 30))
|
||||
sprintf(buffer + 8, "%5.1f G", (double)val / (int64_t(1) << 30));
|
||||
m_canvas->print(8, pos, "%5.1f G", (double)val / (int64_t(1) << 30));
|
||||
else
|
||||
sprintf(buffer + 8, "%5.1f T", (double)val / (int64_t(1) << 40));
|
||||
m_canvas->print(8, pos, "%5.1f T", (double)val / (int64_t(1) << 40));
|
||||
|
||||
std::fill_n(buffer + 15, 64, ' ');
|
||||
|
||||
int first = 16 + std::min<unsigned int>(itr.depth(), 8);
|
||||
int last = std::max<unsigned int>(m_canvas->width() + 1, 16 + 12);
|
||||
|
||||
snprintf(buffer + first, last - first, "| %s",
|
||||
itr.depth() < (*itr)->path()->size() ? (*itr)->path()->at(itr.depth()).c_str() : "UNKNOWN");
|
||||
|
||||
m_canvas->print_attributes(0, pos, buffer, buffer + std::strlen(buffer), &attributes);
|
||||
m_canvas->print(15, pos, "%*c %ls", 1 + itr.depth(), '|',
|
||||
itr.depth() < (*itr)->path()->size() ? wstring_width((*itr)->path()->at(itr.depth()), filenameWidth - itr.depth() - 1).c_str() : L"UNKNOWN");
|
||||
|
||||
} else {
|
||||
m_canvas->print(0, pos, "BORK BORK");
|
||||
}
|
||||
|
||||
if (itr == m_element->selected())
|
||||
m_canvas->set_attr(0, pos, m_canvas->width(), is_focused() ? A_REVERSE : A_BOLD, COLOR_PAIR(0));
|
||||
m_canvas->set_default_attributes(A_NORMAL);
|
||||
|
||||
pos++;
|
||||
first = (first + 1) % (m_canvas->height() - 1);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <locale>
|
||||
#include <rak/path.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
Reference in New Issue
Block a user