#include "MatrixTableWidget.h" #include "MatrixTableItemDelegate.h" #include "algorithm/ConsistencyCheck.h" #include #include #include #include #include #include #include #include "dbService/ClassSet.h" #include "dbService/DBServiceSet.h" #include "dbService/NodeMatrixService.h" #include "dbService/DemandWeightService.h" MatrixTableWidget::MatrixTableWidget(bool diagonalOne, QWidget *parent) : QTableView(parent), diagonalIsOne(diagonalOne) { model = new QStandardItemModel(); this->setModel(model); paintDone = false; // connect(model, &QStandardItemModel::itemChanged, this, // &MatrixTableWidget::nodeValueChanged); connect(this, &QTableView::clicked, this, &MatrixTableWidget::itemClicked); } MatrixTableWidget::~MatrixTableWidget() { } void MatrixTableWidget::addRowNode(QString node, QString name, QString remark) { matrixRows << MatrixTableWidget::MatrixNode(node, name, remark); } void MatrixTableWidget::addColNode(QString node, QString name, QString remark) { matrixCols << MatrixTableWidget::MatrixNode(node, name, remark); } void MatrixTableWidget::setCurrentPage(int page) { currentPage = page; } void MatrixTableWidget::setTableIndexAndTableMsg(int index, int engineerId, int expertId, QString tableMsg) { m_tableIndex = index; m_engineerId = engineerId; m_expertId = expertId; m_table_msg = tableMsg; } void MatrixTableWidget::setMsgName(QString msgName) { m_msg_name = msgName; } QList MatrixTableWidget::getSource() const { return dataSource; } void MatrixTableWidget::paintMatrixTable(QList nodeValueInfoList) { // qDebug() << "nodeValueInfoList========" << nodeValueInfoList.size(); int row = matrixRows.count(); int col = matrixCols.count(); // qDebug() << row << col; this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); this->setSelectionMode(QAbstractItemView::SingleSelection); this->setSelectionBehavior(QAbstractItemView::SelectItems); model->setHorizontalHeaderItem(0, new QStandardItem("")); for (int c = 0; c < col; ++c) { model->setHorizontalHeaderItem(c + 1, new QStandardItem(matrixCols[c].name)); model->horizontalHeaderItem(c + 1)->setToolTip(matrixCols[c].remark); } for (int r = 0; r < row; ++r) { model->setItem(r, 0, new QStandardItem(matrixRows[r].name)); model->item(r, 0)->setToolTip(matrixRows[r].remark); model->item(r, 0)->setTextAlignment(Qt::AlignCenter); model->item(r, 0)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); for (int c = 1; c < col + 1; ++c) { MatrixDataSource data; data.row = r; data.col = c; if (c - 1 == r) { if (diagonalIsOne) { data.changed = true; data.nodeValue = "1"; } else { data.changed = false; for (NodeMatrixInfo *nodeMatrixInfo : nodeValueInfoList) { if (nodeMatrixInfo->abscissa == matrixRows[r].name && nodeMatrixInfo->ordinate == matrixCols[c - 1].name) { data.nodeValue = nodeMatrixInfo->nodeValue; data.changed = true; } } // data.nodeValue = ""; } } else { data.changed = false; // data.nodeValue = ""; for (NodeMatrixInfo *nodeMatrixInfo : nodeValueInfoList) { if (nodeMatrixInfo->abscissa == matrixRows[r].name && nodeMatrixInfo->ordinate == matrixCols[c - 1].name) { data.nodeValue = nodeMatrixInfo->nodeValue; data.changed = true; } } } // data.nodeValue = QString("%1, %2").arg(r).arg(c); model->setItem(r, c, new QStandardItem(data.nodeValue)); model->item(r, c)->setTextAlignment(Qt::AlignCenter); if ((r + 1 >= c) && diagonalIsOne) { model->item(r, c)->setFlags(Qt::ItemIsEnabled); model->item(r, c)->setBackground(QBrush(QColor("lightgray"))); } if (diagonalIsOne) { data.node = matrixRows[r].node; } else { data.node = matrixCols[c - 1].node; } data.abscissa = matrixRows[r].name; data.ordinate = matrixCols[c - 1].name; dataSource << data; } } emit returnModel(model); emit returnModelName(m_msg_name); paintDone = true; } void MatrixTableWidget::nodeValueChanged(QStandardItem *item) { if (paintDone) { bool valid = false; QStringList valist = item->text().trimmed().split("/"); if (valist.count() > 2) { // 两个除号 valid = false; item->setText(""); } else if (valist.count() == 2) { bool num = false; // 分子 bool den = false; // 分母 valist[0].toDouble(&num); valist[1].toDouble(&den); if ((!num) || (!den)) { valid = false; item->setText(""); } } else { bool dou = false; // double item->text().trimmed().toDouble(&dou); if (!dou) { valid = false; item->setText(""); } } if (diagonalIsOne) { if (item->row() + 1 < item->column()) { QString newText; QStringList split = item->text().split("/"); if (split.count() == 1) { if (split[0].toDouble() == 1.) { newText = split[0]; } else { newText = QString("1/%1").arg(item->text()); } } else { if (split[0].toDouble() == 1.) { newText = split[1]; } else { newText = split[1] + "/" + split[0]; } } model->item(item->column() - 1, item->row() + 1)->setText(newText); } } bool inputDone = true; for (int i = 0; i < dataSource.count(); ++i) { if (dataSource[i].row == item->row() && dataSource[i].col == item->column()) { dataSource[i].nodeValue = item->text().trimmed(); if (!item->text().trimmed().isEmpty()) { dataSource[i].changed = true; } else { dataSource[i].changed = false; } } if (!dataSource[i].changed) { inputDone = false; } } // if (inputDone) { qDebug() << "done"; } emit dataReady(inputDone); } } void MatrixTableWidget::itemClicked(const QModelIndex &index) { if (index.row() + 1 >= index.column()) { return; } QStringList l = { "1/9", "1/7", "1/5", "1/3", "1", "3", "5", "7", "9" }; SchemeBar *scheme = new SchemeBar(model->item(index.row(), 0)->text(), model->horizontalHeaderItem(index.column())->text(), l); scheme->setModal(true); scheme->setAttribute(Qt::WA_DeleteOnClose); connect(scheme, &SchemeBar::setValue, [=](QString val) { editItemData(index, val); }); scheme->show(); QPoint p = QCursor::pos(); if (p.x() + scheme->width() + 10 >= QApplication::desktop()->width()) { p.setX(QApplication::desktop()->width() - 10 - scheme->width()); } scheme->move(p); } void MatrixTableWidget::pollCellsData() { // 检测是否存在空值 for (int r = 0; r < model->rowCount(); ++r) { for (int c = 0; c < model->columnCount(); ++c) { if (model->item(r, c)->text().isEmpty()) { return; } } } QTimer::singleShot(0, this, [=]() { QStringList nodes; QVector nxn((int)qPow(model->rowCount(), 2), 0); for (int r = 0; r < model->rowCount(); ++r) { nodes << model->item(r, 0)->text().trimmed(); for (int c = 1; c < model->columnCount(); ++c) { QStringList content = model->item(r, c)->text().trimmed().split("/"); if (content.size() == 1) { nxn[r * model->rowCount() + c - 1] = content[0].toDouble(); } else { nxn[r * model->rowCount() + c - 1] = content[0].toDouble() / content[1].toDouble(); } } } ConsistencyCheck cc(nodes, nxn); if (!cc.consitst()) { QMessageBox::warning(this, "一致性校验", QString("CR:%" "1\r\n您好,一致性检验未通过!请您检查填写的" "数据是否有逻辑上的矛盾,例如A比B重" "要,B比C重要,然后又判断有C比A重要。") .arg(cc.CR())); QStandardItem *item = model->item(model->rowCount() - 2, model->columnCount() - 1); QStandardItem *item1 = model->item(model->columnCount() - 2, model->rowCount() - 1); for (int i = 0; i < dataSource.count(); ++i) { if (dataSource[i].row == item->row() && dataSource[i].col == item->column()) { dataSource[i].nodeValue = ""; item->setText(""); dataSource[i].changed = false; } else if (dataSource[i].row == item1->row() && dataSource[i].col == item1->column()) { dataSource[i].nodeValue = ""; item1->setText(""); dataSource[i].changed = false; } } } else { // 校验成功持久化数据 QStringList nodeList = cc.getNodes(); QVector weights = cc.getWeights(); qDebug() << weights; qDebug() << currentPage; QList list; if (currentPage == 1) { for (int i = 0; i < weights.length(); i++) { DemandWeight *demandWeight = new DemandWeight(); demandWeight->nodeName = nodeList.at(i); demandWeight->nodeWeight = weights.at(i); demandWeight->engineerId = m_engineerId; demandWeight->expertId = m_expertId; demandWeight->isValid = 0; demandWeight->tableIndex = m_tableIndex; demandWeight->tableMsg = m_table_msg; list.append(demandWeight); } } else { // 查询出第一页权重 QList firstList; DemandWeightService().QueryByTableIndexAndTableMsg(&firstList, m_expertId, m_engineerId, 0, m_table_msg); qDebug() << "firstList===" << firstList.size(); double weight = 0; if (firstList.size() != 0) { weight = firstList.at(m_tableIndex - 1)->nodeWeight; } for (int i = 0; i < weights.length(); i++) { DemandWeight *demandWeight = new DemandWeight(); demandWeight->nodeName = nodeList.at(i); demandWeight->nodeWeight = weights.at(i); demandWeight->engineerId = m_engineerId; demandWeight->expertId = m_expertId; demandWeight->isValid = 0; demandWeight->tableIndex = m_tableIndex; demandWeight->tableMsg = m_table_msg; demandWeight->nodeValue = demandWeight->nodeWeight * weight; list.append(demandWeight); } } if (DemandWeightService().QueryByTableIndexAndTableMsg(m_expertId, m_engineerId, m_tableIndex, m_table_msg)) { DemandWeightService().UpdateNodeValueList(list); } else { DemandWeightService().AddNodeWeightInfoList(list); } QMessageBox::information(this, "一致性比例合格", QString("CR:%1").arg(cc.CR())); // TODO 判断是否是保存后修改后,如保存后修改续自动调用保存 emit autoSave(); } }); } void MatrixTableWidget::editItemData(const QModelIndex &index, const QString &val) { model->itemFromIndex(index)->setText(val); QString symmetry; if (val.startsWith("1/")) { symmetry = val.split("/")[1]; } else { if (val == "0" || val == "1") { symmetry = val; } else { symmetry = "1/" + val; } } model->item(index.column() - 1, index.row() + 1)->setText(symmetry); QStandardItem *item = model->itemFromIndex(index); QStandardItem *item1 = model->item(index.column() - 1, index.row() + 1); for (int i = 0; i < dataSource.count(); ++i) { if (dataSource[i].row == item->row() && dataSource[i].col == item->column()) { dataSource[i].nodeValue = item->text().trimmed(); if (!item->text().trimmed().isEmpty()) { dataSource[i].changed = true; } else { dataSource[i].changed = false; } } else if (dataSource[i].row == item1->row() && dataSource[i].col == item1->column()) { dataSource[i].nodeValue = item1->text().trimmed(); if (!item1->text().trimmed().isEmpty()) { dataSource[i].changed = true; } else { dataSource[i].changed = false; } } } pollCellsData(); emit dataReady(isDataReady()); } bool MatrixTableWidget::isDataReady() const { if (dataSource.count() == 0) { return false; } for (MatrixDataSource data : dataSource) { if (data.changed == false) { return false; } } return true; }