// // ListBoxCell.cpp // // $Id: //poco/Main/WebWidgets/src/ListBoxCell.cpp#2 $ // // Library: WebWidgets // Package: Controls // Module: ListBoxCell // // Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // #include "Poco/WebWidgets/ListBoxCell.h" #include "Poco/WebWidgets/RequestHandler.h" #include "Poco/DateTime.h" #include "Poco/StringTokenizer.h" #include "Poco/NumberParser.h" namespace Poco { namespace WebWidgets { const std::string ListBoxCell::EV_LOADDATA("load"); const std::string ListBoxCell::EV_AFTERLOAD("afterLoad"); const std::string ListBoxCell::EV_ROWSELECTED("rowSel"); const std::string ListBoxCell::ARG_SELECTED("sel"); const std::string ListBoxCell::ARG_ROW("row"); const std::string ListBoxCell::VAL_SELECTED("1"); const std::string ListBoxCell::VAL_DESELECTED("0"); ListBoxCell::ListBoxCell(View* pOwner): Cell(pOwner, typeid(ListBoxCell)), _data(), _fmtCache() { } ListBoxCell::ListBoxCell(View* pOwner, const std::type_info& type): Cell(pOwner, type), _data(), _fmtCache() { } ListBoxCell::~ListBoxCell() { } void ListBoxCell::handleForm(const std::string& field, const std::string& value) { // a ListBox inside a form will just send the selected values // may contain multiple values like "field: 1,3" // a deselectAll() would be wrong event wise Poco::StringTokenizer tok(value, ",", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); std::set selected; for (Poco::StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) { int val(-1); bool ok = Poco::NumberParser::tryParse(*it, val); if (ok) selected.insert(val); } for (int i = 0; i < _data.size(); ++i) { if (selected.find(i) != selected.end()) selectByIndex(i); else deselectByIndex(i); } } ListBoxCell::Data::iterator ListBoxCell::find(const Any& elem) { Data::iterator it = begin(); Formatter::Ptr ptr=getFormatter(); std::string elemStr(ptr->format(elem)); std::size_t pos(0); while (it != end()) { if (elemStr == _fmtCache[pos]) { return it; } ++it; ++pos; } return it; } ListBoxCell::Data::const_iterator ListBoxCell::find(const Any& elem) const { Data::const_iterator it = begin(); Formatter::Ptr ptr=getFormatter(); std::string elemStr(ptr->format(elem)); std::size_t pos(0); while (it != end()) { if (elemStr == _fmtCache[pos]) { return it; } ++it; ++pos; } return it; } void ListBoxCell::setElements(const Data& elems) { _data = elems; // update _fmtCache _fmtCache.clear(); Formatter::Ptr ptr = getFormatter(); Data::iterator it = _data.begin(); for (; it != _data.end(); ++it) _fmtCache.push_back(ptr->format(it->first)); } void ListBoxCell::erase(const Any& elem) { Data::iterator it = find(elem); if (it != _data.end()) _data.erase(it); } void ListBoxCell::select(const Any& elem) { Data::iterator it = find(elem); if (it != _data.end()) { if (it->second != true) { it->second = true; int idx = static_cast(it - _data.begin()); rowSelected(this, idx); } } } void ListBoxCell::deselect(const Any& elem) { Data::iterator it = find(elem); if (it != _data.end()) { if (it->second != false) { it->second = false; int idx = static_cast(it - _data.begin()); rowDeselected(this, idx); } } } bool ListBoxCell::hasSelected() const { Data::const_iterator it = _data.begin(); for (; it != _data.end(); ++it) if (it->second) return true; return false; } const Any& ListBoxCell::getSelected() const { Data::const_iterator it = _data.begin(); for (; it != _data.end(); ++it) if (it->second) return it->first; throw Poco::NotFoundException("No element selected"); } bool ListBoxCell::serializeJSON(std::ostream& out, const std::string& name) { out << name << ":"; Data::const_iterator it = _data.begin(); bool written = false; for (std::size_t i = 0; i < _data.size(); ++i) { if (_data[i].second) { if (written) out << ","; else written = true; out << i; } } if (!written) out << "''"; return true; } void ListBoxCell::selectByIndex(int idx, bool sel) { if (idx >= 0 && idx < _data.size()) { if (_data[idx].second != sel) { _data[idx].second = sel; if (sel) rowSelected(this, idx); else rowDeselected(this, idx); } } } void ListBoxCell::selectAll(bool sel) { Data::iterator it = _data.begin(); for (; it != _data.end(); ++it) it->second = sel; } void ListBoxCell::handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response) { const std::string& ev = args[RequestHandler::KEY_EVID]; if (ev == EV_LOADDATA) { Poco::Net::HTTPServerResponse* pResp = &response; std::pair data = std::make_pair(this, pResp); beforeLoad(this, data); } else if (ev == EV_AFTERLOAD) { afterLoad(this); response.send(); } else if (ev == EV_ROWSELECTED) { int row = Poco::NumberParser::parse(args[ARG_ROW]); bool sel = (args.get(ARG_SELECTED) == VAL_SELECTED); selectByIndex(row, sel); response.send(); } else response.send(); } } } // namespace Poco::WebWidgets