diff --git a/rak/functional.h b/rak/functional.h index 3e45ed05..d21f7292 100644 --- a/rak/functional.h +++ b/rak/functional.h @@ -384,16 +384,11 @@ call_delete_func(T* t) { } template -class bind1st_t : public std::unary_function { -protected: - typedef typename reference_fix::type value_type; +class bind1st_t : public std::unary_function { +public: + typedef typename reference_fix::type value_type; typedef typename reference_fix::type argument_type; - Operation m_op; - value_type m_value; - -public: bind1st_t(const Operation& op, const value_type v) : m_op(op), m_value(v) {} @@ -401,7 +396,11 @@ public: operator () (const argument_type arg) { return m_op(m_value, arg); } -}; + +protected: + Operation m_op; + value_type m_value; +}; template inline bind1st_t @@ -410,8 +409,7 @@ bind1st(const Operation& op, const Type& val) { } template -class bind2nd_t : public std::unary_function { +class bind2nd_t : public std::unary_function { public: typedef typename reference_fix::type argument_type; typedef typename reference_fix::type value_type; @@ -427,7 +425,6 @@ public: protected: Operation m_op; value_type m_value; - }; template diff --git a/src/core/curl_stack.cc b/src/core/curl_stack.cc index 04bd6d92..22a61a08 100644 --- a/src/core/curl_stack.cc +++ b/src/core/curl_stack.cc @@ -74,17 +74,16 @@ CurlStack::perform() { if (s != m_size) { // Done with some handles. int t; + CURLMsg* msg; - do { - CURLMsg* msg = curl_multi_info_read((CURLM*)m_handle, &t); - + while ((msg = curl_multi_info_read((CURLM*)m_handle, &t)) != NULL) { CurlGetList::iterator itr = std::find_if(m_getList.begin(), m_getList.end(), rak::equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); if (itr == m_getList.end()) throw std::logic_error("Could not find CurlGet with the right easy_handle"); (*itr)->perform(msg); - } while (t); + } } } while (code == CURLM_CALL_MULTI_PERFORM); diff --git a/src/core/download.h b/src/core/download.h index bb8d1ebd..fc001a69 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -93,6 +93,8 @@ public: const std::string& info_hash() const { return m_download.info_hash(); } std::string info_hash_hex() const { return rak::transform_hex(m_download.info_hash()); } + std::string local_id_escaped() const { return rak::copy_escape_html(m_download.local_id()); } + const std::string& message() const { return m_message; } void set_message(const std::string& msg) { m_message = msg; } diff --git a/src/display/Makefile.am b/src/display/Makefile.am index 497ce116..86fac8f8 100644 --- a/src/display/Makefile.am +++ b/src/display/Makefile.am @@ -17,6 +17,8 @@ libsub_display_a_SOURCES = \ text_element_list.h \ text_element_string.cc \ text_element_string.h \ + text_element_value.cc \ + text_element_value.h \ window.cc \ window.h \ window_download_chunks_seen.cc \ diff --git a/src/display/text_element_list.cc b/src/display/text_element_list.cc index f4396b86..62382a9f 100644 --- a/src/display/text_element_list.cc +++ b/src/display/text_element_list.cc @@ -38,6 +38,7 @@ #include #include +#include #include "text_element_list.h" @@ -59,8 +60,14 @@ TextElementList::print(char* first, const char* last, Canvas::attributes_list* a if (column-- > 0) { const char* columnEnd = std::min(last, first + *m_columnWidth); + if (columnEnd < first || columnEnd > last) + throw torrent::client_error("TextElementList::print(...) columnEnd < first || columnEnd > last."); + first = (*itr)->print(first, columnEnd, attributes, object); + if (first > columnEnd) + throw torrent::client_error("TextElementList::print(...) first > columnEnd."); + std::memset(first, ' ', columnEnd - first); first += columnEnd - first; diff --git a/src/display/text_element_string.cc b/src/display/text_element_string.cc index c00ff13e..6acf0477 100644 --- a/src/display/text_element_string.cc +++ b/src/display/text_element_string.cc @@ -70,19 +70,18 @@ char* TextElementString::copy_string(char* first, const char* last, void* object) { extent_type length = std::min(last - first, m_string.size()); - if (length == 0) - return first; - - std::memcpy(first, m_string.c_str(), std::min(length, last - first)); + std::memcpy(first, m_string.c_str(), length); return first + length; } char* TextElementCString::copy_string(char* first, const char* last, void* object) { - std::memcpy(first, m_string, std::min(m_length, last - first)); + extent_type length = std::min(last - first, m_length); - return first + m_length; + std::memcpy(first, m_string, length); + + return first + length; } } diff --git a/src/display/text_element_string.h b/src/display/text_element_string.h index dffce36c..6b830989 100644 --- a/src/display/text_element_string.h +++ b/src/display/text_element_string.h @@ -34,8 +34,8 @@ // Skomakerveien 33 // 3185 Skoppum, NORWAY -#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H -#define RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H +#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_STRING_H +#define RTORRENT_DISPLAY_TEXT_ELEMENT_STRING_H #include #include diff --git a/src/display/text_element_value.cc b/src/display/text_element_value.cc new file mode 100644 index 00000000..271b4f00 --- /dev/null +++ b/src/display/text_element_value.cc @@ -0,0 +1,70 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, 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 "text_element_value.h" + +namespace display { + +char* +TextElementValueBase::print(char* first, const char* last, Canvas::attributes_list* attributes, void* object) { + // Move this stuff into a function in TextElement. + Attributes base = attributes->back(); + Attributes current(NULL, m_attributes, Attributes::color_invalid); + + if (current.attributes() == Attributes::a_invalid) + current.set_attributes(base.attributes()); + else if (current.attributes() != base.attributes()) + current.set_position(first); + + if (current.colors() == Attributes::color_invalid) + current.set_colors(base.colors()); + else if (current.colors() != base.colors()) + current.set_position(first); + +// first += std::max(snprintf(first, last - first + 1, m_format, value(object)), 0); + first += std::max(snprintf(first, last - first, "%lld", value(object)), 0); + + if (current.position() != NULL) { + attributes->push_back(current); + attributes->push_back(Attributes(first, base.attributes(), base.colors())); + } + + return first; +} + +} diff --git a/src/display/text_element_value.h b/src/display/text_element_value.h new file mode 100644 index 00000000..2829c261 --- /dev/null +++ b/src/display/text_element_value.h @@ -0,0 +1,123 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, 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_DISPLAY_TEXT_ELEMENT_VALUE_H +#define RTORRENT_DISPLAY_TEXT_ELEMENT_VALUE_H + +#include +#include + +#include "text_element.h" + +namespace display { + +class TextElementValueBase : public TextElement { +public: + static const extent_type max_format_length = 12; + + int attributes() const { return m_attributes; } + void set_attributes(int a) { m_attributes = a; } + + void set_format(const char* f); + + virtual char* print(char* first, const char* last, Canvas::attributes_list* attributes, void* object); + +protected: + virtual int64_t value(void* object) = 0; + + int m_attributes; + char m_format[max_format_length]; +}; + +inline void +TextElementValueBase::set_format(const char* f) { + std::strncpy(m_format, f, max_format_length); + m_format[max_format_length - 1] = '\0'; +} + +class TextElementValue : public TextElementValueBase { +public: + TextElementValue(int64_t value, int attributes = Attributes::a_invalid) : m_value(value) { + m_attributes = attributes; + set_format("%lld"); + } + + int64_t value() const { return m_value; } + void set_value(int64_t v) { m_value = v; } + +private: + virtual extent_type max_length() { return 12; } + + virtual int64_t value(void* object) { return m_value; } + + int64_t m_value; +}; + +template +class TextElementValueSlot : public TextElementValueBase { +public: + typedef typename slot_type::argument_type arg1_type; + typedef typename slot_type::result_type result_type; + + TextElementValueSlot(const slot_type& slot, int attributes = Attributes::a_invalid) : m_slot(slot) { + m_attributes = attributes; + set_format("%lld"); + } + +private: + virtual extent_type max_length() { return 12; } + + virtual int64_t value(void* object) { + arg1_type arg1 = reinterpret_cast(object); + + if (arg1 == NULL) + return 0; + + return m_slot(arg1); + } + + slot_type m_slot; +}; + +template +inline TextElementValueSlot* +text_element_value_slot(const slot_type& slot, int attributes = Attributes::a_invalid) { + return new TextElementValueSlot(slot, attributes); +} + +} + +#endif diff --git a/src/display/window_text.cc b/src/display/window_text.cc index 0f6cdba6..e4b2f878 100644 --- a/src/display/window_text.cc +++ b/src/display/window_text.cc @@ -75,6 +75,7 @@ WindowText::redraw() { m_canvas->erase(); unsigned int position = 0; + Canvas::attributes_list attributes; for (iterator itr = begin(); itr != end() && position < m_canvas->height(); ++itr, ++position) { if (*itr == NULL) @@ -83,7 +84,7 @@ WindowText::redraw() { char buffer[m_canvas->width() + 1]; // Add a print function that sets up attributes etc? - Canvas::attributes_list attributes; + attributes.clear(); attributes.push_back(Attributes(buffer, Attributes::a_normal, Attributes::color_default)); char* last = (*itr)->print(buffer, buffer + m_canvas->width(), &attributes, m_object); diff --git a/src/ui/download.cc b/src/ui/download.cc index 36fac9c8..209ca616 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -49,6 +49,7 @@ #include "display/window_download_statusbar.h" #include "display/text_element_string.h" +#include "display/text_element_value.h" #include "control.h" #include "download.h" @@ -133,8 +134,17 @@ Download::create_info() { element->set_column(1); - element->push_column(new display::TextElementCString("Name:"), display::text_element_string_slot(rak::on(std::mem_fun(&core::Download::c_download), std::mem_fun(&torrent::Download::name)))); - element->push_column(new display::TextElementCString("Info Hash:"), display::text_element_string_slot(std::mem_fun(&core::Download::info_hash_hex))); + // Get these bindings with some kind of string map. + + element->push_column("Name:", display::text_element_string_slot(rak::on(std::mem_fun(&core::Download::c_download), std::mem_fun(&torrent::Download::name)))); + element->push_column("Local Id:", display::text_element_string_slot(std::mem_fun(&core::Download::local_id_escaped))); + element->push_column("Info Hash:", display::text_element_string_slot(std::mem_fun(&core::Download::info_hash_hex))); + + element->push_back(""); + element->push_column("Directory:", display::text_element_string_slot(rak::on(std::mem_fun(&core::Download::file_list), std::mem_fun(&torrent::FileList::root_dir)))); + element->push_column("Tied to File:", display::text_element_string_slot(rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file"))); + + element->push_column("Priority:", display::text_element_value_slot(rak::bind2nd(std::mem_fun(&core::Download::variable_value), "priority"))); element->set_column_width(element->column_width() + 1); diff --git a/src/ui/element_text.cc b/src/ui/element_text.cc index aeb60901..bfb05eb1 100644 --- a/src/ui/element_text.cc +++ b/src/ui/element_text.cc @@ -41,7 +41,6 @@ #include "display/frame.h" #include "display/window_text.h" #include "display/text_element_list.h" -#include "display/text_element_string.h" #include "input/manager.h" #include "control.h" @@ -96,8 +95,8 @@ ElementText::disable() { } void -ElementText::push_back(display::TextElement* entry) { - m_window->push_back(entry); +ElementText::push_back(text_element_wrapper entry) { + m_window->push_back(entry.m_element); // For the moment, don't bother doing anything if the window is // already active. @@ -105,15 +104,15 @@ ElementText::push_back(display::TextElement* entry) { } void -ElementText::push_column(display::TextElement* entry1, display::TextElement* entry2) { - m_columnWidth = std::max(entry1->max_length(), m_column); +ElementText::push_column(text_element_wrapper entry1, text_element_wrapper entry2) { + m_columnWidth = std::max(entry1.m_element->max_length(), m_columnWidth); display::TextElementList* list = new display::TextElementList; list->set_column(m_column); list->set_column_width(&m_columnWidth); - list->push_back(entry1); - list->push_back(entry2); + list->push_back(entry1.m_element); + list->push_back(entry2.m_element); push_back(list); } diff --git a/src/ui/element_text.h b/src/ui/element_text.h new file mode 100644 index 00000000..35d7689b --- /dev/null +++ b/src/ui/element_text.h @@ -0,0 +1,97 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, 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_TEXT_H +#define RTORRENT_UI_ELEMENT_TEXT_H + +#include + +#include "core/download.h" +#include "display/text_element_string.h" + +#include "element_base.h" + +namespace display { + class WindowText; + class TextElement; +} + +namespace ui { + +struct text_element_wrapper; + +class ElementText : public ElementBase { +public: + typedef display::WindowText WindowText; + + typedef uint32_t size_type; + typedef uint32_t extent_type; + + ElementText(void *object); + ~ElementText(); + + void activate(display::Frame* frame, bool focus = false); + void disable(); + + // Consider returning a pointer that can be used to manipulate + // entries, f.ex disabling them. + + void push_back(text_element_wrapper entry); + + void push_column(text_element_wrapper entry1, text_element_wrapper entry2); + + void set_column(unsigned int column) { m_column = column; } + + extent_type column_width() const { return m_columnWidth; } + void set_column_width(extent_type width) { m_columnWidth = width; } + +private: + WindowText* m_window; + + unsigned int m_column; + extent_type m_columnWidth; +}; + +struct text_element_wrapper { + text_element_wrapper(const char* cstr) : m_element(new display::TextElementCString(cstr)) {} + text_element_wrapper(display::TextElement* element) : m_element(element) {} + + display::TextElement* m_element; +}; + +} + +#endif