mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-04 19:13:30 +01:00
listbox fixes
This commit is contained in:
parent
585a7f147b
commit
22e337614c
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Version="9,00"
|
||||
Name="ExtJS"
|
||||
ProjectGUID="{19FA461F-7419-4653-8A6B-B93002F7DB14}"
|
||||
RootNamespace="ExtJS"
|
||||
@ -53,7 +53,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"
|
||||
/>
|
||||
@ -76,7 +75,7 @@
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\bin\Poco$(ProjectName)d.pdb"
|
||||
SubSystem="1"
|
||||
OptimizeForWindows98="1"
|
||||
OptimizeForWindows98="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="..\..\lib\Poco$(ProjectName)d.lib"
|
||||
@ -145,7 +144,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"
|
||||
/>
|
||||
@ -170,7 +168,7 @@
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
OptimizeForWindows98="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="..\..\lib\Poco$(ProjectName).lib"
|
||||
|
@ -42,12 +42,17 @@
|
||||
|
||||
#include "Poco/WebWidgets/ExtJS/ExtJS.h"
|
||||
#include "Poco/WebWidgets/Renderer.h"
|
||||
#include "Poco/WebWidgets/JSDelegate.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
class HTTPServerResponse;
|
||||
}
|
||||
namespace WebWidgets {
|
||||
|
||||
class ListBoxCell;
|
||||
class ListBox;
|
||||
|
||||
namespace ExtJS {
|
||||
|
||||
@ -56,6 +61,9 @@ class ExtJS_API ListBoxCellRenderer: public Poco::WebWidgets::Renderer
|
||||
/// ListBoxCellRenderer renders a button
|
||||
{
|
||||
public:
|
||||
static const std::string EV_ROWSELECT;
|
||||
static const std::string EV_ROWDESELECT;
|
||||
|
||||
ListBoxCellRenderer();
|
||||
/// Creates the ListBoxCellRenderer.
|
||||
|
||||
@ -70,6 +78,14 @@ public:
|
||||
|
||||
static void renderProperties(const ListBoxCell* pCell, std::ostream& ostr);
|
||||
/// Renders button properties
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createRowSelectionServerCallback(const ListBox* pList);
|
||||
|
||||
static void onBeforeLoad(void* pSender, std::pair<ListBoxCell*, Poco::Net::HTTPServerResponse*>& ld);
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createAfterLoadServerCallback(const ListBox* pList);
|
||||
/// Adds a javascript callback to inform the WebServer that the client has finished loading data
|
||||
/// Method signature is ( Store this, Ext.data.Record[] records, Object options )
|
||||
};
|
||||
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "Poco/WebWidgets/Button.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
#include "Poco/WebWidgets/WebApplication.h"
|
||||
#include "Poco/WebWidgets/WebWidgetsException.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
|
||||
|
||||
@ -89,6 +90,8 @@ void ButtonCellRenderer::renderProperties(const ButtonCell* pButtonCell, const s
|
||||
{
|
||||
ostr << "type:'submit',";
|
||||
Form::Ptr pForm = Utility::insideForm(pButtonCell);
|
||||
if (!pForm)
|
||||
throw WebWidgetsException("SubmitButton must be used inside a form!");
|
||||
ostr << "handler: function(){Ext.getCmp('" << pForm->id() << "').getForm().submit();},";
|
||||
}
|
||||
View* pView = pButtonCell->getOwner();
|
||||
|
@ -36,8 +36,15 @@
|
||||
|
||||
#include "Poco/WebWidgets/ExtJS/ListBoxCellRenderer.h"
|
||||
#include "Poco/WebWidgets/ExtJS/FormRenderer.h"
|
||||
#include "Poco/WebWidgets/ExtJS/TableRenderer.h"
|
||||
#include "Poco/WebWidgets/ExtJS/Utility.h"
|
||||
#include "Poco/WebWidgets/ListBoxCell.h"
|
||||
#include "Poco/WebWidgets/ListBox.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
#include "Poco/WebWidgets/Table.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Delegate.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
@ -46,6 +53,10 @@ namespace WebWidgets {
|
||||
namespace ExtJS {
|
||||
|
||||
|
||||
const std::string ListBoxCellRenderer::EV_ROWSELECT("rowselect");
|
||||
const std::string ListBoxCellRenderer::EV_ROWDESELECT("rowdeselect");
|
||||
|
||||
|
||||
ListBoxCellRenderer::ListBoxCellRenderer()
|
||||
{
|
||||
}
|
||||
@ -77,45 +88,123 @@ void ListBoxCellRenderer::renderBody(const Renderable* pRenderable, const Render
|
||||
|
||||
void ListBoxCellRenderer::renderProperties(const ListBoxCell* pListBoxCell, std::ostream& ostr)
|
||||
{
|
||||
Utility::writeRenderableProperties(pListBoxCell, ostr);
|
||||
Utility::writeCellProperties(pListBoxCell, ostr);
|
||||
|
||||
if (pListBoxCell->getHeight() > 0)
|
||||
ostr << ",height:" << pListBoxCell->getHeight();
|
||||
if (pListBoxCell->getWidth() > 0)
|
||||
ostr << ",width:" << pListBoxCell->getWidth();
|
||||
const View* pOwner = pListBoxCell->getOwner();
|
||||
poco_check_ptr (pOwner);
|
||||
const ListBox* pList = dynamic_cast<const ListBox*>(pOwner);
|
||||
|
||||
if (pOwner->hasPosition())
|
||||
ostr << ",x:" << pOwner->getPosition().posX << ",y:" << pOwner->getPosition().posY;
|
||||
|
||||
ostr << ",dataFields:['i','d'],data:[";
|
||||
|
||||
if (pList)
|
||||
{
|
||||
bool hasListeners = (pList->rowDeselected.hasJavaScriptCode() ||
|
||||
pList->rowSelected.hasJavaScriptCode());
|
||||
if (hasListeners)
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
bool comma = false;
|
||||
if (pList->rowDeselected.hasJavaScriptCode())
|
||||
comma = Utility::writeJSEvent(ostr, EV_ROWDESELECT, pList->rowDeselected, &ListBoxCellRenderer::createRowSelectionServerCallback, pList);
|
||||
if (pList->rowDeselected.hasJavaScriptCode())
|
||||
{
|
||||
if (comma) ostr << ",";
|
||||
comma = Utility::writeJSEvent(ostr, EV_ROWSELECT, pList->rowSelected, &ListBoxCellRenderer::createRowSelectionServerCallback, pList);
|
||||
}
|
||||
ostr << "}";
|
||||
}
|
||||
}
|
||||
|
||||
// store: afterLoad, beforeLaod event
|
||||
ostr << ",store:new Ext.data.SimpleStore({autoLoad:true,fields:[{name:'i'},{name:'d'}]";
|
||||
ostr << ",proxy:new Ext.data.HttpProxy({url:";
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, ListBoxCell::EV_LOADDATA));
|
||||
std::string url(Utility::createURI(addParams, pList->id()));
|
||||
ostr << url << "})";
|
||||
ostr << ",reader:new Ext.data.ArrayReader()";
|
||||
if (pList->afterLoad.hasJavaScriptCode())
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
Utility::writeJSEvent(ostr, Table::EV_AFTERLOAD, pList->afterLoad, &ListBoxCellRenderer::createAfterLoadServerCallback, pList);
|
||||
ostr << "}";
|
||||
}
|
||||
|
||||
ostr << "})";
|
||||
ostr << ",dataFields:['i','d'],initVal:'";
|
||||
|
||||
//now serialize data, use cached content for that
|
||||
ListBoxCell::StringData::const_iterator it = pListBoxCell->beginString();
|
||||
ListBoxCell::StringData::const_iterator itEnd = pListBoxCell->endString();
|
||||
ListBoxCell::Data::const_iterator itV = pListBoxCell->begin();
|
||||
ListBoxCell::Data::const_iterator itVEnd = pListBoxCell->end();
|
||||
int cnt = 0;
|
||||
bool selected=false;
|
||||
std::ostringstream initValue;
|
||||
initValue << "'";
|
||||
for (; it != itEnd; ++it, ++cnt, ++itV)
|
||||
int cnt(0);
|
||||
for (; itV != itVEnd; ++itV, ++cnt)
|
||||
{
|
||||
if (it != pListBoxCell->beginString())
|
||||
ostr << ",";
|
||||
if (itV->second)
|
||||
{
|
||||
if (selected)
|
||||
initValue << ",";
|
||||
initValue << cnt;
|
||||
ostr << ",";
|
||||
ostr << cnt;
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
ostr << "'";
|
||||
ostr << ",valueField:'i',displayField:'d'";
|
||||
|
||||
ListBoxCell* pL = const_cast<ListBoxCell*>(pListBoxCell);
|
||||
pL->beforeLoad += Poco::delegate(&ListBoxCellRenderer::onBeforeLoad);
|
||||
WebApplication::instance().registerAjaxProcessor(Poco::NumberFormatter::format(pList->id()), pL);
|
||||
if (!pOwner->getName().empty())
|
||||
{
|
||||
WebApplication::instance().registerFormProcessor(pOwner->getName(), pL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate ListBoxCellRenderer::createRowSelectionServerCallback(const ListBox* pList)
|
||||
{
|
||||
// rowselect : ( Ext.ux.Multiselect field, Int idx, bool selected )
|
||||
static const std::string signature("function(field,idx,sel)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(ListBoxCell::ARG_ROW, "+idx"));
|
||||
addParams.insert(std::make_pair(ListBoxCell::ARG_SELECTED, "+(sel?'1':'0')"));
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, ListBoxCell::EV_ROWSELECTED));
|
||||
return Utility::createServerCallback(signature, addParams, pList->id(), pList->rowSelected.getOnSuccess(), pList->rowSelected.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate ListBoxCellRenderer::createAfterLoadServerCallback(const ListBox* pList)
|
||||
{
|
||||
poco_check_ptr (pList);
|
||||
static const std::string signature("function(aStore, recs, op)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, ListBoxCell::EV_AFTERLOAD));
|
||||
return Utility::createServerCallback(signature, addParams, pList->id(), pList->afterLoad.getOnSuccess(), pList->afterLoad.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
void ListBoxCellRenderer::onBeforeLoad(void* pSender, std::pair<ListBoxCell*, Poco::Net::HTTPServerResponse*>& ld)
|
||||
{
|
||||
ld.second->setChunkedTransferEncoding(true);
|
||||
ld.second->setContentType("text/javascript");
|
||||
std::ostream& ostr = ld.second->send();
|
||||
//[
|
||||
// ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
|
||||
// ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am']
|
||||
//]
|
||||
ostr << "[";
|
||||
ListBoxCell::StringData::const_iterator it = ld.first->beginString();
|
||||
ListBoxCell::StringData::const_iterator itEnd = ld.first->endString();
|
||||
int cnt = 0;
|
||||
for (; it != itEnd; ++it, ++cnt)
|
||||
{
|
||||
if (it != ld.first->beginString())
|
||||
ostr << ",";
|
||||
|
||||
ostr << "['" << cnt << "','" << *it << "']";
|
||||
}
|
||||
initValue << "'";
|
||||
ostr << "]";
|
||||
ostr << ",valueField:'i',displayField:'d',initVal:" << initValue.str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -170,7 +170,6 @@ Poco::WebWidgets::JSDelegate TableRenderer::createAfterLoadServerCallback(const
|
||||
}
|
||||
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate TableRenderer::createRenderServerCallback(const Table* pTable)
|
||||
{
|
||||
poco_check_ptr (pTable);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Version="9,00"
|
||||
Name="TestSuite"
|
||||
ProjectGUID="{AB43A995-70FA-4297-BD01-6C88938AA86D}"
|
||||
Keyword="Win32Proj"
|
||||
@ -52,7 +52,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
@ -139,7 +138,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,19 @@
|
||||
.ux-mselect{
|
||||
overflow:auto;
|
||||
background:white;
|
||||
position:relative; /* for calculating scroll offsets */
|
||||
zoom:1;
|
||||
overflow:auto;
|
||||
}
|
||||
.ux-mselect-item{
|
||||
font:normal 12px tahoma, arial, helvetica, sans-serif;
|
||||
padding:2px;
|
||||
border:1px solid #fff;
|
||||
white-space: nowrap;
|
||||
cursor:pointer;
|
||||
}
|
||||
.ux-mselect-selected{
|
||||
border:1px dotted #a3bae9 !important;
|
||||
background:#DFE8F6;
|
||||
cursor:pointer;
|
||||
}
|
||||
.ux-mselect{
|
||||
overflow:auto;
|
||||
background:white;
|
||||
position:relative; /* for calculating scroll offsets */
|
||||
zoom:1;
|
||||
overflow:auto;
|
||||
}
|
||||
.ux-mselect-item{
|
||||
font:normal 12px tahoma, arial, helvetica, sans-serif;
|
||||
padding:2px;
|
||||
border:1px solid #fff;
|
||||
white-space: nowrap;
|
||||
cursor:pointer;
|
||||
}
|
||||
.ux-mselect-selected{
|
||||
border:1px dotted #a3bae9 !important;
|
||||
background:#DFE8F6;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,7 @@
|
||||
#include "Poco/WebWidgets/SimpleTableModel.h"
|
||||
#include "Poco/WebWidgets/JSDelegate.h"
|
||||
#include "Poco/WebWidgets/ResourceManager.h"
|
||||
#include "Poco/WebWidgets/SubmitButton.h"
|
||||
#include "Poco/TeeStream.h"
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
#include "Poco/DateTime.h"
|
||||
@ -1127,6 +1128,39 @@ void ExtJSTest::testListBox()
|
||||
}
|
||||
|
||||
|
||||
void ExtJSTest::testFormListBox()
|
||||
{
|
||||
ResourceManager::Ptr pRM(new ResourceManager());Utility::initialize(pRM, Poco::Path());WebApplication webApp(Poco::URI("/"), pRM);
|
||||
LookAndFeel::Ptr laf(new LookAndFeel());
|
||||
webApp.setLookAndFeel(laf);
|
||||
RenderContext context(*laf, webApp);
|
||||
Utility::initialize(laf);
|
||||
|
||||
Page::Ptr ptr = new Page("test");
|
||||
webApp.setCurrentPage(ptr);
|
||||
Form::Ptr ptrF = new Form(Poco::URI("/test"));
|
||||
ptrF->setHeight(600);
|
||||
ptrF->setWidth(800);
|
||||
ptr->add(ptrF);
|
||||
ListBox::Ptr ptrList(new ListBox("MyWindow"));
|
||||
ptrList->setWidth(640);
|
||||
ptrList->setHeight(400);
|
||||
ptrF->add(ptrList);
|
||||
ptrList->insert(std::string("First"), false);
|
||||
ptrList->insert(std::string("FirstSelected"), true);
|
||||
ptrList->insert(std::string("Second"), false);
|
||||
ptrList->insert(std::string("SecondSelected"), true);
|
||||
ptrF->add(new SubmitButton("", "Click"));
|
||||
std::ostringstream ostr;
|
||||
std::ofstream fstr("testFormListBox.html");
|
||||
TeeOutputStream out(ostr);
|
||||
out.addStream(fstr);
|
||||
ptr->renderHead(context, out);
|
||||
ptr->renderBody(context, out);
|
||||
std::string result = ostr.str();
|
||||
}
|
||||
|
||||
|
||||
void ExtJSTest::testDateFormatConversion()
|
||||
{
|
||||
std::string result = Utility::convertPocoDateToPHPDate(Poco::DateTimeFormat::ISO8601_FORMAT);
|
||||
@ -1606,6 +1640,7 @@ CppUnit::Test* ExtJSTest::suite()
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testFormFrameVerticalLayout);
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testFormGridLayoutNullElements);
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testFormImage);
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testFormListBox);
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testDateFormatConversion);
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testCollapsible);
|
||||
CppUnit_addTest(pSuite, ExtJSTest, testCollapsible2);
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
void testFormFrameHorizontalLayout();
|
||||
void testFormFrameVerticalLayout();
|
||||
void testFormImage();
|
||||
void testFormListBox();
|
||||
void testTabView();
|
||||
void testCollapsible();
|
||||
void testCollapsible2();
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Version="9,00"
|
||||
Name="WebWidgets"
|
||||
ProjectGUID="{8962DAD7-4F7B-46D0-A451-8D3476606890}"
|
||||
RootNamespace="WebWidgets"
|
||||
@ -53,7 +53,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"
|
||||
/>
|
||||
@ -76,7 +75,7 @@
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\bin\Poco$(ProjectName)d.pdb"
|
||||
SubSystem="1"
|
||||
OptimizeForWindows98="1"
|
||||
OptimizeForWindows98="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="..\lib\Poco$(ProjectName)d.lib"
|
||||
@ -145,7 +144,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="0"
|
||||
CompileAs="0"
|
||||
/>
|
||||
@ -170,7 +168,7 @@
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
OptimizeForWindows98="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="..\lib\Poco$(ProjectName).lib"
|
||||
|
@ -42,6 +42,8 @@
|
||||
|
||||
#include "Poco/WebWidgets/Control.h"
|
||||
#include "Poco/WebWidgets/ListBoxCell.h"
|
||||
#include "Poco/WebWidgets/JavaScriptEvent.h"
|
||||
#include "Poco/FIFOEvent.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -54,7 +56,16 @@ class WebWidgets_API ListBox: public Control
|
||||
{
|
||||
public:
|
||||
typedef Poco::AutoPtr<ListBox> Ptr;
|
||||
typedef ListBoxCell::Data Data; /// An element plus its selected flag as pair
|
||||
typedef ListBoxCell::Data Data; /// An element plus its selected flag as std::pair
|
||||
typedef ListBoxCell::RowValueChange RowValueChange; /// the row plus old and new value
|
||||
|
||||
FIFOEvent<Poco::Net::HTTPServerResponse*> beforeLoad; /// thrown whenever a load is requested, internal event to which the ListBoxCellRenderer must register
|
||||
|
||||
JavaScriptEvent<ListBox*> afterLoad; // thrown after data was loaded
|
||||
|
||||
JavaScriptEvent<int> rowSelected; /// fires the row selected event
|
||||
|
||||
JavaScriptEvent<int> rowDeselected; /// fires the row deselected event
|
||||
|
||||
ListBox(const std::string& name);
|
||||
/// Creates a ListBox with the given name.
|
||||
@ -62,18 +73,6 @@ public:
|
||||
ListBox();
|
||||
/// Creates an anonymous TextField.
|
||||
|
||||
void setHeight(int height);
|
||||
/// Sets the height in pixel. A negative value equals autoSize.
|
||||
|
||||
int getHeight() const;
|
||||
/// Returns the height in pixel. A negative value equals autoSize.
|
||||
|
||||
void setWidth(int width);
|
||||
/// Sets the width in pixel. A negative value equals autoSize.
|
||||
|
||||
int getWidth() const;
|
||||
/// Returns the width in pixel. A negative value equals autoSize.
|
||||
|
||||
Data::const_iterator begin() const;
|
||||
/// ConstIterator to all elements
|
||||
|
||||
@ -104,6 +103,18 @@ public:
|
||||
void deselect(const Any& elem);
|
||||
/// Deselects the element.
|
||||
|
||||
void selectByIndex(int idx, bool sel = true);
|
||||
/// Selects the element by Index. idx values that are out of range are ignored
|
||||
|
||||
void deselectByIndex(int idx);
|
||||
/// Deselects the element. idx values that are out of range are ignored
|
||||
|
||||
void selectAll(bool sel= true);
|
||||
/// Selects all elements
|
||||
|
||||
void deselectAll();
|
||||
/// Deselects all elements
|
||||
|
||||
bool hasSelected() const;
|
||||
/// Returns true if at least one selected element exists
|
||||
|
||||
@ -117,10 +128,10 @@ protected:
|
||||
ListBox(const std::type_info& type);
|
||||
/// Creates a ListBox.
|
||||
|
||||
ListBox(const std::string& name, const std::type_info& type, Cell::Ptr ptrCell);
|
||||
ListBox(const std::string& name, const std::type_info& type, ListBoxCell::Ptr ptrCell);
|
||||
/// Creates a ListBox and assigns it the given name.
|
||||
|
||||
ListBox(const std::type_info& type, Cell::Ptr ptrCell);
|
||||
ListBox(const std::type_info& type, ListBoxCell::Ptr ptrCell);
|
||||
/// Creates a ListBox.
|
||||
|
||||
~ListBox();
|
||||
@ -131,6 +142,17 @@ protected:
|
||||
|
||||
void init(Cell::Ptr pCell);
|
||||
/// Common init code for all ctors.
|
||||
|
||||
void fireBeforeLoad(std::pair<ListBoxCell*, Poco::Net::HTTPServerResponse*>& data);
|
||||
|
||||
void fireAfterLoad(void* pSender);
|
||||
|
||||
void fireRowSelected(int& pos);
|
||||
|
||||
void fireRowDeselected(int& pos);
|
||||
|
||||
private:
|
||||
ListBoxCell* _pLBCell;
|
||||
};
|
||||
|
||||
|
||||
@ -138,101 +160,103 @@ protected:
|
||||
// inlines
|
||||
//
|
||||
|
||||
inline void ListBox::setHeight(int height)
|
||||
{
|
||||
cell<ListBoxCell>()->setHeight(height);
|
||||
}
|
||||
|
||||
|
||||
inline int ListBox::getHeight() const
|
||||
{
|
||||
return cell<ListBoxCell>()->getHeight();
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::setWidth(int width)
|
||||
{
|
||||
cell<ListBoxCell>()->setWidth(width);
|
||||
}
|
||||
|
||||
|
||||
inline int ListBox::getWidth() const
|
||||
{
|
||||
return cell<ListBoxCell>()->getWidth();
|
||||
}
|
||||
|
||||
|
||||
inline bool ListBox::hasSelected() const
|
||||
{
|
||||
return cell<ListBoxCell>()->hasSelected();
|
||||
return _pLBCell->hasSelected();
|
||||
}
|
||||
|
||||
|
||||
inline ListBox::Data::const_iterator ListBox::begin() const
|
||||
{
|
||||
return cell<ListBoxCell>()->begin();
|
||||
return _pLBCell->begin();
|
||||
}
|
||||
|
||||
|
||||
inline ListBox::Data::iterator ListBox::begin()
|
||||
{
|
||||
return cell<ListBoxCell>()->begin();
|
||||
return _pLBCell->begin();
|
||||
}
|
||||
|
||||
|
||||
inline ListBox::Data::const_iterator ListBox::end() const
|
||||
{
|
||||
return cell<ListBoxCell>()->end();
|
||||
return _pLBCell->end();
|
||||
}
|
||||
|
||||
|
||||
inline ListBox::Data::iterator ListBox::end()
|
||||
{
|
||||
return cell<ListBoxCell>()->end();
|
||||
return _pLBCell->end();
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::setElements(const ListBox::Data& elems)
|
||||
{
|
||||
cell<ListBoxCell>()->setElements(elems);
|
||||
_pLBCell->setElements(elems);
|
||||
}
|
||||
|
||||
|
||||
inline const ListBox::Data& ListBox::getElements() const
|
||||
{
|
||||
return cell<ListBoxCell>()->getElements();
|
||||
return _pLBCell->getElements();
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::insert(const Any& elem, bool selected)
|
||||
{
|
||||
cell<ListBoxCell>()->insert(elem, selected);
|
||||
_pLBCell->insert(elem, selected);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::erase(const Any& elem)
|
||||
{
|
||||
cell<ListBoxCell>()->erase(elem);
|
||||
_pLBCell->erase(elem);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::select(const Any& elem)
|
||||
{
|
||||
cell<ListBoxCell>()->select(elem);
|
||||
_pLBCell->select(elem);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::deselect(const Any& elem)
|
||||
{
|
||||
cell<ListBoxCell>()->deselect(elem);
|
||||
_pLBCell->deselect(elem);
|
||||
}
|
||||
|
||||
|
||||
inline const Any& ListBox::getSelected() const
|
||||
{
|
||||
return cell<ListBoxCell>()->getSelected();
|
||||
return _pLBCell->getSelected();
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::selectByIndex(int idx, bool sel)
|
||||
{
|
||||
_pLBCell->selectByIndex(idx, sel);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::deselectByIndex(int idx)
|
||||
{
|
||||
_pLBCell->deselectByIndex(idx);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::selectAll(bool sel)
|
||||
{
|
||||
_pLBCell->selectAll(sel);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBox::deselectAll()
|
||||
{
|
||||
_pLBCell->deselectAll();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -41,10 +41,15 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/Cell.h"
|
||||
#include "Poco/WebWidgets/Delegate.h"
|
||||
#include "Poco/FIFOEvent.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
class HTTPServerResponse;
|
||||
}
|
||||
namespace WebWidgets {
|
||||
|
||||
|
||||
@ -57,21 +62,34 @@ public:
|
||||
typedef std::vector<std::pair<Any, bool> > Data; /// An element plus its selected flag
|
||||
typedef std::vector<std::string> StringData;
|
||||
|
||||
static const std::string EV_LOADDATA;
|
||||
static const std::string EV_AFTERLOAD;
|
||||
static const std::string EV_ROWSELECTED;
|
||||
static const std::string ARG_SELECTED;
|
||||
static const std::string ARG_ROW;
|
||||
static const std::string VAL_SELECTED;
|
||||
static const std::string VAL_DESELECTED;
|
||||
|
||||
FIFOEvent<std::pair<ListBoxCell*, Poco::Net::HTTPServerResponse*> > beforeLoad; /// thrown whenever a load is requested, internal event to which the ListBoxCellRenderer must register
|
||||
|
||||
Delegate afterLoad; // thrown after data was loaded
|
||||
|
||||
FIFOEvent<int> rowSelected; /// fires the row selected event
|
||||
|
||||
FIFOEvent<int> rowDeselected; /// fires the row selected event
|
||||
|
||||
struct WebWidgets_API RowValueChange
|
||||
/// Data sent with a rowValueChanged event.
|
||||
{
|
||||
std::size_t row;
|
||||
const Poco::Any oldValue;
|
||||
const Poco::Any newValue;
|
||||
RowValueChange(std::size_t row, const Poco::Any& oldValue, const Poco::Any& newValue);
|
||||
};
|
||||
|
||||
ListBoxCell(View* pOwner);
|
||||
/// Creates a ListBoxCell.
|
||||
|
||||
void setHeight(int height);
|
||||
/// Sets the height in pixel. A negative value equals autoSize.
|
||||
|
||||
int getHeight() const;
|
||||
/// Returns the height in pixel. A negative value equals autoSize.
|
||||
|
||||
void setWidth(int width);
|
||||
/// Sets the width in pixel. A negative value equals autoSize.
|
||||
|
||||
int getWidth() const;
|
||||
/// Returns the width in pixel. A negative value equals autoSize.
|
||||
|
||||
Data::const_iterator begin() const;
|
||||
/// ConstIterator to all elements
|
||||
|
||||
@ -108,15 +126,31 @@ public:
|
||||
void deselect(const Any& elem);
|
||||
/// Deselects the element.
|
||||
|
||||
void selectByIndex(int idx, bool sel = true);
|
||||
/// Selects the element by Index. idx values that are out of range are ignored
|
||||
|
||||
void deselectByIndex(int idx);
|
||||
/// Deselects the element. idx values that are out of range are ignored
|
||||
|
||||
void selectAll(bool sel= true);
|
||||
/// Selects all elements
|
||||
|
||||
void deselectAll();
|
||||
/// Deselects all elements
|
||||
|
||||
bool hasSelected() const;
|
||||
/// Returns true if at least one selected element exists
|
||||
|
||||
const Any& getSelected() const;
|
||||
/// Returns the first selected element, exception if none was selected
|
||||
/// Returns the first selected element, exception if none was selected.
|
||||
/// To get all selected elements use getElements and iterate over the
|
||||
/// returned vector
|
||||
|
||||
// Cell
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
|
||||
void handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response);
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
@ -135,37 +169,12 @@ protected:
|
||||
private:
|
||||
Data _data;
|
||||
StringData _fmtCache;
|
||||
int _height;
|
||||
int _width;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline void ListBoxCell::setHeight(int height)
|
||||
{
|
||||
_height = height;
|
||||
}
|
||||
|
||||
|
||||
inline int ListBoxCell::getHeight() const
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
|
||||
inline void ListBoxCell::setWidth(int width)
|
||||
{
|
||||
_width = width;
|
||||
}
|
||||
|
||||
|
||||
inline int ListBoxCell::getWidth() const
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
|
||||
inline ListBoxCell::Data::const_iterator ListBoxCell::begin() const
|
||||
{
|
||||
@ -216,6 +225,18 @@ inline ListBoxCell::StringData::const_iterator ListBoxCell::endString() const
|
||||
}
|
||||
|
||||
|
||||
inline void ListBoxCell::deselectByIndex(int idx)
|
||||
{
|
||||
selectByIndex(idx, false);
|
||||
}
|
||||
|
||||
|
||||
inline void ListBoxCell::deselectAll()
|
||||
{
|
||||
selectAll(false);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -36,20 +36,21 @@
|
||||
|
||||
#include "Poco/WebWidgets/ListBox.h"
|
||||
#include "Poco/WebWidgets/ListBoxCell.h"
|
||||
#include "Poco/Delegate.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace WebWidgets {
|
||||
|
||||
|
||||
ListBox::ListBox(const std::string& name, const std::type_info& type, Cell::Ptr ptrCell):
|
||||
ListBox::ListBox(const std::string& name, const std::type_info& type, ListBoxCell::Ptr ptrCell):
|
||||
Control(name, type)
|
||||
{
|
||||
init(ptrCell);
|
||||
}
|
||||
|
||||
|
||||
ListBox::ListBox(const std::type_info& type, Cell::Ptr ptrCell):
|
||||
ListBox::ListBox(const std::type_info& type, ListBoxCell::Ptr ptrCell):
|
||||
Control(type)
|
||||
{
|
||||
init(ptrCell);
|
||||
@ -91,8 +92,12 @@ ListBox::~ListBox()
|
||||
|
||||
void ListBox::init()
|
||||
{
|
||||
ListBoxCell* pCell = new ListBoxCell(this);
|
||||
setCell(pCell);
|
||||
_pLBCell = new ListBoxCell(this);
|
||||
_pLBCell->afterLoad = delegate(*this, &ListBox::fireAfterLoad);
|
||||
_pLBCell->beforeLoad += Poco::delegate(this, &ListBox::fireBeforeLoad);
|
||||
_pLBCell->rowDeselected += Poco::delegate(this, &ListBox::fireRowDeselected);
|
||||
_pLBCell->rowSelected += Poco::delegate(this, &ListBox::fireRowSelected);
|
||||
setCell(_pLBCell);
|
||||
}
|
||||
|
||||
|
||||
@ -100,11 +105,38 @@ void ListBox::init(Cell::Ptr ptrCell)
|
||||
{
|
||||
ListBoxCell::Ptr ptr = ptrCell.cast<ListBoxCell>();
|
||||
poco_check_ptr (ptr);
|
||||
|
||||
_pLBCell = ptr;
|
||||
_pLBCell->afterLoad = delegate(*this, &ListBox::fireAfterLoad);
|
||||
_pLBCell->beforeLoad += Poco::delegate(this, &ListBox::fireBeforeLoad);
|
||||
_pLBCell->rowDeselected += Poco::delegate(this, &ListBox::fireRowDeselected);
|
||||
_pLBCell->rowSelected += Poco::delegate(this, &ListBox::fireRowSelected);
|
||||
setCell(ptrCell);
|
||||
}
|
||||
|
||||
|
||||
void ListBox::fireBeforeLoad(std::pair<ListBoxCell*, Poco::Net::HTTPServerResponse*>& data)
|
||||
{
|
||||
beforeLoad(this, data.second);
|
||||
}
|
||||
|
||||
|
||||
void ListBox::fireAfterLoad(void* pSender)
|
||||
{
|
||||
ListBox* pThis = this;
|
||||
afterLoad(this, pThis);
|
||||
}
|
||||
|
||||
|
||||
void ListBox::fireRowSelected(int& pos)
|
||||
{
|
||||
rowSelected(this, pos);
|
||||
}
|
||||
|
||||
|
||||
void ListBox::fireRowDeselected(int& pos)
|
||||
{
|
||||
rowDeselected(this, pos);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -35,20 +35,29 @@
|
||||
|
||||
|
||||
#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(),
|
||||
_height(-1),
|
||||
_width(-1)
|
||||
_fmtCache()
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,9 +65,7 @@ ListBoxCell::ListBoxCell(View* pOwner):
|
||||
ListBoxCell::ListBoxCell(View* pOwner, const std::type_info& type):
|
||||
Cell(pOwner, type),
|
||||
_data(),
|
||||
_fmtCache(),
|
||||
_height(-1),
|
||||
_width(-1)
|
||||
_fmtCache()
|
||||
{
|
||||
}
|
||||
|
||||
@ -70,7 +77,25 @@ ListBoxCell::~ListBoxCell()
|
||||
|
||||
void ListBoxCell::handleForm(const std::string& field, const std::string& value)
|
||||
{
|
||||
throw Poco::NotImplementedException();
|
||||
// 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<int> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -138,7 +163,14 @@ void ListBoxCell::select(const Any& elem)
|
||||
{
|
||||
Data::iterator it = find(elem);
|
||||
if (it != _data.end())
|
||||
it->second = true;
|
||||
{
|
||||
if (it->second != true)
|
||||
{
|
||||
it->second = true;
|
||||
int idx = it - _data.begin();
|
||||
rowSelected(this, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -146,7 +178,14 @@ void ListBoxCell::deselect(const Any& elem)
|
||||
{
|
||||
Data::iterator it = find(elem);
|
||||
if (it != _data.end())
|
||||
it->second = false;
|
||||
{
|
||||
if (it->second != false)
|
||||
{
|
||||
it->second = false;
|
||||
int idx = it - _data.begin();
|
||||
rowDeselected(this, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -172,18 +211,73 @@ const Any& ListBoxCell::getSelected() const
|
||||
bool ListBoxCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name << ":";
|
||||
if (hasSelected())
|
||||
Data::const_iterator it = _data.begin();
|
||||
bool written = false;
|
||||
for (std::size_t i = 0; i < _data.size(); ++i)
|
||||
{
|
||||
const Poco::Any& sel = getSelected();
|
||||
if (sel.type() == typeid(std::string) || sel.type() == typeid(Poco::DateTime))
|
||||
out << ":'" << getFormatter()->format(sel) << "'";
|
||||
else
|
||||
out << ":" << getFormatter()->format(sel);
|
||||
if (_data[i].second)
|
||||
{
|
||||
if (written)
|
||||
out << ",";
|
||||
else
|
||||
written = true;
|
||||
out << i;
|
||||
}
|
||||
}
|
||||
else
|
||||
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<ListBoxCell*, Poco::Net::HTTPServerResponse*> 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
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Version="9,00"
|
||||
Name="TestSuite"
|
||||
ProjectGUID="{09255B72-C314-4E57-BCF8-73698222F042}"
|
||||
Keyword="Win32Proj"
|
||||
@ -52,7 +52,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
@ -139,7 +138,6 @@
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
|
Loading…
x
Reference in New Issue
Block a user