diff --git a/src/core/download.cc b/src/core/download.cc index b881d421..8ea1f8be 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -91,6 +91,8 @@ Download::Download(download_type d) : m_variables.insert("directory", new utils::VariableStringSlot(rak::mem_fn(&m_fileList, &torrent::FileList::root_dir), rak::mem_fn(this, &Download::set_root_directory))); + m_variables.insert("info_hash", new utils::VariableStringSlot(rak::mem_fn(&m_download, &torrent::Download::info_hash), NULL)); + m_variables.insert("min_peers", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::peers_min), rak::mem_fn(&m_download, &download_type::set_peers_min))); m_variables.insert("max_peers", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::peers_max), rak::mem_fn(&m_download, &download_type::set_peers_max))); m_variables.insert("max_uploads", new utils::VariableValueSlot(rak::mem_fn(&m_download, &download_type::uploads_max), rak::mem_fn(&m_download, &download_type::set_uploads_max))); diff --git a/src/core/download.h b/src/core/download.h index 2d90333a..bb8d1ebd 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -37,6 +37,7 @@ #ifndef RTORRENT_CORE_DOWNLOAD_H #define RTORRENT_CORE_DOWNLOAD_H +#include #include #include #include @@ -83,13 +84,14 @@ public: const std::string& variable_string(const std::string& key) const { return m_variables.get_string(key); } download_type* download() { return &m_download; } - const download_type* download() const { return &m_download; } + const download_type* c_download() const { return &m_download; } torrent::Object* bencode() { return m_download.bencode(); } file_list_type* file_list() { return &m_fileList; } tracker_list_type* tracker_list() { return &m_trackerList; } 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()); } const std::string& message() const { return m_message; } void set_message(const std::string& msg) { m_message = msg; } diff --git a/src/display/text_element.h b/src/display/text_element.h index 138b836f..1e329149 100644 --- a/src/display/text_element.h +++ b/src/display/text_element.h @@ -38,6 +38,7 @@ #define RTORRENT_DISPLAY_TEXT_ELEMENT_H #include +#include #include "display/canvas.h" diff --git a/src/display/text_element_list.cc b/src/display/text_element_list.cc index e325e636..f4396b86 100644 --- a/src/display/text_element_list.cc +++ b/src/display/text_element_list.cc @@ -51,20 +51,33 @@ TextElementList::clear() { char* TextElementList::print(char* first, const char* last, Canvas::attributes_list* attributes, void* object) { + int column = m_columnWidth != NULL ? m_column : 0; + // Call print for each element even if first == last so that any // attributes gets added to the list. for (iterator itr = begin(); itr != end(); ++itr) - first = (*itr)->print(first, last, attributes, object); + if (column-- > 0) { + const char* columnEnd = std::min(last, first + *m_columnWidth); + + first = (*itr)->print(first, columnEnd, attributes, object); + + std::memset(first, ' ', columnEnd - first); + first += columnEnd - first; + + } else { + first = (*itr)->print(first, last, attributes, object); + } return first; } TextElementList::extent_type TextElementList::max_length() { - size_type length = 0; + extent_type length = 0; + int column = m_columnWidth != NULL ? m_column : 0; for (iterator itr = begin(); itr != end(); ++itr) { - size_type l = (*itr)->max_length(); + extent_type l = column-- > 0 ? std::min((*itr)->max_length(), *m_columnWidth) : (*itr)->max_length(); if (l == extent_full) return extent_full; diff --git a/src/display/text_element_list.h b/src/display/text_element_list.h index 9aad0302..6535874c 100644 --- a/src/display/text_element_list.h +++ b/src/display/text_element_list.h @@ -61,13 +61,21 @@ public: using base_type::push_back; + TextElementList() : m_column(0), m_columnWidth(0) {} virtual ~TextElementList() { clear(); } void clear(); + void set_column(unsigned int column) { m_column = column; } + void set_column_width(extent_type* width) { m_columnWidth = width; } + virtual char* print(char* first, const char* last, Canvas::attributes_list* attributes, void* object); virtual extent_type max_length(); + +private: + unsigned int m_column; + extent_type* m_columnWidth; }; } diff --git a/src/display/text_element_string.cc b/src/display/text_element_string.cc index 3bff7c66..c00ff13e 100644 --- a/src/display/text_element_string.cc +++ b/src/display/text_element_string.cc @@ -36,21 +36,12 @@ #include "config.h" -#include - #include "text_element_string.h" namespace display { char* -TextElementString::print(char* first, const char* last, Canvas::attributes_list* attributes, void* object) { - size_t length = std::min(last - first, m_string.size()); - - if (length == 0) - return first; - - std::memcpy(first, m_string.c_str(), length); - +TextElementStringBase::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); @@ -65,17 +56,33 @@ TextElementString::print(char* first, const char* last, Canvas::attributes_list* else if (current.colors() != base.colors()) current.set_position(first); + first = copy_string(first, last, object); + if (current.position() != NULL) { attributes->push_back(current); - attributes->push_back(Attributes(first + length, base.attributes(), base.colors())); + attributes->push_back(Attributes(first, base.attributes(), base.colors())); } + return first; +} + +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)); + return first + length; } -TextElementString::extent_type -TextElementString::max_length() { - return m_string.size(); +char* +TextElementCString::copy_string(char* first, const char* last, void* object) { + std::memcpy(first, m_string, std::min(m_length, last - first)); + + return first + m_length; } } diff --git a/src/display/text_element_string.h b/src/display/text_element_string.h index 4aa1c660..dffce36c 100644 --- a/src/display/text_element_string.h +++ b/src/display/text_element_string.h @@ -37,32 +37,105 @@ #ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H #define RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H +#include #include +#include #include "text_element.h" namespace display { -class TextElementString : public TextElement { +class TextElementStringBase : public TextElement { public: - TextElementString() {} - TextElementString(const std::string& s, int attributes = Attributes::a_invalid) : m_string(s), m_attributes(attributes) {} - - const std::string& str() const { return m_string; } - void set_str(const std::string& s) { m_string = s; } - int attributes() const { return m_attributes; } void set_attributes(int a) { m_attributes = a; } virtual char* print(char* first, const char* last, Canvas::attributes_list* attributes, void* object); - virtual extent_type max_length(); +protected: + virtual char* copy_string(char* first, const char* last, void* object) = 0; -private: - std::string m_string; int m_attributes; }; +class TextElementString : public TextElementStringBase { +public: + TextElementString(const std::string& s, int attributes = Attributes::a_invalid) : + m_string(s) { m_attributes = attributes; } + + const std::string& str() const { return m_string; } + void set_str(const std::string& s) { m_string = s; } + +private: + virtual extent_type max_length() { return m_string.size(); } + + virtual char* copy_string(char* first, const char* last, void* object); + + std::string m_string; +}; + +class TextElementCString : public TextElementStringBase { +public: + TextElementCString(const char* s, int attributes = Attributes::a_invalid) : + m_length(std::strlen(s)), m_string(s) { + m_attributes = attributes; + } + +private: + virtual extent_type max_length() { return m_length; } + + virtual char* copy_string(char* first, const char* last, void* object); + + extent_type m_length; + const char* m_string; +}; + +template +class TextElementStringSlot : public TextElementStringBase { +public: + typedef typename slot_type::argument_type arg1_type; + typedef typename slot_type::result_type result_type; + + TextElementStringSlot(const slot_type& slot, int attributes = Attributes::a_invalid) : + m_length(extent_full), m_slot(slot) { + m_attributes = attributes; + } + +private: + virtual extent_type max_length() { return m_length; } + + virtual char* copy_string(char* first, const char* last, void* object) { + arg1_type arg1 = reinterpret_cast(object); + + if (arg1 == NULL) + return first; + + result_type result = m_slot(arg1); + extent_type length = std::min(result_length(&result), last - first); + + std::memcpy(first, result_buffer(&result), length); + + return first + length; + } + + template + extent_type result_length(Result* result) { return result->size(); } + extent_type result_length(const char** result) { return std::strlen(*result); } + + template + const char* result_buffer(Result* result) { return result->c_str(); } + const char* result_buffer(const char** result) { return *result; } + + extent_type m_length; + slot_type m_slot; +}; + +template +inline TextElementStringSlot* +text_element_string_slot(const slot_type& slot, int attributes = Attributes::a_invalid) { + return new TextElementStringSlot(slot, attributes); +} + } #endif diff --git a/src/display/window_text.cc b/src/display/window_text.cc index b941581e..0f6cdba6 100644 --- a/src/display/window_text.cc +++ b/src/display/window_text.cc @@ -58,8 +58,14 @@ WindowText::push_back(TextElement* element) { // m_minHeight = size(); m_maxHeight = size(); - if (element != NULL) - m_maxWidth = std::max(m_maxWidth, element->max_length() + 2); + if (element != NULL) { + extent_type width = element->max_length(); + + if (width == extent_full) + m_maxWidth = extent_full; + else + m_maxWidth = std::max(m_maxWidth, element->max_length() + m_margin); + } // Check if active, if so do the update thingie. Or be lazy? } @@ -80,7 +86,7 @@ WindowText::redraw() { Canvas::attributes_list attributes; attributes.push_back(Attributes(buffer, Attributes::a_normal, Attributes::color_default)); - char* last = (*itr)->print(buffer, buffer + m_canvas->width(), &attributes, NULL); + char* last = (*itr)->print(buffer, buffer + m_canvas->width(), &attributes, m_object); m_canvas->print_attributes(0, position, buffer, last, &attributes); } diff --git a/src/display/window_text.h b/src/display/window_text.h index caed5ade..98b83fbd 100644 --- a/src/display/window_text.h +++ b/src/display/window_text.h @@ -62,7 +62,8 @@ public: using base_type::rbegin; using base_type::rend; - WindowText() : Window(new Canvas, 0, 0, 0, extent_static, extent_static) {} + WindowText(void* object = NULL, extent_type margin = 0) : + Window(new Canvas, 0, 0, 0, extent_static, extent_static), m_object(object), m_margin(margin) {} ~WindowText() { clear(); } void clear(); @@ -70,6 +71,11 @@ public: void push_back(TextElement* element); virtual void redraw(); + +private: + void* m_object; + + extent_type m_margin; }; } diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 88ea340a..857ce9d6 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -20,6 +20,8 @@ libsub_ui_a_SOURCES = \ element_peer_list.h \ element_string_list.cc \ element_string_list.h \ + element_text.cc \ + element_text.h \ element_tracker_list.cc \ element_tracker_list.h \ element_transfer_list.cc \ diff --git a/src/ui/download.cc b/src/ui/download.cc index c6ca9213..36fac9c8 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -47,11 +48,14 @@ #include "display/window_title.h" #include "display/window_download_statusbar.h" +#include "display/text_element_string.h" + #include "control.h" #include "download.h" #include "root.h" #include "element_file_list.h" #include "element_menu.h" +#include "element_text.h" #include "element_peer_list.h" #include "element_tracker_list.h" #include "element_chunks_seen.h" @@ -59,7 +63,7 @@ namespace ui { -Download::Download(DPtr d) : +Download::Download(core::Download* d) : m_download(d), m_state(DISPLAY_MAX_SIZE), m_focusDisplay(false) { @@ -67,31 +71,9 @@ Download::Download(DPtr d) : m_windowDownloadStatus = new WDownloadStatus(d); m_windowDownloadStatus->set_bottom(true); - ElementMenu* elementMenu = new ElementMenu; - - elementMenu->push_back("Peer List", - sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_LIST), - sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_PEER_LIST)); -// elementMenu->push_back("Peer Info", -// sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_INFO), -// sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_PEER_INFO)); - elementMenu->push_back("File List", - sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_FILE_LIST), - sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_FILE_LIST)); - elementMenu->push_back("Tracker List", - sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST), - sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRACKER_LIST)); - elementMenu->push_back("Chunks Seen", - sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_CHUNKS_SEEN), - sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_CHUNKS_SEEN)); - elementMenu->push_back("Transfer List", - sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_LIST), - sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRANSFER_LIST)); - - elementMenu->set_entry(0); - - m_uiArray[DISPLAY_MENU] = elementMenu; + m_uiArray[DISPLAY_MENU] = create_menu(); m_uiArray[DISPLAY_PEER_LIST] = new ElementPeerList(d); + m_uiArray[DISPLAY_INFO] = create_info(); m_uiArray[DISPLAY_FILE_LIST] = new ElementFileList(d); m_uiArray[DISPLAY_TRACKER_LIST] = new ElementTrackerList(d); m_uiArray[DISPLAY_CHUNKS_SEEN] = new ElementChunksSeen(d); @@ -99,6 +81,7 @@ Download::Download(DPtr d) : m_uiArray[DISPLAY_MENU]->slot_exit(sigc::mem_fun(&m_slotExit, &slot_type::operator())); m_uiArray[DISPLAY_PEER_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_PEER_LIST)); + m_uiArray[DISPLAY_INFO]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_INFO)); m_uiArray[DISPLAY_FILE_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_FILE_LIST)); m_uiArray[DISPLAY_TRACKER_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRACKER_LIST)); m_uiArray[DISPLAY_CHUNKS_SEEN]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_CHUNKS_SEEN)); @@ -116,6 +99,48 @@ Download::~Download() { delete m_windowDownloadStatus; } +inline ElementBase* +Download::create_menu() { + ElementMenu* element = new ElementMenu; + + element->push_back("Peer List", + sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_LIST), + sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_PEER_LIST)); + element->push_back("Info", + sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_INFO), + sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_INFO)); + element->push_back("File List", + sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_FILE_LIST), + sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_FILE_LIST)); + element->push_back("Tracker List", + sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST), + sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRACKER_LIST)); + element->push_back("Chunks Seen", + sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_CHUNKS_SEEN), + sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_CHUNKS_SEEN)); + element->push_back("Transfer List", + sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_LIST), + sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRANSFER_LIST)); + + element->set_entry(0); + + return element; +} + +inline ElementBase* +Download::create_info() { + ElementText* element = new ElementText(m_download); + + 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))); + + element->set_column_width(element->column_width() + 1); + + return element; +} + void Download::activate(display::Frame* frame, bool focus) { if (is_active()) @@ -166,6 +191,7 @@ Download::activate_display(Display displayType, bool focusDisplay) { break; case DISPLAY_PEER_LIST: + case DISPLAY_INFO: case DISPLAY_FILE_LIST: case DISPLAY_TRACKER_LIST: case DISPLAY_CHUNKS_SEEN: @@ -189,6 +215,7 @@ Download::activate_display(Display displayType, bool focusDisplay) { break; case DISPLAY_PEER_LIST: + case DISPLAY_INFO: case DISPLAY_FILE_LIST: case DISPLAY_TRACKER_LIST: case DISPLAY_CHUNKS_SEEN: diff --git a/src/ui/download.h b/src/ui/download.h index f22169b3..c5efb682 100644 --- a/src/ui/download.h +++ b/src/ui/download.h @@ -60,12 +60,12 @@ class Download : public ElementBase { public: typedef display::WindowDownloadStatusbar WDownloadStatus; - typedef core::Download* DPtr; typedef std::list PList; typedef enum { DISPLAY_MENU, DISPLAY_PEER_LIST, + DISPLAY_INFO, DISPLAY_FILE_LIST, DISPLAY_TRACKER_LIST, DISPLAY_CHUNKS_SEEN, @@ -73,7 +73,7 @@ public: DISPLAY_MAX_SIZE } Display; - Download(DPtr d); + Download(core::Download* d); ~Download(); void activate(display::Frame* frame, bool focus = true); @@ -93,13 +93,16 @@ private: Download(const Download&); void operator = (const Download&); + inline ElementBase* create_menu(); + inline ElementBase* create_info(); + void receive_max_uploads(int t); void receive_min_peers(int t); void receive_max_peers(int t); void bind_keys(); - DPtr m_download; + core::Download* m_download; Display m_state; ElementBase* m_uiArray[DISPLAY_MAX_SIZE]; diff --git a/src/ui/element_menu.cc b/src/ui/element_menu.cc index 64379dd4..b43865a6 100644 --- a/src/ui/element_menu.cc +++ b/src/ui/element_menu.cc @@ -49,14 +49,14 @@ namespace ui { struct ElementMenuEntry { - display::TextElementString* m_element; + display::TextElementStringBase* m_element; - ElementMenu::slot_type m_slotFocus; - ElementMenu::slot_type m_slotSelect; + ElementMenu::slot_type m_slotFocus; + ElementMenu::slot_type m_slotSelect; }; ElementMenu::ElementMenu() : - m_window(new WindowText), + m_window(new WindowText(NULL, 2)), m_entry(entry_invalid) { // Move bindings into a function that defines default bindings. @@ -103,10 +103,10 @@ ElementMenu::disable() { } void -ElementMenu::push_back(const std::string& name, const slot_type& slotSelect, const slot_type& slotFocus) { +ElementMenu::push_back(const char* name, const slot_type& slotSelect, const slot_type& slotFocus) { entry_type* entry = new entry_type; - entry->m_element = new display::TextElementString(name); + entry->m_element = new display::TextElementCString(name); entry->m_slotSelect = slotSelect; entry->m_slotFocus = slotFocus; diff --git a/src/ui/element_menu.h b/src/ui/element_menu.h index 923157d0..e97451ad 100644 --- a/src/ui/element_menu.h +++ b/src/ui/element_menu.h @@ -81,7 +81,8 @@ public: // Consider returning a pointer that can be used to manipulate // entries, f.ex disabling them. - void push_back(const std::string& name, + // The c string is not copied nor freed, so it should be constant. + void push_back(const char* name, const slot_type& slotSelect = slot_type(), const slot_type& slotFocus = slot_type()); diff --git a/src/ui/element_text.cc b/src/ui/element_text.cc new file mode 100644 index 00000000..aeb60901 --- /dev/null +++ b/src/ui/element_text.cc @@ -0,0 +1,121 @@ +// 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 + +#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" +#include "element_text.h" + +namespace ui { + +ElementText::ElementText(void *object) : + m_window(new WindowText(object)), + m_column(0), + m_columnWidth(0) { + + // Move bindings into a function that defines default bindings. + m_bindings[KEY_LEFT] = sigc::mem_fun(&m_slotExit, &slot_type::operator()); + +// m_bindings[KEY_UP] = sigc::mem_fun(this, &ElementText::entry_prev); +// m_bindings[KEY_DOWN] = sigc::mem_fun(this, &ElementText::entry_next); +// m_bindings[KEY_RIGHT] = sigc::mem_fun(this, &ElementText::entry_select); +} + +ElementText::~ElementText() { + delete m_window; +} + +void +ElementText::activate(display::Frame* frame, bool focus) { + if (is_active()) + throw torrent::client_error("ui::ElementText::activate(...) is_active()."); + + if (focus) + control->input()->push_back(&m_bindings); + + m_focus = focus; + + m_frame = frame; + m_frame->initialize_window(m_window); + + m_window->set_active(true); +} + +void +ElementText::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementText::disable(...) !is_active()."); + + control->input()->erase(&m_bindings); + + m_frame->clear(); + m_frame = NULL; + + m_window->set_active(false); +} + +void +ElementText::push_back(display::TextElement* entry) { + m_window->push_back(entry); + + // For the moment, don't bother doing anything if the window is + // already active. + m_window->mark_dirty(); +} + +void +ElementText::push_column(display::TextElement* entry1, display::TextElement* entry2) { + m_columnWidth = std::max(entry1->max_length(), m_column); + + 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); + + push_back(list); +} + +} diff --git a/src/utils/variable_generic.cc b/src/utils/variable_generic.cc index ae0a06d0..427691a0 100644 --- a/src/utils/variable_generic.cc +++ b/src/utils/variable_generic.cc @@ -162,11 +162,17 @@ VariableVoidSlot::get() { void VariableVoidSlot::set(const torrent::Object& arg) { + if (!m_slotSet.is_valid()) + return; + m_slotSet(); } const torrent::Object& VariableValueSlot::get() { + if (!m_slotGet.is_valid()) + return m_cache; + m_cache = m_slotGet() / m_unit; return m_cache; @@ -174,6 +180,9 @@ VariableValueSlot::get() { void VariableValueSlot::set(const torrent::Object& arg) { + if (!m_slotSet.is_valid()) + return; + value_type value; switch (arg.type()) { @@ -196,6 +205,9 @@ VariableValueSlot::set(const torrent::Object& arg) { const torrent::Object& VariableStringSlot::get() { + if (!m_slotGet.is_valid()) + return m_cache; + m_cache = m_slotGet(); return m_cache; @@ -203,6 +215,9 @@ VariableStringSlot::get() { void VariableStringSlot::set(const torrent::Object& arg) { + if (!m_slotSet.is_valid()) + return; + switch (arg.type()) { case torrent::Object::TYPE_STRING: m_slotSet(arg.as_string()); diff --git a/src/utils/variable_generic.h b/src/utils/variable_generic.h index e1558cad..b755a656 100644 --- a/src/utils/variable_generic.h +++ b/src/utils/variable_generic.h @@ -167,6 +167,12 @@ public: m_slotSet.set(rak::convert_fn(slotSet)); } + template + VariableStringSlot(SlotGet* slotGet, void* slotSet) { + m_slotGet.set(rak::convert_fn(slotGet)); + m_slotSet.set(NULL); + } + virtual const torrent::Object& get(); virtual void set(const torrent::Object& arg);