123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- #include "MatrixTableWidget.h"
- #include "MatrixTableItemDelegate.h"
- #include "algorithm/ConsistencyCheck.h"
- #include <QApplication>
- #include <QDebug>
- #include <QDesktopWidget>
- #include <QHeaderView>
- #include <QMessageBox>
- #include <QTimer>
- #include <QtMath>
- #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<MatrixDataSource> MatrixTableWidget::getSource() const
- {
- return dataSource;
- }
- void MatrixTableWidget::paintMatrixTable(QList<NodeMatrixInfo *> 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<qreal> 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<qreal> weights = cc.getWeights();
- qDebug() << weights;
- qDebug() << currentPage;
- QList<DemandWeight *> 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<DemandWeight *> 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;
- }
|