#include "DataTableWidget.h" #include "DataTableItemDelegate.h" #include "ProjectManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char *kDataTabName = "tabName"; static const char *kUUIDName = "uuidName"; DataTableItemModel::DataTableItemModel(QObject *parent) : QStandardItemModel(parent) { } QVariant DataTableItemModel::data(const QModelIndex &index, int role) const { QVariant value = QStandardItemModel::data(index, role); if (Qt::TextAlignmentRole == role) { value = Qt::AlignCenter; } return value; } DataTableWidget::DataTableWidget(SchemePlanManager::SchemeProcessInfo process, QWidget *parent) : QWidget(parent), m_process(process) { m_mind1 = new CMind(this); m_mind2 = new CMind(this); initWidget(); initLayout(); connectSignalsAndSlots(); m_comboDelegate = new DataTableComboDelegate(this); } SchemePlanManager::SchemeProcessInfo DataTableWidget::process() const { return m_process; } void DataTableWidget::initWidget() { m_dataTab = new QTabWidget(this); m_dataTab->setTabPosition(QTabWidget::South); m_pageLab = new QLabel(this); m_previous = new PushButton("上一级指标", this); m_next = new PushButton("下一级指标", this); } void DataTableWidget::initLayout() { m_layout = new QVBoxLayout(this); m_layout->setMargin(0); m_layout->addWidget(m_dataTab); m_pageLayout = new QHBoxLayout(); m_layout->addLayout(m_pageLayout); m_pageLayout->setSpacing(10); m_pageLayout->addStretch(); m_pageLayout->addWidget(m_previous); m_pageLayout->addWidget(m_pageLab); m_pageLayout->addWidget(m_next); m_pageLayout->addStretch(); } void DataTableWidget::connectSignalsAndSlots() { connect(m_previous, &PushButton::clicked, this, &DataTableWidget::slotPrevious); connect(m_next, &PushButton::clicked, this, &DataTableWidget::slotNext); connect(m_dataTab, &QTabWidget::currentChanged, this, &DataTableWidget::slotTabCurrentChanged); } void DataTableWidget::setupModels() { // 按照脑图层级创建各个表的 models m_models.clear(); QList hHeaders; QList vHeaders; for (int i = 1; i < m_mind1->levels(); i++) { QList modelList; /// 方案优选和综合效能的评估数据采集 /// 页面只有一级, 不用切换页面 /// 方案优选显示指标量纲和指标类型 /// 综合效能显示指标类型 if (m_process.type == SchemePlanManager::ImportEvalData && (m_process.indexType == ProjectManager::OptimalIndex || m_process.indexType == ProjectManager::EfficiencyIndex)) { DataTableItemModel *model = new DataTableItemModel(this); int hIndex = -1; QStandardItem *item = new QStandardItem("指标量纲"); model->setHorizontalHeaderItem(++hIndex, item); vHeaders = m_mind1->leaves(); for (int j = 0; j < vHeaders.count(); j++) { CNodeData node = vHeaders[j]; QStandardItem *item = new QStandardItem(); item->setEditable(false); item->setText(node.dimension); model->setItem(j, hIndex, item); } if (m_process.indexType == ProjectManager::OptimalIndex) { QStandardItem *item = new QStandardItem("指标类型"); model->setHorizontalHeaderItem(++hIndex, item); for (int k = 0; k < vHeaders.count(); k++) { CNodeData node = vHeaders[k]; QStandardItem *item = new QStandardItem(); item->setEditable(false); SchemePlanManager::IndexCostType cost = (SchemePlanManager::IndexCostType)node.type; item->setText(SchemePlanManager::stringFromIndexCostType(cost)); model->setItem(k, hIndex, item); } } updateModel(model, hHeaders, vHeaders, hIndex); hIndex += hHeaders.size(); m_schemeList.clear(); if (m_process.indexType == ProjectManager::EfficiencyIndex) { SchemeInfoService().QuerySchemeInfoByEngineerId(&m_schemeList, m_process.projectId, 1); } if (m_process.indexType == ProjectManager::OptimalIndex) { SchemeInfoService().QuerySchemeInfoByEngineerId(&m_schemeList, m_process.projectId, 0); } m_schemeStartIndex = hIndex + 1; if (m_schemeList.count() > 0) { for (SchemaEval *scheme : m_schemeList) { QStandardItem *item = new QStandardItem(scheme->name); model->setHorizontalHeaderItem(++hIndex, item); for (QString indexValue : scheme->valueStr.split(";")) { QStringList indexAndValue = indexValue.split(":"); if (indexAndValue.size() < 2) { continue; } for (int l = 0; l < model->rowCount(); l++) { QStandardItem *hHeader = model->verticalHeaderItem(l); if (hHeader->text() == indexAndValue.first()) { QStandardItem *item = new QStandardItem(indexAndValue.last()); item->setData(indexAndValue.last()); model->setItem(l, hIndex, item); } } } } } modelList.append(model); m_models[i] = modelList; break; } /// 权重分析数据: 能力重要度评估,方案优选评估,综合效能评估 /// 评估数据: 技术措施重要度评估 QList nodes = m_mind1->nodesInLevel(i); for (int j = 0; j < nodes.count(); j++) { CNodeData node = nodes[j]; DataTableItemModel *model = new DataTableItemModel(this); if (m_process.type == SchemePlanManager::ImportWeightData) { hHeaders = m_mind1->subNodes(node); if (m_process.dSource == SchemePlanManager::FromExpert) { vHeaders = hHeaders; } } if (m_process.type == SchemePlanManager::ImportEvalData) { if (m_process.indexType == ProjectManager::TechIndex) { hHeaders = m_mind1->subNodes(node); vHeaders = m_mind2->leaves(); } } model->setProperty(kDataTabName, node.name); updateModel(model, hHeaders, vHeaders); modelList.append(model); } m_models[i] = modelList; } for (auto modelList : m_models.values()) { for (auto model : modelList) { connect(model, &QStandardItemModel::itemChanged, this, &DataTableWidget::itemChanged); } } setCurrentPage(1); } void DataTableWidget::setupTabWidget() { m_dataTab->clear(); QList list = m_models[m_currentPage]; for (int j = 0; j < list.size(); j++) { DataTableItemModel *model = list[j]; QTableView *t = new QTableView(m_dataTab); t->setAlternatingRowColors(m_mind2->nodeList().count() > 0); t->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); t->horizontalHeader()->setStyleSheet("QHeaderView::section{background:rgb(244,244,244);color: black;}"); t->verticalHeader()->setStyleSheet("QHeaderView::section{background:rgb(244,244,244);color: black;}"); t->verticalHeader()->setDefaultAlignment(Qt::AlignCenter); t->setSelectionMode(QAbstractItemView::SingleSelection); t->setModel(model); m_dataTab->addTab(t, model->property(kDataTabName).toString()); if (m_process.type == SchemePlanManager::ImportEvalData && m_process.indexType == ProjectManager::OptimalIndex) { t->setItemDelegateForColumn(1, m_comboDelegate); } } } int DataTableWidget::currentPage() const { return m_currentPage; } void DataTableWidget::setCurrentPage(int p) { if (p < 1 || p > m_models.size()) { return; } m_currentPage = p; m_previous->setEnabled(p > 1); m_next->setEnabled(p < m_models.size()); setupTabWidget(); m_pageLab->setText(QString("共 %1 页, 当前第 %2 页").arg(m_models.size()).arg(p)); } void DataTableWidget::updateCurrentTable() { return; int c = m_dataTab->currentIndex(); QTableView *table = (QTableView *)m_dataTab->widget(c); if (table == nullptr || table->model() == nullptr || m_isSettingTable) { return; } QStandardItemModel *model = (QStandardItemModel *)table->model(); /// 设置顶部水平方向标题 int hIndex = -1; int dimensionIndex = -1; // 量纲所在列 int typeIndex = -1; // 指标类型所在列 // 指标 CNodeData n = m_mind1->nodesInLevel(m_currentPage)[c]; QList hList = m_mind1->subNodes(n); // 以下情况需要显示指标 // 导入权重分析数据 // 导入需求分析评估的评估数据 if (m_process.type == SchemePlanManager::ImportWeightData || m_process.indexType == ProjectManager::TechIndex) { for (CNodeData node : hList) { QStandardItem *item = new QStandardItem(node.name); item->setToolTip(node.remark); model->setHorizontalHeaderItem(++hIndex, item); } } // 导入方案优选评估或效能评估的评估数据时, 需要显示量纲 if (m_process.type == SchemePlanManager::ImportEvalData && (m_process.indexType == ProjectManager::OptimalIndex || m_process.indexType == ProjectManager::EfficiencyIndex)) { QStandardItem *item = new QStandardItem("指标量纲"); model->setHorizontalHeaderItem(++hIndex, item); dimensionIndex = hIndex; } // 导入方案优选评估的评估数据时, 需要显示指标类型 if (m_process.type == SchemePlanManager::ImportEvalData && m_process.indexType == ProjectManager::OptimalIndex) { QStandardItem *item = new QStandardItem("指标类型"); model->setHorizontalHeaderItem(++hIndex, item); typeIndex = hIndex; } /// 设置左侧垂直方向标题 QList vList; // 导入权重分析的专家数据时, 显示指标 if (m_process.type == SchemePlanManager::ImportWeightData && m_process.dSource == SchemePlanManager::FromExpert) { vList = hList; } // 导入评估数据时, 显示最后一级指标 if (m_process.type == SchemePlanManager::ImportEvalData) { if (m_process.indexType == ProjectManager::TechIndex) { vList = m_mind2->leaves(); } else { vList = m_mind1->leaves(); } } for (int i = 0; i < vList.count(); i++) { CNodeData node = vList[i]; QStandardItem *item = new QStandardItem(QString(" %1 ").arg(node.name)); item->setToolTip(node.remark); model->setVerticalHeaderItem(i, item); table->setRowHeight(i, 35); } /// 填充量纲和指标类型 for (int i = 0; i < vList.count(); i++) { CNodeData vNode = vList[i]; QStandardItem *d = new QStandardItem(); d->setData(Qt::AlignCenter, Qt::TextAlignmentRole); // 单元格文字居中 if (dimensionIndex >= 0) { d->setText(vNode.dimension); model->setItem(i, dimensionIndex, d); } if (typeIndex >= 0) { model->setItem(i, typeIndex, d); table->setItemDelegateForColumn(typeIndex, m_comboDelegate); } table->setRowHeight(i, 35); } /// 填充单元格 if (m_process.type == SchemePlanManager::ImportWeightData) { if (m_process.dSource == SchemePlanManager::FromExpert) { for (int i = 0; i < vList.count(); i++) { CNodeData vNode = vList[i]; for (int j = 0; j < hList.count(); j++) { CNodeData hNode = hList[j]; QStandardItem *item = new QStandardItem(); item->setData(Qt::AlignCenter, Qt::TextAlignmentRole); // 单元格文字居中 item->setBackground(QBrush(QColor("white"))); for (NodeMatrixInfo *info : m_data) { if (info->abscissa.toInt() == hNode.id && info->ordinate.toInt() == vNode.id) { item->setText(info->nodeValue); model->setItem(i, j, item); break; } } } table->setRowHeight(i, 35); } } else if (m_process.dSource == SchemePlanManager::FromMeasurement) { int row = model->rowCount(); for (int j = 0; j < hList.count(); j++) { CNodeData hNode = hList[j]; QStandardItem *item = new QStandardItem(); item->setData(Qt::AlignCenter, Qt::TextAlignmentRole); // 单元格文字居中 item->setBackground(QBrush(QColor("white"))); for (NodeMatrixInfo *info : m_data) { if (info->abscissa.toInt() == hNode.id) { item->setText(info->nodeValue); model->setItem(row, j, item); break; } } } } } else if (m_process.type == SchemePlanManager::ImportEvalData) { if (m_process.indexType == ProjectManager::TechIndex) { for (int i = 0; i < vList.count(); i++) { CNodeData vNode = vList[i]; for (int j = 0; j < hList.count(); j++) { CNodeData hNode = hList[j]; QStandardItem *item = new QStandardItem(); item->setData(Qt::AlignCenter, Qt::TextAlignmentRole); // 单元格文字居中 item->setBackground(QBrush(QColor("white"))); for (NodeMatrixInfo *info : m_data) { if (info->abscissa.toInt() == hNode.id && info->ordinate.toInt() == vNode.id) { item->setText(info->nodeValue); model->setItem(i, j, item); break; } } } table->setRowHeight(i, 35); } } } } void DataTableWidget::setSchemeList(const QList &list) { } void DataTableWidget::addScheme(SchemaEval *scheme) { if (m_process.type == SchemePlanManager::ImportEvalData && m_process.indexType == ProjectManager::EfficiencyIndex) { } if (m_models.count() <= 0 || m_models[1].count() <= 0) { return; } DataTableItemModel *model = m_models[1].first(); QStandardItem *item = new QStandardItem(scheme->name); model->setHorizontalHeaderItem(model->columnCount(), item); } QTabWidget *DataTableWidget::tabWidget() const { return m_dataTab; } CMind *DataTableWidget::mind1() const { return m_mind1; } CMind *DataTableWidget::mind2() const { return m_mind2; } void DataTableWidget::setNodeMatrixData(QList data, bool isExpertData) { m_isFillingData = true; /// 清空表中数据 for (QList modelList : m_models.values()) { for (DataTableItemModel *model : modelList) { for (int r = 0; r < model->rowCount(); r++) { for (int c = 0; c < model->columnCount(); c++) { QStandardItem *item = model->item(r, c); if (item != nullptr) { item->setData(""); item->setText(""); } } } } } if (data.size() <= 0) { m_isFillingData = false; return; } m_data = data; m_uuidStr = data.first()->strUuid; // 加载权重分析数据 if (m_process.type == SchemePlanManager::ImportWeightData) { if (m_process.dSource == SchemePlanManager::FromExpert) { // 专家数据 for (NodeMatrixInfo *info : data) { for (QList modelList : m_models.values()) { for (DataTableItemModel *model : modelList) { for (int r = 0; r < model->rowCount(); r++) { QStandardItem *rHeader = model->verticalHeaderItem(r); for (int c = 0; c < model->columnCount(); c++) { QStandardItem *cHeader = model->horizontalHeaderItem(c); if (cHeader->text() == info->abscissa && rHeader->text() == info->ordinate) { QStandardItem *item = new QStandardItem(); item->setText(info->nodeValue); item->setEditable(false); model->setItem(r, c, item); } } } } } } } else { // 实测数据 for (NodeMatrixInfo *info : data) { for (QList modelList : m_models.values()) { for (DataTableItemModel *model : modelList) { for (int c = 0; c < model->columnCount(); c++) { QStandardItem *cHeader = model->horizontalHeaderItem(c); if (cHeader->text() == info->abscissa) { QStandardItem *item = new QStandardItem(); item->setText(info->nodeValue); item->setData(info->nodeValue); model->setItem(0, c, item); } } } } } } } // 加载技术重要度的评估数据 // 由于表的结构相似, 所以不用不区分专家数据和实测数据 if (m_process.type == SchemePlanManager::ImportEvalData && m_process.indexType == ProjectManager::TechIndex) { for (NodeMatrixInfo *info : data) { for (QList modelList : m_models.values()) { for (DataTableItemModel *model : modelList) { for (int r = 0; r < model->rowCount(); r++) { QStandardItem *rHeader = model->verticalHeaderItem(r); for (int c = 0; c < model->columnCount(); c++) { QStandardItem *cHeader = model->horizontalHeaderItem(c); if (cHeader->text() == info->abscissa && rHeader->text() == info->ordinate) { QStandardItem *item = new QStandardItem(); item->setText(info->nodeValue); item->setData(info->nodeValue); model->setItem(r, c, item); } } } } } } } m_isFillingData = false; } void DataTableWidget::updateModel(DataTableItemModel *model, QList &hHeaders, QList &vHeaders, int hStart, int vStart) { for (int i = 0; i < hHeaders.size(); i++) { CNodeData node = hHeaders[i]; QStandardItem *item = new QStandardItem(node.name); item->setToolTip(node.remark); model->setHorizontalHeaderItem(i + hStart, item); } for (int i = 0; i < vHeaders.size(); i++) { CNodeData node = vHeaders[i]; QStandardItem *item = new QStandardItem(node.name); item->setToolTip(node.remark); model->setVerticalHeaderItem(i + vStart, item); } if (m_process.dSource == SchemePlanManager::FromExpert) { for (int i = 0; i < hHeaders.size(); i++) { for (int j = 0; j < vHeaders.size(); j++) { QStandardItem *item = new QStandardItem(); item->setEditable(false); model->setItem(j, i, item); } } } } void DataTableWidget::slotPrevious() { setCurrentPage(m_currentPage - 1); } void DataTableWidget::slotNext() { setCurrentPage(m_currentPage + 1); } void DataTableWidget::slotTabCurrentChanged(int c) { Q_UNUSED(c) updateCurrentTable(); } /// 用户编辑了表格数据后, 将数据存到数据库, 并更新本地数据源 void DataTableWidget::itemChanged(QStandardItem *item) { // 排除程序的填充数据操作, 只关心用户操作 if (m_isFillingData == true) { return; } // 校验输入字符的合法性, 只允许输入非负数 // 遇到非法字符时, 恢复原值 static bool useOldData = false; if (useOldData) { useOldData = false; return; } // ([0-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]) // (-?[1-9][0-9]+)|(-?[0-9])|(-?[1-9]\\d+\\.\\d+)|(-?[0-9]\\.\\d+) QString Pattern("(\\d*\\.?\\d*)"); // 匹配非负数 QRegExp reg(Pattern); if (!reg.exactMatch(item->text())) { useOldData = true; item->setText(item->data().toString()); return; } else { if (item->data().toString() != item->text()) { item->setData(item->text()); return; } } // 用户编辑实测数据, 包括权重数据和能力重要度评估数据 bool weightData = m_process.type == SchemePlanManager::ImportWeightData && m_process.dSource == SchemePlanManager::FromMeasurement; bool evalData = m_process.type == SchemePlanManager::ImportEvalData && m_process.dSource == SchemePlanManager::FromMeasurement && m_process.indexType == ProjectManager::TechIndex; // 用户编辑方案数据, 包括方案优选评估数据和效能评估数据 bool schemeData = m_process.type == SchemePlanManager::ImportEvalData && (m_process.indexType == ProjectManager::OptimalIndex || m_process.indexType == ProjectManager::EfficiencyIndex); if (weightData || evalData) { QString indexName = ProjectManager::nameOfIndexType((ProjectManager::IndexType)m_process.indexType); NodeMatrixInfo info; info.nodeValue = item->text(); info.engineerId = m_process.projectId; info.tableMsg = indexName; info.strUuid = m_uuidStr; QStandardItem *hHeader = item->model()->horizontalHeaderItem(item->column()); info.abscissa = hHeader->text(); if (evalData) { QStandardItem *vHeader = item->model()->verticalHeaderItem(item->row()); info.ordinate = vHeader->text(); } qDebug() << __FUNCTION__ << __LINE__ << info.tableMsg << info.strUuid << info.abscissa << info.ordinate << info.nodeValue << endl; bool ret = NodeMatrixService().UpdateMeasureData(info); if (ret) { emit sigMeasureDataEdited(&info); } } if (schemeData) { int schemeIndex = item->column() - m_schemeStartIndex; if (schemeIndex < 0 || schemeIndex >= m_schemeList.size()) { return; } SchemaEval *scheme = m_schemeList[schemeIndex]; QStringList valueList; for (int i = 0; i < item->model()->rowCount(); i++) { QStandardItem *vHeader = item->model()->verticalHeaderItem(i); QString indexName = vHeader->text(); QString valueStr = ""; QStandardItem *t = item->model()->item(i, item->column()); if (t != nullptr && t->text().trimmed().length() > 0) { valueStr = t->text(); } valueList.append(QString("%1:%2").arg(indexName).arg(valueStr)); } scheme->valueStr = valueList.join(";"); bool ret = SchemeInfoService().UpdateValueStrById(scheme->id, scheme->valueStr); qDebug() << __FUNCTION__ << __LINE__ << ret << endl; } }