// // Table.cpp // // $Id: //poco/Main/WebWidgets/src/Table.cpp#14 $ // // Library: WebWidgets // Package: Views // Module: Table // // Copyright (c) 2008, 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/Table.h" #include "Poco/WebWidgets/RequestHandler.h" #include "Poco/NumberParser.h" #include "Poco/Net/HTTPServerResponse.h" namespace Poco { namespace WebWidgets { const std::string Table::FIELD_COL("col"); const std::string Table::FIELD_ROW("row"); const std::string Table::FIELD_VAL("val"); const std::string Table::FIELD_CNT("cnt"); const std::string Table::EV_CELLCLICKED("click"); const std::string Table::EV_CELLVALUECHANGED("edit"); const std::string Table::EV_LOADDATA("load"); Table::Table(const TableColumns& tc, TableModel::Ptr pModel): View(typeid(Table)), _pModel(pModel), _columns(tc), _col(-1), _row(-1), _cnt(-1), _val(), _ev() { checkValidConfig(); } Table::Table(const std::string& name, const TableColumns& tc, TableModel::Ptr pModel): View(name, typeid(Table)), _pModel(pModel), _columns(tc), _col(-1), _row(-1), _cnt(-1), _val(), _ev() { checkValidConfig(); } Table::Table(const std::string& name, const std::type_info& type, const TableColumns& tc, TableModel::Ptr pModel): View(name, type), _pModel(pModel), _columns(tc), _col(-1), _row(-1), _cnt(-1), _val(), _ev() { checkValidConfig(); } Table::Table(const std::type_info& type, const TableColumns& tc, TableModel::Ptr pModel): View(type), _pModel(pModel), _columns(tc), _col(-1), _row(-1), _cnt(-1), _val(), _ev() { checkValidConfig(); } Table::~Table() { } void Table::checkValidConfig() { if (_columns.empty()) throw Poco::InvalidArgumentException("At least one column is required for a table"); if (!_pModel) throw Poco::InvalidArgumentException("An empty model is not allowed"); if (_columns.size() != _pModel->getColumnCount()) throw Poco::InvalidArgumentException("Model column count mismatches Columns count"); TableColumns::iterator it = _columns.begin(); for (; it != _columns.end(); ++it) { if ((*it)) adoptChild((*it));; } } void Table::handleForm(const std::string& field, const std::string& value) { if (field == FIELD_COL) handleCol(value); else if (field == FIELD_ROW) handleRow(value); else if (field == FIELD_VAL) handleVal(value); else if (field == FIELD_CNT) handleCnt(value); else if (field == RequestHandler::KEY_EVID) _ev = value; } void Table::handleRequest(const Poco::Net::HTTPServerRequest& req) { if (_ev == EV_CELLVALUECHANGED) handleValueChanged(); else if (_ev == EV_CELLCLICKED) handleCellClicked(); _col = -1; _row = -1; _cnt = -1; _val.clear(); _ev.clear(); } void Table::handleRequestAndResponse(const Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) { // RequestHandler has already called all the handeForm stuff if (_ev == EV_LOADDATA) { /// serialize the Table back /// check for cnt and start if only a segment was requested if (_row < 0) _row = 0; if (_cnt < 0) _cnt = 0; LoadData ld(&response, this, _row, _cnt); _col = -1; _row = -1; _cnt = -1; _val.clear(); _ev.clear(); beforeLoad.notify(this, ld); } else { handleRequest(request); response.send(); } } void Table::handleValueChanged() { if (_col < 0 || _row < 0 || _col >= getColumnCount()) throw InvalidArgumentException("col/row out of range"); Cell::Ptr pCell = getColumns()[_col]->getCell(); Formatter::Ptr pForm; if (pCell) pForm = pCell->getFormatter(); if (pForm) { Poco::Any any = pForm->parse(_val); setValue(any, _row, _col); } else setValue(Poco::Any(_val), _row, _col); } void Table::handleCellClicked() { if (_col < 0 || _row < 0 || _col >= getColumnCount()) throw InvalidArgumentException("col/row out of range"); CellClick ev(_row, _col); cellClicked(this, ev); } void Table::handleCol(const std::string& val) { _col = Poco::NumberParser::parse(val); } void Table::handleRow(const std::string& val) { _row = Poco::NumberParser::parse(val); } void Table::handleVal(const std::string& val) { // we have no guarantee that _col is set at this timepoint // so we cannot get the formatter for the row // we do the conversion later in apply _val = val; } void Table::handleCnt(const std::string& val) { _cnt = Poco::NumberParser::parse(val); } void Table::setValue(const Poco::Any& val, std::size_t row, std::size_t col) { Poco::Any oldValue; if (getRowCount() > row) oldValue = getValue(row, col); CellValueChange ev(row, col, oldValue, val); _pModel->setValue(val, row, col); cellValueChanged(this, ev); } Table::CellClick::CellClick(std::size_t r, std::size_t c): row(r), col(c) { } Table::CellValueChange::CellValueChange(std::size_t r, std::size_t c, const Poco::Any& old, const Poco::Any& n): row(r), col(c), oldValue(old), newValue(n) { } Table::LoadData::LoadData(Poco::Net::HTTPServerResponse* pR, Table* pT, int row, int cnt): pResponse(pR), pTable(pT), firstRow(row), rowCnt(cnt) { } } } // namespace Poco::WebWidgets