2025-08-20 19:00:22 +08:00
|
|
|
|
#include "PvTable.h"
|
|
|
|
|
|
#include "PvStyle.h"
|
2025-08-22 19:06:50 +08:00
|
|
|
|
#include "pv/PvApp.h"
|
2025-08-26 18:36:25 +08:00
|
|
|
|
#include "pv/PvPopWidget.h"
|
2025-08-20 19:00:22 +08:00
|
|
|
|
|
|
|
|
|
|
static const string STYLE_BKG =
|
|
|
|
|
|
"border-width:1 1 1 1px; border-style:outset solid; border-color:rgba(180,180,180,255);"
|
|
|
|
|
|
"background-color:rgba(80,80,80,0);";
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************
|
|
|
|
|
|
// PvTable
|
2025-08-28 18:42:37 +08:00
|
|
|
|
PvTable::PvTable(PARAM* p, int parent, int x, int y, int w, int irow, Options& opts)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
//: PvWidget(p, parent, PvRect(x, y, w, opts.item_height* row + (opts.show_header ? (opts.header_height) : 0))),
|
2025-08-28 18:42:37 +08:00
|
|
|
|
: PvObject(p), option(opts), nrow(irow), ncol(0)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 计算表格的显示区域
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int h = opts.row_height* irow + (opts.show_header ? (opts.head_height) : 0);
|
|
|
|
|
|
rect.set(x, y, w, h);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
// 表格的主窗体(QWidget设置样式无效)
|
2025-08-28 18:42:37 +08:00
|
|
|
|
pvid = PvApp::widget(p, parent, x, y, w, h+1);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
// 表格的背景色和边框样式
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
PvApp::label(p, pvid, 0, 0, w, h+1, "", qss::QSS_TABLE);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
vecHeads.resize(0);
|
|
|
|
|
|
vecRows.resize(nrow);
|
|
|
|
|
|
vecData.resize(nrow);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建行高亮显示背景
|
2025-08-28 18:42:37 +08:00
|
|
|
|
for (int row = 0; row < nrow; row++)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int y = row * option.row_height + (option.show_header ? option.head_height : 0);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
string qss = (row % 2 != 0) ? qss::QSS_TABLE_ROW_0 : qss::QSS_TABLE_ROW_1;
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int widgetRow = PvApp::label(p, pvid, 1, y, rect.w-2, option.row_height, "", qss);
|
|
|
|
|
|
pvHide(p, widgetRow);
|
|
|
|
|
|
vecRows[row].widget = widgetRow;
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PvTable::addHead(string id, string text, int width, vector<pair<string, string>> mapping)
|
|
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
vecHeads.push_back(Head(id, text, width, mapping));
|
|
|
|
|
|
ncol = vecHeads.size();
|
2025-08-22 19:06:50 +08:00
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (width <= -1) { width = rect.w-1 - posCol; }
|
|
|
|
|
|
int col = ncol - 1;
|
2025-08-22 19:06:50 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建表头的标签
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (option.show_header)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
vecHeads[col].pvid = PvApp::label(p, pvid, posCol, 0, width, option.head_height, text, qss::QSS_TABLE_HEAD);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建列的单元格
|
2025-08-28 18:42:37 +08:00
|
|
|
|
for (int row = 0; row < nrow; ++row)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int cellId = PvApp::label(p, vecRows[row].widget, posCol, 0, width, option.row_height, "", qss::QSS_TABLE_CELL);
|
|
|
|
|
|
vecRows[row].vecCells.push_back(cellId);
|
|
|
|
|
|
PvApp::bind(p, MOUSE_OVER_EVENT, cellId, [=](string s) { highlight(row, (s == "1")); });
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
posCol += width;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PvTable::addHead(vector<string> vec_text)
|
|
|
|
|
|
{
|
2025-08-22 19:06:50 +08:00
|
|
|
|
int colSize = vec_text.size();
|
|
|
|
|
|
int x = 0;
|
|
|
|
|
|
for (int i = 0; i < vec_text.size(); ++i)
|
|
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int w = float(rect.w-1) * float(i+1) / float(colSize);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
string text = vec_text[i];
|
|
|
|
|
|
this->addHead(text, text, w-x);
|
|
|
|
|
|
x = w;
|
|
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
void PvTable::setRowVisible(int irow, bool v)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (irow < 0 || irow >= vecRows.size())
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
auto& rowItem = vecRows[irow];
|
2025-08-22 19:06:50 +08:00
|
|
|
|
if (rowItem.visible != v)
|
|
|
|
|
|
{
|
|
|
|
|
|
rowItem.visible = v;
|
2025-08-28 18:42:37 +08:00
|
|
|
|
rowItem.visible ? pvShow(p, rowItem.widget) : pvHide(p, rowItem.widget);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
if (!v)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int col = 0; col<rowItem.vecCells.size(); ++col)
|
|
|
|
|
|
{
|
|
|
|
|
|
pvSetText(p, rowItem.vecCells[col], "");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
void PvTable::highlight(int irow, bool v)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
string qss = ((irow % 2 != 0) ? qss::QSS_TABLE_ROW_0 : qss::QSS_TABLE_ROW_1);
|
|
|
|
|
|
if (vecRows.size() > 0 && irow <= vecRows.size())
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (v) { qss = "background-color:rgba(14,45,60,200);border:1px solid rgba(255,0,0,100);"; }
|
2025-08-28 18:42:37 +08:00
|
|
|
|
pvSetStyleSheet(p, vecRows[irow].widget, qss.c_str());
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PvTable::addOperate(vector<string> vecOpt)
|
|
|
|
|
|
{
|
2025-08-22 19:06:50 +08:00
|
|
|
|
// 创建表头的标签
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (option.show_header)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
PvApp::label(p, pvid, posCol, 0, rect.w - posCol, option.head_height, "操作", qss::QSS_TABLE_HEAD);
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
for (int row = 0; row < nrow; ++row)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int cellWidget = PvApp::label(p, vecRows[row].widget, posCol, 0, rect.w - posCol, option.row_height, "", qss::QSS_TABLE_CELL);
|
|
|
|
|
|
vecOper.push_back({ cellWidget, vector<int>() });
|
|
|
|
|
|
auto& vec_opt_btn_ = vecOper.back().second;
|
2025-08-22 19:06:50 +08:00
|
|
|
|
int x = 5, w = 60;
|
|
|
|
|
|
for (int i = 0; i < vecOpt.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& title = vecOpt[i];
|
|
|
|
|
|
w = 20 + 15 * title.size() / 3;
|
|
|
|
|
|
int btn = PvApp::button(p, cellWidget, x, 4, w, 24, title, qss::button(14, "", "", "none; border-radius: 0px"));
|
|
|
|
|
|
PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](std::string) {
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (callbackOper) { callbackOper(row, 0, title); }
|
2025-08-22 19:06:50 +08:00
|
|
|
|
});
|
|
|
|
|
|
vec_opt_btn_.push_back(btn);
|
|
|
|
|
|
x += (w + 5);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PvTable::setOperateCallback(CallbackTableOpt cb)
|
|
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
callbackOper = cb;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
void PvTable::setRow(int irow, Fields& d)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (irow >= nrow) { return; }
|
2025-08-22 19:06:50 +08:00
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
vecData[irow] = d;
|
|
|
|
|
|
for (int col = 0; col < vecHeads.size(); ++col)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
auto& head = vecHeads[col];
|
2025-08-22 19:06:50 +08:00
|
|
|
|
string text = d.value(head.id);
|
|
|
|
|
|
text = head.getMapping(text);
|
2025-08-28 18:42:37 +08:00
|
|
|
|
pvSetText(p, vecRows[irow].vecCells[col], text.c_str());
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
setRowVisible(irow, true);
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
void PvTable::setRow(int irow, std::vector<std::string> vd)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
if (irow >= nrow) { return; }
|
|
|
|
|
|
pvShow(p, vecRows[irow].widget);
|
|
|
|
|
|
for (int col = 0; col < vecHeads.size(); ++col)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (col < vd.size()) {
|
2025-08-28 18:42:37 +08:00
|
|
|
|
auto& head = vecHeads[col];
|
2025-08-22 19:06:50 +08:00
|
|
|
|
string text = head.getMapping(vd[col]);
|
2025-08-28 18:42:37 +08:00
|
|
|
|
pvSetText(p, vecRows[irow].vecCells[col], text.c_str());
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
setRowVisible(irow, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Fields PvTable::row(int irow)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (irow >= 0 && irow < vecData.size()) ? vecData[irow] : Fields();
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
Fields PvTable::rowMapping(int rowid)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
Fields d = this->row(rowid);
|
|
|
|
|
|
this->mappingData(d);
|
|
|
|
|
|
return d;
|
2025-08-22 19:06:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PvTable::mappingData(Fields& fields)
|
|
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
for (int i=0; i< vecHeads.size(); ++i)
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
auto& head = vecHeads[i];
|
2025-08-26 18:36:25 +08:00
|
|
|
|
if (fields.contains(head.id))
|
2025-08-22 19:06:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
auto& val = fields.value(head.id);
|
|
|
|
|
|
val = head.getMapping(val);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int PvTable::rowCount()
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
return this->nrow;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
int PvTable::colCount()
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
return this->ncol;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
vector<Fields> PvTable::data()
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
return vecData;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PvTable::Head& PvTable::header(int col)
|
|
|
|
|
|
{
|
2025-08-28 18:42:37 +08:00
|
|
|
|
return vecHeads[col];
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const string STYLE_NORMAL =
|
2025-08-22 19:06:50 +08:00
|
|
|
|
"QPushButton { background-color:rgba(255,255,255,30);border-radius:0px;font:bold 16px ;color:white;border:1px solid #20a481;}"
|
|
|
|
|
|
"QPushButton:hover { background-color:rgba(32,164,128,255);color:white;}"
|
|
|
|
|
|
"QPushButton:pressed { border-width:3px 0 0 3px;border-style:inset;color:white;}"
|
|
|
|
|
|
"QPushButton:disabled { color: gray; border-color: gray; }";
|
2025-08-20 19:00:22 +08:00
|
|
|
|
|
|
|
|
|
|
static const string STYLE_ACTIVE =
|
2025-08-22 19:06:50 +08:00
|
|
|
|
"QPushButton { background-color:rgba(32,164,128,255);border-radius:0px;font:bold 16px ;color:white;border:1px solid #20a481;}"
|
|
|
|
|
|
"QPushButton:hover { background-color:rgba(32,164,128,255);color:white;}"
|
|
|
|
|
|
"QPushButton:pressed { border-width:3px 0 0 3px;border-style:inset;color:white;}"
|
|
|
|
|
|
"QPushButton:disabled { color: gray; border-color: gray; }";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PvPagination::PvPagination(PARAM* p, int parent, int x, int y, int n)
|
|
|
|
|
|
: PvObject(p)
|
|
|
|
|
|
{
|
|
|
|
|
|
pvid = PvApp::label(p, parent, x, y, 2*32 + 80, 30, "", "border: 0px solid gray;");
|
|
|
|
|
|
|
|
|
|
|
|
// 分页控件
|
|
|
|
|
|
btnPrev = PvApp::button(p, pvid, 0, 0, 30, 30, "<", STYLE_NORMAL);
|
|
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int btn = PvApp::button(p, pvid, (i+1)*32, 0, 30, 30, std::to_string(i+1), STYLE_NORMAL);
|
|
|
|
|
|
pvHide(p, btn);
|
|
|
|
|
|
vecBtn.push_back({btn, i});
|
|
|
|
|
|
PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](string) { this->activePage(i, true); });
|
|
|
|
|
|
}
|
|
|
|
|
|
btnNext = PvApp::button(p, pvid, 32, 0, 30, 30, ">", STYLE_NORMAL);
|
|
|
|
|
|
labelInfo = PvApp::label(p, pvid, 2*32, 0, 80, 30, " 共0页", qss::label(14, "rgb(27, 220, 224)"));
|
|
|
|
|
|
|
|
|
|
|
|
pvSetEnabled(p, btnPrev, 0);
|
|
|
|
|
|
pvSetEnabled(p, btnNext, 0);
|
|
|
|
|
|
PvApp::bind(p, PvEvent::BUTTON_EVENT, btnPrev, [=](string e) { this->activePage(--pageIndex, true); });
|
|
|
|
|
|
PvApp::bind(p, PvEvent::BUTTON_EVENT, btnNext, [=](string e) { this->activePage(++pageIndex, true); });
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
void PvPagination::setPage(int index, int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
pageIndex = index;
|
|
|
|
|
|
pageCount = count;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < vecBtn.size(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& btn = vecBtn[i];
|
|
|
|
|
|
auto btnid = btn.first;
|
|
|
|
|
|
int idx = i + 1;
|
|
|
|
|
|
if (idx > pageCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
pvHide(p, btnid);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
pvShow(p, btnid);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int x = (count+1)*32;
|
|
|
|
|
|
pvMove(p, btnNext, x, 0);
|
|
|
|
|
|
pvMove(p, labelInfo, x+=32, 0);
|
|
|
|
|
|
pvSetText(p, labelInfo, (" 共" + std::to_string(count) + "页").c_str());
|
|
|
|
|
|
pvResize(p, pvid, x += 81, 30);
|
|
|
|
|
|
this->activePage(pageIndex);
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
int PvPagination::page()
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-22 19:06:50 +08:00
|
|
|
|
return pageIndex;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
void PvPagination::activePage(int index, bool invoke)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-22 19:06:50 +08:00
|
|
|
|
if (pageCount == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
pageIndex = 0;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
pageIndex = index;
|
|
|
|
|
|
if (pageIndex < 0){ pageIndex = 0; }
|
|
|
|
|
|
if (pageIndex >= pageCount) { pageIndex = pageCount - 1; }
|
2025-08-20 19:00:22 +08:00
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
pvSetEnabled(p, btnPrev, pageIndex != 0);
|
|
|
|
|
|
pvSetEnabled(p, btnNext, (pageIndex != pageCount - 1));
|
2025-08-20 19:00:22 +08:00
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
if (btnActive != PV_ID_NUL) { pvSetStyleSheet(p, btnActive, STYLE_NORMAL.c_str()); }
|
|
|
|
|
|
btnActive = vecBtn[pageIndex].first;
|
|
|
|
|
|
pvSetStyleSheet(p, btnActive, STYLE_ACTIVE.c_str());
|
2025-08-20 19:00:22 +08:00
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
if (invoke)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (callback) callback(pageIndex);
|
|
|
|
|
|
}
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-22 19:06:50 +08:00
|
|
|
|
void PvPagination::setCallback(std::function<void(int index)> func)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-22 19:06:50 +08:00
|
|
|
|
callback = func;
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-26 18:36:25 +08:00
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// === PageTable ===
|
|
|
|
|
|
PageTable::PageTable(PARAM* p) : PvMask(p)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-26 18:36:25 +08:00
|
|
|
|
table = std::make_shared<PvTable>(p, 0, 20, 210, 1880, pageSize, option);
|
2025-08-28 18:42:37 +08:00
|
|
|
|
table->setOperateCallback([=](int irow, int icol, std::string text) {
|
|
|
|
|
|
curRowData = table->row(irow);
|
|
|
|
|
|
this->onOperate(irow, icol, text);
|
|
|
|
|
|
});
|
2025-08-26 18:36:25 +08:00
|
|
|
|
|
|
|
|
|
|
pagination = std::make_shared<PvPagination>(p, 0, 20, 780, 20);
|
|
|
|
|
|
pagination->setCallback([=](int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
pageIndex = index;
|
|
|
|
|
|
this->updateDataFromDB();
|
|
|
|
|
|
});
|
2025-08-20 19:00:22 +08:00
|
|
|
|
}
|
2025-08-26 18:36:25 +08:00
|
|
|
|
std::shared_ptr<PvPopWidget> PageTable::addPop(int w, int h, int w0, std::string name, std::vector<std::string> primaryKeys)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<PvPopWidget> pop = std::make_shared<PvPopWidget>(p, w, h, name);
|
|
|
|
|
|
pop->lineValWidth = w0;
|
|
|
|
|
|
pop->setPrimaryKeys(primaryKeys);
|
|
|
|
|
|
pop->setCallbackConfirm([=]()
|
|
|
|
|
|
{
|
|
|
|
|
|
auto fields = pop->getData();
|
|
|
|
|
|
std::string err = this->onValidation(pop, fields);
|
|
|
|
|
|
pop->setMsg(err);
|
2025-08-20 19:00:22 +08:00
|
|
|
|
|
2025-08-26 18:36:25 +08:00
|
|
|
|
if (err.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
XLOGD() << "POP get: data=" << fields.toStr();
|
|
|
|
|
|
if (pop->status == POP_OPER_EDIT) { pop->checkChangedData(fields); }
|
|
|
|
|
|
XLOGD() << "POP get: data=" << fields.toStr();
|
|
|
|
|
|
table->mappingData(fields);
|
|
|
|
|
|
XLOGD() << "POP get: data=" << fields.toStr();
|
|
|
|
|
|
err = this->onPopConfirm(pop, fields);
|
|
|
|
|
|
pop->setMsg(err);
|
|
|
|
|
|
if (err.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
this->hidePop(0);
|
|
|
|
|
|
this->updateDataFromDB();
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
pop->show(0);
|
|
|
|
|
|
vecPop.push_back(pop);
|
|
|
|
|
|
return pop;
|
|
|
|
|
|
}
|
2025-08-28 18:42:37 +08:00
|
|
|
|
void PageTable::showPop(int index, std::string oper, Fields fields)
|
2025-08-26 18:36:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
XLOGD() << "POP set: data=" << fields.toStr();
|
|
|
|
|
|
table->mappingData(fields);
|
|
|
|
|
|
XLOGD() << "POP set: data=" << fields.toStr();
|
|
|
|
|
|
if (index < vecPop.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& pop = vecPop[index];
|
|
|
|
|
|
pop->show(true);
|
|
|
|
|
|
pop->setStatus(oper);
|
|
|
|
|
|
pop->setData(fields);
|
|
|
|
|
|
pop->setMsg("");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void PageTable::hidePop(int index)
|
2025-08-20 19:00:22 +08:00
|
|
|
|
{
|
2025-08-26 18:36:25 +08:00
|
|
|
|
if (index < vecPop.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
vecPop[index]->show(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void PageTable::updateDataFromDB()
|
|
|
|
|
|
{
|
|
|
|
|
|
std::vector<Fields> result;
|
|
|
|
|
|
PageInfo pageInfo;
|
|
|
|
|
|
pageInfo.size = pageSize;
|
|
|
|
|
|
pageInfo.index = pageIndex;
|
|
|
|
|
|
this->onQueryTable(pageInfo, result);
|
2025-08-28 18:42:37 +08:00
|
|
|
|
for (int i = 0; i<table->rowCount(); ++i)
|
2025-08-26 18:36:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (i<result.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& fields = result[i];
|
2025-08-28 18:42:37 +08:00
|
|
|
|
table->setRow(i, result[i]);
|
2025-08-26 18:36:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
table->setRowVisible(i, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
pagination->setPage(pageInfo.index, pageInfo.total/pageInfo.size + int(pageInfo.total%pageInfo.size != 0));
|
|
|
|
|
|
}
|