|
#include <Wt/WServer>
|
|
#include <Wt/WIOService>
|
|
#include <Wt/WApplication>
|
|
#include <Wt/WEnvironment>
|
|
#include <Wt/WTabWidget>
|
|
#include <Wt/WTableView>
|
|
#include <Wt/WStandardItem>
|
|
#include <Wt/WStandardItemModel>
|
|
#include <Wt/WPushButton>
|
|
#include <Wt/WLabel>
|
|
#include <Wt/WLineEdit>
|
|
#include <Wt/WBootstrapTheme>
|
|
#include <Wt/WCssDecorationStyle>
|
|
#include <Wt/WBreak>
|
|
|
|
struct RowData {
|
|
RowData(){}
|
|
RowData(const std::string &s, const std::string &d, const std::string &c, const std::string &u, unsigned int i, int t, int r) :
|
|
cell1(s),
|
|
cell2(d),
|
|
cell3(c),
|
|
cell4(u),
|
|
value1(i), value2(t), value3(r)
|
|
{}
|
|
|
|
std::string cell1;
|
|
std::string cell2;
|
|
std::string cell3;
|
|
std::string cell4;
|
|
unsigned int value1;
|
|
int value2;
|
|
int value3;
|
|
};
|
|
|
|
class DataTable : public Wt::WContainerWidget
|
|
{
|
|
public:
|
|
DataTable(WContainerWidget *parent = 0);
|
|
|
|
private:
|
|
Wt::WTableView *table;
|
|
Wt::WStandardItemModel *model;
|
|
Wt::WPushButton *first;
|
|
|
|
Wt::WLineEdit *searchLineEdit;
|
|
Wt::WPushButton *search;
|
|
|
|
void initializeModel();
|
|
void firstPage();
|
|
|
|
void insertData(const std::vector<RowData> &data);
|
|
|
|
void searchText();
|
|
void onRowSelected();
|
|
void onClicked(const Wt::WModelIndex &index, const Wt::WMouseEvent &);
|
|
void setText(const Wt::WString &t);
|
|
|
|
enum { ROWS_PER_PAGE = 40 };
|
|
};
|
|
|
|
std::vector<RowData> dummyData(int n)
|
|
{
|
|
std::vector<RowData> data;
|
|
data.reserve(n);
|
|
|
|
static const RowData le{"Cell 1", "Cell 2", "Cell 3", "Cell 4", 0, 0, 14};
|
|
|
|
for (int i = 0; i < n; ++i)
|
|
data.push_back(le);
|
|
|
|
return data;
|
|
}
|
|
|
|
DataTable::DataTable(WContainerWidget *parent)
|
|
: Wt::WContainerWidget(parent)
|
|
, table(new Wt::WTableView)
|
|
, model(0)
|
|
, first(new Wt::WPushButton(" << "))
|
|
, searchLineEdit(new Wt::WLineEdit)
|
|
, search(new Wt::WPushButton("Search"))
|
|
{
|
|
first->clicked().connect(this, &DataTable::firstPage);
|
|
|
|
search->clicked().connect(this, &DataTable::searchText);
|
|
searchLineEdit->enterPressed().connect(this, &DataTable::searchText);
|
|
|
|
|
|
initializeModel();
|
|
table->setMinimumSize(850, Wt::WLength::Auto);
|
|
table->setModel(model);
|
|
table->setColumnWidth(4, 240);
|
|
table->setHeaderClickSortEnabled(true);
|
|
table->setSelectionMode(Wt::SingleSelection);
|
|
table->setSelectionBehavior(Wt::SelectRows);
|
|
table->clicked().connect(this, &DataTable::onClicked);
|
|
table->setAlternatingRowColors(true);
|
|
table->decorationStyle().setBorder(Wt::WBorder(), Wt::All);
|
|
|
|
auto form = new Wt::WContainerWidget;
|
|
form->setStyleClass("form-horizontal");
|
|
auto controlGroup = new Wt::WContainerWidget;
|
|
controlGroup->setStyleClass("control-group");
|
|
|
|
controlGroup->addWidget(first);
|
|
|
|
controlGroup->addWidget(searchLineEdit);
|
|
controlGroup->addWidget(search);
|
|
form->addWidget(controlGroup);
|
|
addWidget(form);
|
|
|
|
addWidget(table);
|
|
|
|
setContentAlignment(Wt::AlignLeft);
|
|
|
|
firstPage();
|
|
}
|
|
|
|
void DataTable::initializeModel()
|
|
{
|
|
if (model == 0) {
|
|
model = new Wt::WStandardItemModel(0, 5, this);
|
|
std::vector<std::string> headerData;
|
|
headerData.push_back(std::string("Title 1"));
|
|
headerData.push_back(std::string("Title 2"));
|
|
headerData.push_back(std::string("Title 3"));
|
|
headerData.push_back(std::string("Title 4"));
|
|
headerData.push_back(std::string("Title 5"));
|
|
|
|
for (std::vector<std::string>::size_type i = 0; i < headerData.size(); ++i)
|
|
model->setHeaderData(i, boost::any(headerData.at(i)));
|
|
}
|
|
}
|
|
|
|
|
|
void DataTable::firstPage()
|
|
{
|
|
searchLineEdit->setText(Wt::WString::Empty);
|
|
insertData(dummyData(ROWS_PER_PAGE));
|
|
}
|
|
|
|
void DataTable::insertData(const std::vector<RowData> &data)
|
|
{
|
|
model->removeRows(0, model->rowCount());
|
|
for (std::vector<RowData>::size_type i = 0; i < data.size(); ++i) {
|
|
|
|
const RowData &e = data.at(i);
|
|
std::vector<Wt::WStandardItem*> items;
|
|
items.reserve(5);
|
|
|
|
items.push_back(new Wt::WStandardItem(Wt::WString(e.cell1)));
|
|
items.push_back(new Wt::WStandardItem(Wt::WString(e.cell2)));
|
|
items.push_back(new Wt::WStandardItem(Wt::WString(e.cell3)));
|
|
items.push_back(new Wt::WStandardItem(Wt::WString(e.cell4)));
|
|
items.push_back(new Wt::WStandardItem(Wt::WString("{1}:{2}").arg(e.value2).arg(e.value3)));
|
|
|
|
model->appendRow(items);
|
|
}
|
|
}
|
|
|
|
void DataTable::searchText()
|
|
{
|
|
insertData(dummyData(1000));
|
|
first->setEnabled(true);
|
|
}
|
|
|
|
void DataTable::onRowSelected()
|
|
{
|
|
Wt::WModelIndexSet indexes = table->selectedIndexes();
|
|
if (!indexes.empty()) {
|
|
Wt::WModelIndex i = *indexes.begin();
|
|
const Wt::WString sn = model->item(i.row(), i.column())->text();
|
|
searchLineEdit->setText(sn);
|
|
searchLineEdit->setFocus();
|
|
}
|
|
}
|
|
|
|
void DataTable::onClicked(const Wt::WModelIndex &index, const Wt::WMouseEvent &)
|
|
{
|
|
const Wt::WString t = model->item(index.row(), 0)->text();
|
|
setText(t);
|
|
}
|
|
|
|
void DataTable::setText(const Wt::WString &t)
|
|
{
|
|
if (!t.empty()) {
|
|
searchLineEdit->setText(t);
|
|
searchLineEdit->setFocus();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
class Application : public Wt::WApplication
|
|
{
|
|
public:
|
|
Application(const Wt::WEnvironment &env)
|
|
: Wt::WApplication(env)
|
|
, tabs(0)
|
|
, dataTable(0)
|
|
{
|
|
addMetaHeader(Wt::MetaName,"viewport", "width=device-width, initial-scale=1");
|
|
Wt::WBootstrapTheme *theme = new Wt::WBootstrapTheme();
|
|
theme->setVersion(Wt::WBootstrapTheme::Version2);
|
|
theme->setResponsive(true);
|
|
setTheme(theme);
|
|
|
|
root()->addStyleClass("container");
|
|
loadData();
|
|
enableUpdates();
|
|
}
|
|
|
|
void update()
|
|
{
|
|
delete tabs->parent();
|
|
tabs = 0;
|
|
dataTable = 0;
|
|
loadData();
|
|
triggerUpdate();
|
|
}
|
|
|
|
private:
|
|
Wt::WTabWidget *tabs;
|
|
DataTable *dataTable;
|
|
|
|
void loadData()
|
|
{
|
|
auto *c = new Wt::WContainerWidget(root());
|
|
tabs = new Wt::WTabWidget(c);
|
|
tabs->setMaximumSize(850, Wt::WLength::Auto);
|
|
dataTable = new DataTable;
|
|
tabs->addTab(dataTable, Wt::WString("Tab"));
|
|
}
|
|
};
|
|
|
|
Wt::WApplication *createApplication(const Wt::WEnvironment& env)
|
|
{
|
|
return new Application(env);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
Wt::WRun(argc, argv, createApplication);
|
|
}
|
|
|