mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 21:22:31 +00:00
* Added FileListIterator to the API, which allows the client to
iterate through FileList as if it consisted of directories. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@831 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -91,6 +91,28 @@ advance_bidirectional(_InputIter __first, _InputIter __middle1, _InputIter __las
|
||||
return std::make_pair(__middle1, __middle2);
|
||||
}
|
||||
|
||||
template <typename _InputIter, typename _Distance>
|
||||
_InputIter
|
||||
advance_forward(_InputIter __first, _InputIter __last, _Distance __distance) {
|
||||
while (__first != __last && __distance != 0) {
|
||||
__first++;
|
||||
__distance--;
|
||||
}
|
||||
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <typename _InputIter, typename _Distance>
|
||||
_InputIter
|
||||
advance_backward(_InputIter __first, _InputIter __last, _Distance __distance) {
|
||||
while (__first != __last && __distance != 0) {
|
||||
__first--;
|
||||
__distance--;
|
||||
}
|
||||
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <typename _Value>
|
||||
struct compare_base : public std::binary_function<_Value, _Value, bool> {
|
||||
bool operator () (const _Value& complete, const _Value& base) const {
|
||||
@@ -133,6 +155,8 @@ make_base(_InputIter __first, _InputIter __last) {
|
||||
return __base;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <torrent/path.h>
|
||||
#include <torrent/data/file.h>
|
||||
#include <torrent/data/file_list.h>
|
||||
#include <torrent/data/file_list_iterator.h>
|
||||
|
||||
#include "core/download.h"
|
||||
|
||||
@@ -48,7 +49,7 @@
|
||||
|
||||
namespace display {
|
||||
|
||||
WindowFileList::WindowFileList(core::Download* d, unsigned int* focus) :
|
||||
WindowFileList::WindowFileList(core::Download* d, iterator* focus) :
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_focus(focus) {
|
||||
@@ -71,72 +72,6 @@ hack_wstring(const std::string& src) {
|
||||
}
|
||||
*/
|
||||
|
||||
// A special purpose iterator class for iterating through FileList as
|
||||
// a dired structure.
|
||||
class file_path_iterator {
|
||||
public:
|
||||
typedef torrent::FileList::iterator iterator;
|
||||
typedef torrent::File& reference;
|
||||
typedef torrent::File* pointer;
|
||||
|
||||
file_path_iterator() {}
|
||||
explicit file_path_iterator(iterator pos, uint32_t depth = 0) : m_position(pos), m_depth(depth) {}
|
||||
|
||||
bool is_file() const { return m_depth >= 0 && m_depth + 1 == (int32_t)(*m_position)->path()->size(); }
|
||||
bool is_empty() const { return (*m_position)->path()->size() == 0; }
|
||||
|
||||
bool is_entering() const { return m_depth >= 0 && m_depth + 1 != (int32_t)(*m_position)->path()->size(); }
|
||||
bool is_leaving() const { return m_depth < 0; }
|
||||
|
||||
uint32_t depth() const { return std::abs(m_depth); }
|
||||
|
||||
iterator base() const { return m_position; }
|
||||
|
||||
reference operator *() const { return **m_position; }
|
||||
pointer operator ->() const { return *m_position; }
|
||||
|
||||
file_path_iterator operator ++();
|
||||
|
||||
friend bool operator == (const file_path_iterator& left, const file_path_iterator& right);
|
||||
friend bool operator != (const file_path_iterator& left, const file_path_iterator& right);
|
||||
|
||||
private:
|
||||
iterator m_position;
|
||||
int32_t m_depth;
|
||||
};
|
||||
|
||||
file_path_iterator
|
||||
file_path_iterator::operator ++() {
|
||||
int32_t sizePath = (*m_position)->path()->size();
|
||||
|
||||
if (sizePath == 0) {
|
||||
m_position++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_depth++;
|
||||
|
||||
if (m_depth == sizePath)
|
||||
m_depth = -m_depth + 1;
|
||||
|
||||
if (-m_depth == (int32_t)(*m_position)->match_depth_next()) {
|
||||
m_depth = -m_depth;
|
||||
m_position++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
operator == (const file_path_iterator& left, const file_path_iterator& right) {
|
||||
return left.m_position == right.m_position && left.m_depth == right.m_depth;
|
||||
}
|
||||
|
||||
bool
|
||||
operator != (const file_path_iterator& left, const file_path_iterator& right) {
|
||||
return left.m_position != right.m_position || left.m_depth != right.m_depth;
|
||||
}
|
||||
|
||||
void
|
||||
WindowFileList::redraw() {
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(10)).round_seconds());
|
||||
@@ -158,27 +93,30 @@ WindowFileList::redraw() {
|
||||
|
||||
++pos;
|
||||
|
||||
if (*m_focus >= fl->size_files())
|
||||
throw std::logic_error("WindowFileList::redraw() called on an object with a bad focus value");
|
||||
// if (m_focus->first >= fl->size_files() || m_focus->second >= (*(fl->begin() + m_focus->first))->path()->size())
|
||||
// throw torrent::internal_error("WindowFileList::redraw() called on an object with a bad focus value.");
|
||||
|
||||
std::pair<unsigned int, unsigned int> range = rak::advance_bidirectional<unsigned int>(0, *m_focus, fl->size_files(), m_canvas->height() - pos);
|
||||
// std::pair<unsigned int, unsigned int> range = rak::advance_bidirectional<unsigned int>(0, *m_focus, fl->size_files(), m_canvas->height() - pos);
|
||||
|
||||
file_path_iterator first(fl->begin() + range.first, (*(fl->begin() + range.first))->match_depth_prev());
|
||||
file_path_iterator last(fl->end());
|
||||
// iterator first(fl->begin() + range.first, (*(fl->begin() + range.first))->match_depth_prev());
|
||||
// iterator last(fl->end());
|
||||
|
||||
while (pos != m_canvas->height() && first != last) {
|
||||
if (first.is_empty()) {
|
||||
std::pair<iterator, iterator> range =
|
||||
rak::advance_bidirectional<iterator>(iterator(fl->begin()), *m_focus, iterator(fl->end()), m_canvas->height() - pos);
|
||||
|
||||
while (pos != m_canvas->height() && range.first != range.second) {
|
||||
if (range.first.is_empty()) {
|
||||
m_canvas->print(0, pos, "EMPTY");
|
||||
|
||||
} else if (first.is_entering()) {
|
||||
m_canvas->print(first.depth(), pos, "\\ %s",
|
||||
first.depth() < first->path()->size() ? first->path()->at(first.depth()).c_str() : "UNKNOWN");
|
||||
} else if (range.first.is_entering()) {
|
||||
m_canvas->print(range.first.depth(), pos, "\\ %s",
|
||||
range.first.depth() < (*range.first)->path()->size() ? (*range.first)->path()->at(range.first.depth()).c_str() : "UNKNOWN");
|
||||
|
||||
} else if (first.is_leaving()) {
|
||||
m_canvas->print(first.depth(), pos, "/");
|
||||
} else if (range.first.is_leaving()) {
|
||||
m_canvas->print(range.first.depth(), pos, "/");
|
||||
|
||||
} else if (first.is_file()) {
|
||||
torrent::File* e = &*first;
|
||||
} else if (range.first.is_file()) {
|
||||
torrent::File* e = *range.first;
|
||||
|
||||
std::string priority;
|
||||
|
||||
@@ -200,8 +138,8 @@ WindowFileList::redraw() {
|
||||
break;
|
||||
};
|
||||
|
||||
m_canvas->print(first.depth(), pos, "| %s",
|
||||
first.depth() < first->path()->size() ? first->path()->at(first.depth()).c_str() : "UNKNOWN");
|
||||
m_canvas->print(range.first.depth(), pos, "| %s",
|
||||
range.first.depth() < (*range.first)->path()->size() ? (*range.first)->path()->at(range.first.depth()).c_str() : "UNKNOWN");
|
||||
|
||||
// %6.1f %s %3d %9s",
|
||||
// (double)e->size_bytes() / (double)(1 << 20),
|
||||
@@ -221,7 +159,7 @@ WindowFileList::redraw() {
|
||||
m_canvas->print(0, pos, "BORK BORK");
|
||||
}
|
||||
|
||||
++first;
|
||||
++range.first;
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
namespace torrent {
|
||||
class File;
|
||||
class FileListIterator;
|
||||
}
|
||||
|
||||
namespace core {
|
||||
@@ -53,16 +54,17 @@ namespace display {
|
||||
|
||||
class WindowFileList : public Window {
|
||||
public:
|
||||
WindowFileList(core::Download* d, unsigned int* focus);
|
||||
typedef torrent::FileListIterator iterator;
|
||||
|
||||
virtual void redraw();
|
||||
WindowFileList(core::Download* d, iterator* focus);
|
||||
|
||||
virtual void redraw();
|
||||
|
||||
private:
|
||||
int done_percentage(torrent::File* e);
|
||||
int done_percentage(torrent::File* e);
|
||||
|
||||
core::Download* m_download;
|
||||
|
||||
unsigned int* m_focus;
|
||||
core::Download* m_download;
|
||||
iterator* m_focus;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+33
-46
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <rak/algorithm.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/data/file.h>
|
||||
#include <torrent/data/file_list.h>
|
||||
@@ -53,7 +54,7 @@ namespace ui {
|
||||
ElementFileList::ElementFileList(core::Download* d) :
|
||||
m_download(d),
|
||||
m_window(NULL),
|
||||
m_focus(0) {
|
||||
m_focus(iterator(d->download()->file_list()->begin())) {
|
||||
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = sigc::mem_fun(&m_slotExit, &slot_type::operator());
|
||||
|
||||
@@ -104,47 +105,38 @@ ElementFileList::window() {
|
||||
|
||||
void
|
||||
ElementFileList::receive_next() {
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("ui::ElementFileList::receive_next(...) called on a disabled object");
|
||||
torrent::FileList* fl = m_download->download()->file_list();
|
||||
|
||||
if (++m_focus >= m_download->download()->file_list()->size_files())
|
||||
m_focus = 0;
|
||||
if (m_focus == iterator(fl->end()) || ++m_focus == iterator(fl->end()))
|
||||
m_focus = iterator(fl->begin());
|
||||
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
ElementFileList::receive_prev() {
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
|
||||
|
||||
torrent::FileList* fl = m_download->download()->file_list();
|
||||
|
||||
if (fl->size_files() == 0)
|
||||
return;
|
||||
|
||||
if (m_focus != 0)
|
||||
--m_focus;
|
||||
else
|
||||
m_focus = fl->size_files() - 1;
|
||||
if (m_focus == iterator(fl->begin()))
|
||||
m_focus = iterator(fl->end());
|
||||
|
||||
m_focus--;
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
ElementFileList::receive_pagenext() {
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("ui::ElementFileList::receive_pagenext(...) called on a disabled object");
|
||||
|
||||
unsigned int count = (m_window->height() - 1) / 2;
|
||||
torrent::FileList* fl = m_download->download()->file_list();
|
||||
|
||||
if (m_focus + count < fl->size_files())
|
||||
m_focus += count;
|
||||
else if (m_focus == fl->size_files() - 1)
|
||||
m_focus = 0;
|
||||
else
|
||||
m_focus = fl->size_files() - 1;
|
||||
if (m_focus == --iterator(fl->end())) {
|
||||
m_focus = iterator(fl->begin());
|
||||
|
||||
} else {
|
||||
m_focus = rak::advance_forward(m_focus, iterator(fl->end()), (m_window->height() - 1) / 2);
|
||||
|
||||
if (m_focus == iterator(fl->end()))
|
||||
m_focus = --iterator(fl->end());
|
||||
}
|
||||
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
@@ -156,17 +148,10 @@ ElementFileList::receive_pageprev() {
|
||||
|
||||
torrent::FileList* fl = m_download->download()->file_list();
|
||||
|
||||
if (fl->size_files() == 0)
|
||||
return;
|
||||
|
||||
unsigned int count = (m_window->height() - 1) / 2;
|
||||
|
||||
if (m_focus > count)
|
||||
m_focus -= count;
|
||||
else if (m_focus == 0)
|
||||
m_focus = fl->size_files() - 1;
|
||||
if (m_focus == iterator(fl->begin()))
|
||||
m_focus = --iterator(fl->end());
|
||||
else
|
||||
m_focus = 0;
|
||||
m_focus = rak::advance_backward(m_focus, iterator(fl->begin()), (m_window->height() - 1) / 2);
|
||||
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
@@ -176,14 +161,16 @@ ElementFileList::receive_priority() {
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
|
||||
|
||||
torrent::FileList* fl = m_download->download()->file_list();
|
||||
// Fix priorities.
|
||||
|
||||
if (m_focus >= fl->size_files())
|
||||
return;
|
||||
// torrent::FileList* fl = m_download->download()->file_list();
|
||||
|
||||
torrent::File* file = *(fl->begin() + m_focus);
|
||||
// if (m_focus >= fl->size_files())
|
||||
// return;
|
||||
|
||||
file->set_priority(next_priority(file->priority()));
|
||||
// torrent::File* file = *(fl->begin() + m_focus);
|
||||
|
||||
// file->set_priority(next_priority(file->priority()));
|
||||
|
||||
m_download->download()->update_priorities();
|
||||
m_window->mark_dirty();
|
||||
@@ -194,15 +181,15 @@ ElementFileList::receive_change_all() {
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("ui::ElementFileList::receive_prev(...) called on a disabled object");
|
||||
|
||||
torrent::FileList* fl = m_download->download()->file_list();
|
||||
// torrent::FileList* fl = m_download->download()->file_list();
|
||||
|
||||
if (m_focus >= fl->size_files())
|
||||
return;
|
||||
// if (m_focus >= fl->size_files())
|
||||
// return;
|
||||
|
||||
Priority p = next_priority((*(fl->begin() + m_focus))->priority());
|
||||
// Priority p = next_priority((*(fl->begin() + m_focus))->priority());
|
||||
|
||||
for (torrent::FileList::iterator itr = fl->begin(), last = fl->end(); itr != last; ++itr)
|
||||
(*itr)->set_priority(p);
|
||||
// for (torrent::FileList::iterator itr = fl->begin(), last = fl->end(); itr != last; ++itr)
|
||||
// (*itr)->set_priority(p);
|
||||
|
||||
m_download->download()->update_priorities();
|
||||
m_window->mark_dirty();
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define RTORRENT_UI_ELEMENT_FILE_LIST_H
|
||||
|
||||
#include <torrent/common.h>
|
||||
#include <torrent/data/file_list_iterator.h>
|
||||
|
||||
#include "core/download.h"
|
||||
|
||||
@@ -56,6 +57,8 @@ public:
|
||||
typedef torrent::priority_t Priority;
|
||||
typedef display::WindowFileList WFileList;
|
||||
|
||||
typedef torrent::FileListIterator iterator;
|
||||
|
||||
ElementFileList(core::Download* d);
|
||||
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
@@ -78,7 +81,7 @@ private:
|
||||
WFileList* m_window;
|
||||
|
||||
// Change to unsigned, please.
|
||||
unsigned int m_focus;
|
||||
iterator m_focus;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user