mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-18 00:15:27 +01:00
added TableCellHandler
This commit is contained in:
parent
6c80fe82c1
commit
1bd450e943
@ -0,0 +1,389 @@
|
||||
//
|
||||
// TableCellHandler.h
|
||||
//
|
||||
// $Id: //poco/Main/WebWidgets/ExtJS/include/Poco/WebWidgets/ExtJS/TableCellHandler.h#1 $
|
||||
//
|
||||
// Library: ExtJS
|
||||
// Package: Core
|
||||
// Module: TableCellHandler
|
||||
//
|
||||
// Definition of the TableCellHandler class.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ExtJS_TableCellHandler_INCLUDED
|
||||
#define ExtJS_TableCellHandler_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/ExtJS/Utility.h"
|
||||
#include "Poco/WebWidgets/ExtJS/AbstractTableCellHandler.h"
|
||||
#include "Poco/WebWidgets/ExtJS/CellInitializer.h"
|
||||
#include "Poco/WebWidgets/ImageButtonCell.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace WebWidgets {
|
||||
namespace ExtJS {
|
||||
|
||||
|
||||
|
||||
template <typename Class>
|
||||
class AbstractFunction
|
||||
{
|
||||
public:
|
||||
AbstractFunction(){}
|
||||
virtual ~AbstractFunction(){}
|
||||
virtual void writeData(const Class* pObj, std::ostream& out) const = 0;
|
||||
virtual AbstractFunction* clone() const = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
static void write(const T& t, std::ostream& out)
|
||||
{
|
||||
out << t;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
static void write(const std::string& t, std::ostream& out)
|
||||
{
|
||||
out << "'" << Utility::safe(t) << "'";
|
||||
}
|
||||
|
||||
|
||||
template <typename Class, typename Ret>
|
||||
class Function: public AbstractFunction<Class>
|
||||
{
|
||||
public:
|
||||
typedef Ret (Class::*Func)() const;
|
||||
|
||||
Function(Func func):_func(func)
|
||||
{
|
||||
}
|
||||
|
||||
void writeData(const Class* pObj, std::ostream& out) const
|
||||
{
|
||||
write<Ret>((pObj->*_func)(), out);
|
||||
}
|
||||
|
||||
AbstractFunction* clone() const
|
||||
{
|
||||
return new Function(_func);
|
||||
}
|
||||
|
||||
private:
|
||||
Func _func;
|
||||
};
|
||||
|
||||
|
||||
template <typename Class, typename Ret>
|
||||
class Function<Class, const Ret&>: public AbstractFunction<Class>
|
||||
{
|
||||
public:
|
||||
typedef const Ret& (Class::*Func)() const;
|
||||
|
||||
Function(Func func):_func(func)
|
||||
{
|
||||
}
|
||||
|
||||
void writeData(const Class* pObj, std::ostream& out) const
|
||||
{
|
||||
write<Ret>((pObj->*_func)(), out);
|
||||
}
|
||||
|
||||
AbstractFunction* clone() const
|
||||
{
|
||||
return new Function(_func);
|
||||
}
|
||||
|
||||
private:
|
||||
Func _func;
|
||||
};
|
||||
|
||||
|
||||
template <typename Class>
|
||||
class StaticContentFunction: public AbstractFunction<Class>
|
||||
{
|
||||
public:
|
||||
StaticContentFunction(const std::string& str):_str(str)
|
||||
{
|
||||
}
|
||||
|
||||
void writeData(const Class*, std::ostream& out) const
|
||||
{
|
||||
out << _str;
|
||||
}
|
||||
|
||||
AbstractFunction* clone() const
|
||||
{
|
||||
return new StaticContentFunction(_str);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _str;
|
||||
};
|
||||
|
||||
|
||||
template <typename Class, typename Ret>
|
||||
static AbstractFunction<Class>* function(Ret (Class::*Func)() const)
|
||||
{
|
||||
return new Function<Class, Ret>(Func);
|
||||
};
|
||||
|
||||
|
||||
template<typename Class>
|
||||
class TableCellHandler: public AbstractTableCellHandler
|
||||
/// TableCellHandler
|
||||
{
|
||||
public:
|
||||
typedef typename Poco::AutoPtr<TableCellHandler> Ptr;
|
||||
typedef typename std::vector<AbstractFunction<Class>*> Functions;
|
||||
typedef typename Functions::const_iterator ConstIterator;
|
||||
typedef typename Functions::iterator Iterator;
|
||||
typedef typename std::map<std::string, StaticContentFunction<Class>* > CodeGen; /// Maps a var name to a string generating function
|
||||
typedef typename CodeGen::iterator CodeIterator;
|
||||
typedef typename CodeGen::const_iterator CodeConstIterator;
|
||||
|
||||
TableCellHandler(const std::string& className, bool useEditor, bool useRenderer):
|
||||
AbstractTableCellHandler(useEditor, useRenderer),
|
||||
_className(className)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void addFixed(const std::string& name, const std::string& fixedContent)
|
||||
/// Adds a variable with a given fixed string content. The content will not be wrapped
|
||||
/// with ' ' but will be written as is
|
||||
{
|
||||
_code.insert(std::make_pair(name, new StaticContentFunction<Class>(fixedContent)));
|
||||
}
|
||||
|
||||
template <typename Ret>
|
||||
void addDynamic(const std::string& name, Ret (Class::*Function)() const)
|
||||
/// Adds a variable to be initialized from a Store
|
||||
/// This requires us to generate the column as part of the store data array (simply call addData)
|
||||
/// and we have to map the varName to an index
|
||||
{
|
||||
//FIXME: multiple dynamic data support: write val[i]
|
||||
static const std::string var("val");
|
||||
addData<Ret>(Function);
|
||||
addFixed(name, var);
|
||||
}
|
||||
|
||||
void writeData(const void* pAny, std::ostream& out)
|
||||
/// Writes the content of the table used to dynamically
|
||||
/// initialize Table Columns
|
||||
{
|
||||
const Class* pObj = reinterpret_cast<const Class*>(pAny);
|
||||
ConstIterator it = _functions.begin();
|
||||
//FIXME: only one dynamic column
|
||||
if (it != _functions.end())
|
||||
{
|
||||
if (it != _functions.begin())
|
||||
out << ",";
|
||||
(*it)->writeData(pObj, out);
|
||||
}
|
||||
}
|
||||
|
||||
void writeDynamicData(std::ostream& out)
|
||||
{
|
||||
out << "function (val){";
|
||||
out << "var tmp = new " << _className;
|
||||
out << "({renderTo:'" << Utility::getTmpID() << "'";
|
||||
CodeConstIterator it = _code.begin();
|
||||
for (; it != _code.end(); ++it)
|
||||
{
|
||||
out << ",";
|
||||
out << it->first << ":";
|
||||
it->second->writeData(0, out);
|
||||
}
|
||||
out << "});";
|
||||
out << "var html = Ext.get('tmp').dom.innerHTML;";
|
||||
out << "Ext.destroy(tmp);";
|
||||
out << "return html;}";
|
||||
}
|
||||
|
||||
AbstractTableCellHandler* clone() const
|
||||
{
|
||||
return new TableCellHandler(*this);
|
||||
}
|
||||
|
||||
void init(const Cell* pCell)
|
||||
{
|
||||
const Class* pClass = dynamic_cast<const Class*>(pCell);
|
||||
poco_check_ptr (pClass);
|
||||
AbstractTableCellHandler* pHandler = this;
|
||||
cellInitializer(pClass, pHandler);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~TableCellHandler()
|
||||
/// Destroys the TableCellHandler.
|
||||
{
|
||||
{
|
||||
CodeIterator it = _code.begin();
|
||||
for (; it != _code.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
{
|
||||
Iterator it = _functions.begin();
|
||||
for (; it != _functions.end(); ++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ret>
|
||||
void addData(Ret (Class::*Function)() const)
|
||||
{
|
||||
if (_functions.size() > 0)
|
||||
throw NotImplementedException("More than one dynamic column is not supported by table");
|
||||
_functions.push_back(function<Class, Ret>(Function));
|
||||
}
|
||||
|
||||
TableCellHandler(const TableCellHandler& other):
|
||||
AbstractTableCellHandler(other.useEditor(), other.useRenderer()),
|
||||
_className(other._className),
|
||||
_functions(),
|
||||
_code()
|
||||
{
|
||||
{
|
||||
ConstIterator it = other._functions.begin();
|
||||
for (; it != other._functions.end(); ++it)
|
||||
{
|
||||
_functions.push_back((*it)->clone());
|
||||
}
|
||||
}
|
||||
{
|
||||
CodeConstIterator it = other._code.begin();
|
||||
for (; it != other._code.end(); ++it)
|
||||
{
|
||||
_code.insert(std::make_pair(it->first, static_cast<StaticContentFunction<Class>* >(it->second->clone())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _className;
|
||||
Functions _functions;
|
||||
CodeGen _code;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
class TableCellHandler<ImageButtonCell>: public AbstractTableCellHandler
|
||||
/// TableCellHandler
|
||||
{
|
||||
public:
|
||||
TableCellHandler(bool useEditor, bool useRenderer):
|
||||
AbstractTableCellHandler(useEditor, useRenderer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void addFixed(const std::string& name, const std::string& fixedContent)
|
||||
/// Adds a variable with a given fixed string content. The content will not be wrapped
|
||||
/// with ' ' but will be written as is
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void writeData(const void* pAny, std::ostream& out)
|
||||
/// Writes the content of the table used to dynamically
|
||||
/// initialize Table Columns
|
||||
{
|
||||
}
|
||||
|
||||
void writeDynamicData(std::ostream& out)
|
||||
{
|
||||
Image::Ptr ptrImg = _pClass->getImage();
|
||||
bool hasImg = ptrImg && !ptrImg->getURI().empty();
|
||||
bool showTxt = _pClass->getShowText() || !hasImg;
|
||||
|
||||
out << "function (val){return ";
|
||||
out << "'<div>";
|
||||
out << "<div>";
|
||||
out << "<input src=\"' + val + '\"";
|
||||
if (!ptrImg->getName().empty())
|
||||
out << " name=\"" << ptrImg->getName() << "\"";
|
||||
if (ptrImg->getWidth() > 0)
|
||||
out << " width=\"" << ptrImg->getWidth() << "\"";
|
||||
if (ptrImg->getHeight() > 0)
|
||||
out << " height=\"" << ptrImg->getHeight() << "\"";
|
||||
std::string tooltip = ptrImg->getToolTip();
|
||||
if (!tooltip.empty())
|
||||
out << " alt=\"" << Utility::safe(tooltip) << "\"";
|
||||
out << " type=\"image\"/>";
|
||||
out << "</div>";
|
||||
if (showTxt && !_pClass->getValue().empty())
|
||||
out << "<div>" << Utility::safe(_pClass->getString()) << "</div>";
|
||||
out << "</div>';}";
|
||||
}
|
||||
|
||||
AbstractTableCellHandler* clone() const
|
||||
{
|
||||
return new TableCellHandler(*this);
|
||||
}
|
||||
|
||||
void init(const Cell* pCell)
|
||||
{
|
||||
_pClass = dynamic_cast<const ImageButtonCell*>(pCell);
|
||||
poco_check_ptr (_pClass);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~TableCellHandler()
|
||||
/// Destroys the TableCellHandler.
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TableCellHandler(const TableCellHandler& other):
|
||||
AbstractTableCellHandler(other.useEditor(), other.useRenderer()),
|
||||
_pClass(other._pClass)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
const ImageButtonCell* _pClass;
|
||||
};
|
||||
|
||||
|
||||
} } } // namespace Poco::WebWidgets::ExtJS
|
||||
|
||||
|
||||
#endif // ExtJS_TableCellHandler_INCLUDED
|
Loading…
x
Reference in New Issue
Block a user