#include "compareitemlistdialog.h" #include "ui_compareitemlistwidget.h" #include #include "compareitemdialog.h" #include "UIStyleManager.h" #include "CompareItemData.h" #include "GlobalInfo.h" #include "tipwidget.h" #include "warning.h" #include "compareitemdetailwidget.h" #include "baseheader.h" #include "DelegateCheckBox.h" /* 重载比较函数 */ bool CSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { // /* 先比较是正常日还是特殊日 */ // auto leftDay = sourceModel()->data(left, UserRole_WeekDay).toInt(); // auto rightDay = sourceModel()->data(right, UserRole_WeekDay).toInt(); // if(leftDay != rightDay) // { // return leftDay < rightDay; /* 比较周几 */ // } // /* 日期类型相等,再比较时间 */ // auto leftTime = sourceModel()->data(left, UserRole_Time).toDateTime(); // auto rightTime = sourceModel()->data(right, UserRole_Time).toDateTime(); // if(leftDay == static_cast(enum_WeekDay::WeekDay_Special)) // { // /* 特殊日,比较日期和时间 */ // return leftTime < rightTime; // }else { // /* 正常日,只比较时间 */ // return leftTime.time() < rightTime.time(); // } return true; } CompareItemListDialog::CompareItemListDialog(QWidget *parent) : DialogBase(parent), ui(new Ui::CompareItemListWidget) { QWidget *widgetContent = new QWidget(this); ui->setupUi(widgetContent); /* 设置内容 */ setContentWidget(widgetContent); /* 移除底栏 */ removeBottomWidget(); /* 设置标题 */ setTitle("对比项列表", QSize(120, 18)); // UIStyle.registerWidget(widgetContent); // SPDLOG_LOGGER_DEBUG(m_logger, "ObjectName: {}", widgetContent->objectName().toStdString()); this->resize(1000 + 40, 800 + 40); /* 设置对话框大小,包含阴影的宽度 */ /* 连接信号和槽 */ connect(ui->pBtn_close, &QPushButton::clicked, this, &CompareItemListDialog::do_pBtn_close_Clicked); connect(ui->pBtn_add, &QPushButton::clicked, this, &CompareItemListDialog::do_pBtn_add_Clicked); connect(ui->pBtn_delete, &QPushButton::clicked, this, &CompareItemListDialog::do_pBtn_delete_Clicked); connect(ui->pBtn_modify, &QPushButton::clicked, this, &CompareItemListDialog::do_pBtn_edit_Clicked); connect(ui->pBtn_enableCPItem, &QPushButton::clicked, this, &CompareItemListDialog::do_pBtn_enable_Clicked); connect(ui->pBtn_disableCPItem, &QPushButton::clicked, this, &CompareItemListDialog::do_pBtn_disable_Clicked); /* 设置TableView */ ui->tableView->setParent(nullptr); /* 先移除父对象 */ ui->tableView->deleteLater(); /* 延迟删除 */ ui->tableView = new CTableView(ui->widgetContent); auto layout = ui->widgetContent->layout(); layout->addWidget(ui->tableView); /* 初始化表格 */ initTable(); UIStyle.registerWidget(widgetContent); } CompareItemListDialog::~CompareItemListDialog() { UIStyle.unregisterWidget(getContentWidget()); delete ui; } /* 设置已有的对比项数据 */ void CompareItemListDialog::setCompareItemList(const QList& list) { for(const CompareItemTableItem_t& item : list) { /* 添加到表格中 */ addRow(item); } } /* 点击了关闭按钮 */ void CompareItemListDialog::do_pBtn_close_Clicked() { this->close(); } /* 点击了添加按钮 */ void CompareItemListDialog::do_pBtn_add_Clicked() { /* 获取当前所有的对比项名称 */ QList listItemNames = CIData.getCompareItemNameList(); CompareItemDialog dlg; /* 设置默认参数 */ dlg.setDefaultParams(GInfo.getDefaultCompareItem()); /* 设置对比项名称列表 */ dlg.setCompareItemNameList(listItemNames); dlg.exec(); /* 判断是否按下了确定按钮 */ if(!dlg.isOK()) { return; /* 如果没有按下确定按钮,直接返回 */ } /* 获取对比项信息 */ CompareItemInfo_t ciInfo = dlg.getCompareItemInfo(); /* 获取一个未使用的对比项ID */ int id = CIData.getUnusedCompareItemID(); /* 添加到全局对比项数据中 */ ciInfo.nID = id; /* 设置对比项ID */ CIData.addCompareItem(ciInfo); /* 添加到表格中 */ CompareItemTableItem_t tableItem; tableItem.nSerialNum = m_model->rowCount() + 1; /* 序号 */ tableItem.nID = ciInfo.nID; /* 对比项ID */ tableItem.strName = ciInfo.strName; /* 对比项名称 */ tableItem.isEnable = ciInfo.isEnable; /* 对比项状态 */ tableItem.nChannelCount = ciInfo.mapRoad.size(); /* 通道数 */ addRow(tableItem); TipWidget::display(TipWidget::OPERATOR_OK, "对比项新增成功", this); } /* 点击了删除按钮 */ void CompareItemListDialog::do_pBtn_delete_Clicked() { /* 获取第一列选中的列,以CheckBox选中为准,获取到需要删除的对比项ID */ QList listCheckedID; for(int i = m_model->rowCount() - 1; i >= 0; --i) { bool isChecked = m_model->data(m_model->index(i, 0), Qt::CheckStateRole).toBool(); if(isChecked) { int nID = m_model->data(m_model->index(i, 0), m_userRole_CompareItemID).toInt(); listCheckedID.push_back(nID); } } if(listCheckedID.isEmpty()) { TipWidget::display(TipWidget::OPERATOR_WARN, "请先选择要删除的对比项", GInfo.getTopWindow()); return; } /* 确认删除 */ Warning w; w.setTitle("删除对比项"); w.setText("是否确认删除选中的对比项?"); w.exec(); if(!w.isOk()) { return; /* 如果没有按下确定按钮,直接返回 */ } /* 删除选中的行 */ // for(const QModelIndex& index : selectedRows) // { // /* 获取对比项ID */ // // int nID = m_model->data(m_model->index(index.row(), 0), m_userRole_CompareItemID).toInt(); // // int nID = m_model->data(index, m_userRole_CompareItemID).toInt(); // int nID = index.data(m_userRole_CompareItemID).toInt(); // // SPDLOG_LOGGER_INFO(m_logger, "删除对比项ID: {}", nID); // /* 从全局对比项数据中删除 */ // CIData.removeCompareItem(nID); // } /* 删除表格中的数据,需要倒叙删除,因为 selectedRows 也会继续向 m_model 获取数据 */ // for (int i = selectedRows.size() - 1; i >= 0; --i) // { // m_model->removeRow(selectedRows[i].row()); // } /* 获取第一列选中的列,以CheckBox选中为准,获取到需要删除的对比项ID */ for(int i = m_model->rowCount() - 1; i >= 0; --i) { bool isChecked = m_model->data(m_model->index(i, 0), Qt::CheckStateRole).toBool(); if(isChecked) { int nID = m_model->data(m_model->index(i, 0), m_userRole_CompareItemID).toInt(); CIData.removeCompareItem(nID); m_model->removeRow(i); } } /* 重新排序 */ for(int i = 0; i < m_model->rowCount(); i++) { m_model->setData(m_model->index(i, 0), i + 1); } } /* 点击了编辑按钮 */ void CompareItemListDialog::do_pBtn_edit_Clicked() { /* 获取第一列选中的列,以CheckBox选中为准,获取到需要删除的对比项ID */ std::map mapCheckedID; for(int i = m_model->rowCount() - 1; i >= 0; --i) { bool isChecked = m_model->data(m_model->index(i, 0), Qt::CheckStateRole).toBool(); if(isChecked) { int nID = m_model->data(m_model->index(i, 0), m_userRole_CompareItemID).toInt(); mapCheckedID[nID] = m_model->index(i, 1); } } if(mapCheckedID.empty()) { TipWidget::display(TipWidget::OPERATOR_WARN, "请先选择要编辑的对比项", GInfo.getTopWindow()); return; } bool isMultiEdit = false; if(mapCheckedID.size() == 1) { isMultiEdit = false; }else { isMultiEdit = true; } /* 获取对比项ID */ int nID = mapCheckedID.begin()->first; /* 查找对比项信息 */ CompareItemInfo_t ciInfo = CIData.findCompareItemByID(nID); if(ciInfo.nID < 0) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项不存在,无法编辑", GInfo.getTopWindow()); SPDLOG_LOGGER_WARN(m_logger, "对比项ID {} 不存在,无法编辑", nID); return; } QList listItemNames = CIData.getCompareItemNameList(); /* 打开对比项编辑对话框 */ CompareItemDialog dlg; /* 设置默认参数 */ dlg.setDefaultParams(ciInfo); dlg.setMultiEditMode(isMultiEdit); dlg.setCompareItemNameList(listItemNames); dlg.exec(); /* 判断是否按下了确定按钮 */ if(!dlg.isOK()) { return; /* 如果没有按下确定按钮,直接返回 */ } /* 获取对比项信息 */ CompareItemInfo_t newCiInfo = dlg.getCompareItemInfo(); if(isMultiEdit) { bool isMainEnabled = newCiInfo.mapRoad[1].isEnableRecord; bool isSecondEnabled = newCiInfo.mapRoad[2].isEnableRecord; /* 处理多项编辑,挨个获取对比项信息修改 */ for(auto& pair : mapCheckedID) { auto item = CIData.findCompareItemByID(pair.first); item.mapRoad[1].isEnableRecord = isMainEnabled; /* 主通道是否开启录音 */ item.mapRoad[2].isEnableRecord = isSecondEnabled; /* 第二通道是否开启录音 */ item.setVolumeDetectParams(newCiInfo); /* 修改音量检测参数 */ /* 判断有没有修改启用状态 */ if(newCiInfo.isEnable != item.isEnable) { item.isEnable = newCiInfo.isEnable; /* 修改启用状态 */ /* 如果启用状态有变化,更新表格中的状态 */ m_model->setData(pair.second, newCiInfo.isEnable ? "启用" : "未启用"); } CIData.modifyCompareItem(item); } }else { /* 修改全局对比项数据 */ if(!CIData.modifyCompareItem(newCiInfo)) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项修改失败,请稍后重试", GInfo.getTopWindow()); SPDLOG_LOGGER_ERROR(m_logger, "对比项ID {} 修改失败", nID); return; } auto index = mapCheckedID.begin()->second; /* 判断有没有修改启用状态 */ if(newCiInfo.isEnable != ciInfo.isEnable) { /* 如果启用状态有变化,更新表格中的状态 */ m_model->setData(index, newCiInfo.isEnable ? "启用" : "未启用"); } } } /* 启用对比项 */ void CompareItemListDialog::do_pBtn_enable_Clicked() { /* 获取当前选中的行 */ QModelIndexList selectedRows = ui->tableView->selectionModel()->selectedRows(); if(selectedRows.isEmpty()) { TipWidget::display(TipWidget::OPERATOR_WARN, "请先选择要修改的对比项", GInfo.getTopWindow()); return; } for(auto& index : selectedRows) { /* 获取对比项ID */ int nID = m_model->data(m_model->index(index.row(), 0), m_userRole_CompareItemID).toInt(); /* 查找对比项信息 */ CompareItemInfo_t ciInfo = CIData.findCompareItemByID(nID); if(ciInfo.nID < 0) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项不存在,无法启用", GInfo.getTopWindow()); SPDLOG_LOGGER_WARN(m_logger, "对比项ID {} 不存在,无法启用", nID); return; } /* 判断是否已经启用 */ if(ciInfo.isEnable) { // TipWidget::display(TipWidget::OPERATOR_OK, "对比项已经处于启用状态", GInfo.getTopWindow()); return; /* 如果已经启用,直接返回 */ } /* 修改对比项状态为启用 */ ciInfo.isEnable = true; if(!CIData.modifyCompareItem(ciInfo)) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项启用失败,请稍后重试", GInfo.getTopWindow()); SPDLOG_LOGGER_ERROR(m_logger, "对比项ID {} 启用失败", nID); return; } /* 更新表格中的状态 */ m_model->setData(m_model->index(index.row(), 1), "启用"); } } /* 禁用对比项 */ void CompareItemListDialog::do_pBtn_disable_Clicked() { /* 获取当前选中的行 */ QModelIndexList selectedRows = ui->tableView->selectionModel()->selectedRows(); if(selectedRows.isEmpty()) { TipWidget::display(TipWidget::OPERATOR_WARN, "请先选择要修改的对比项", GInfo.getTopWindow()); return; } for(auto& index : selectedRows) { /* 获取对比项ID */ int nID = m_model->data(m_model->index(index.row(), 0), m_userRole_CompareItemID).toInt(); /* 查找对比项信息 */ CompareItemInfo_t ciInfo = CIData.findCompareItemByID(nID); if(ciInfo.nID < 0) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项不存在,无法禁用", GInfo.getTopWindow()); SPDLOG_LOGGER_WARN(m_logger, "对比项ID {} 不存在,无法禁用", nID); return; } /* 判断是否已经启用 */ if(!ciInfo.isEnable) { // TipWidget::display(TipWidget::OPERATOR_OK, "对比项已经处于禁用状态", GInfo.getTopWindow()); return; } /* 修改对比项状态为启用 */ ciInfo.isEnable = false; if(!CIData.modifyCompareItem(ciInfo)) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项禁用失败,请稍后重试", GInfo.getTopWindow()); SPDLOG_LOGGER_ERROR(m_logger, "对比项ID {} 禁用失败", nID); return; } /* 更新表格中的状态 */ m_model->setData(m_model->index(index.row(), 1), "未启用"); } } /* 显示详情 */ void CompareItemListDialog::do_tableView_doubleClicked(const QModelIndex &index) { /* 判断是不是第4列 */ if(index.column() != 4) { /* 如果不是第4列,直接返回 */ return; } /* 获取对比项ID */ int nID = m_model->data(m_model->index(index.row(), 0), m_userRole_CompareItemID).toInt(); /* 查找对比项信息 */ CompareItemInfo_t ciInfo = CIData.findCompareItemByID(nID); if(ciInfo.nID < 0) { TipWidget::display(TipWidget::OPERATOR_WARN, "对比项不存在,无法查看详情", GInfo.getTopWindow()); SPDLOG_LOGGER_WARN(m_logger, "对比项ID {} 不存在,无法查看详情", nID); return; } /* 打开弹窗 */ CompareItemDetailWidget* detailWidget = new CompareItemDetailWidget(GInfo.getTopWindow()); /* 设置对比项信息 */ detailWidget->setCompareItemInfo(ciInfo); detailWidget->exec(); } /* 表格点击了一行 */ void CompareItemListDialog::do_tableView_clicked(const QModelIndex &index) { if(index.column() == 4) { /* 打开对比项详情弹窗 */ do_tableView_doubleClicked(index); return; } // int row = index.row(); // /* 修改第一列状态 */ // bool currentState = m_model->data(m_model->index(row, 0), Qt::CheckStateRole).toBool(); // bool nextState = !currentState; // m_model->setData(m_model->index(row, 0), nextState, Qt::CheckStateRole); } /* 修改了选择行的状态 */ void CompareItemListDialog::do_selectChanged(const QItemSelection &selected, const QItemSelection &deselected) { /* 这里获取的是选中的所有单元格数目 */ QModelIndexList selectedRows = selected.indexes(); QModelIndexList deselectedRows = deselected.indexes(); if(selectedRows.isEmpty() && deselectedRows.isEmpty()) { /* 如果没有选中行,直接返回 */ return; } /* 更新第一列的状态 */ for(const QModelIndex& index : selectedRows) { // bool currentState = m_model->data(m_model->index(index.row(), 0), Qt::CheckStateRole).toBool(); m_model->setData(m_model->index(index.row(), 0), Qt::Checked, Qt::CheckStateRole); } /* 如果有取消选择的行,更新第一列状态 */ for(const QModelIndex& index : deselectedRows) { // bool currentState = m_model->data(m_model->index(index.row(), 0), Qt::CheckStateRole).toBool(); m_model->setData(m_model->index(index.row(), 0), Qt::Unchecked, Qt::CheckStateRole); } /* 更新标题栏选中的状态,下面获取的才是真正的选中的行 */ int selectedCount = ui->tableView->selectionModel()->selectedRows().size(); Qt::CheckState headerState = Qt::Unchecked; if(selectedCount == m_model->rowCount()) { headerState = Qt::CheckState::Checked; }else if(selectedCount == 0) { headerState = Qt::CheckState::Unchecked; }else { headerState = Qt::CheckState::PartiallyChecked; } // SPDLOG_LOGGER_INFO(m_logger, "选中行数: {}, 总行数: {}, 标题状态: {}", selectedCount, m_model->rowCount(), static_cast(headerState)); /* 如果选中的行数等于总行数,说明全部选中 */ auto header = qobject_cast(ui->tableView->horizontalHeader()); if(header) { header->SetChecked(headerState); } } /* 点击了标题栏选择框 */ void CompareItemListDialog::do_headerSelect_clicked(bool state) { auto header = qobject_cast(ui->tableView->horizontalHeader()); if(header == nullptr) { return; } if(state) { for(int i = 0; i < m_model->rowCount(); ++i) { /* 设置第一列为选中状态 */ m_model->setData(m_model->index(i, 0), Qt::Checked, Qt::CheckStateRole); ui->tableView->selectionModel()->select(m_model->index(i, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } }else { for(int i = 0; i < m_model->rowCount(); ++i) { /* 设置第一列为未选中状态 */ m_model->setData(m_model->index(i, 0), Qt::Unchecked, Qt::CheckStateRole); ui->tableView->selectionModel()->select(m_model->index(i, 0), QItemSelectionModel::Deselect | QItemSelectionModel::Rows); } } } /* 初始化表格 */ void CompareItemListDialog::initTable() { /* 初始化视图模型 */ m_model = new QStandardItemModel(this); m_model->setColumnCount(5); /* 设置每一列的标题 */ m_model->setHeaderData(0, Qt::Horizontal, "序号"); m_model->setHeaderData(1, Qt::Horizontal, "状态"); m_model->setHeaderData(2, Qt::Horizontal, "对比项"); m_model->setHeaderData(3, Qt::Horizontal, "通道数"); m_model->setHeaderData(4, Qt::Horizontal, "操作"); // m_model->clear(); // m_sortModel = new CSortModel(this); // m_sortModel->setSourceModel(m_model); // m_sortModel->sort(0, Qt::AscendingOrder); /* 默认升序 */ /* 设置排序数据 */ // m_sortModel->setSortRole(QtUserRole::UserRole_Time); /* 设置排序角色 */ ui->tableView->setModel(m_model); /* 设置标题头部代理 */ auto oneHeader = new BaseHeader(ui->tableView); oneHeader->SetCheckable(true); ui->tableView->setHorizontalHeader(oneHeader); /* 设置选择属性 */ ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); /* 可多选 */ ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); /* 设置第一列代理 */ auto checkBoxDelegate = new DelegateCheckBox(ui->tableView); /* 设置多种选择状态 */ ui->tableView->setItemDelegateForColumn(0, checkBoxDelegate); /*--------------------------- 设置横向标题 -------------------------------*/ /* 设置横向标题可见 */ ui->tableView->horizontalHeader()->setVisible(true); /* 设置标题左对齐 */ ui->tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); /* 设置横向标题可点击 */ ui->tableView->horizontalHeader()->setSectionsClickable(true); /*--------------------------- 设置列 -------------------------------*/ /* 设置每列的高度 */ ui->tableView->verticalHeader()->setDefaultSectionSize(48); /* 设置横向表头高度为48像素(可根据需要调整) */ ui->tableView->horizontalHeader()->setFixedHeight(48); /* 设置列宽度固定 */ ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); /* 去掉列标题 */ ui->tableView->verticalHeader()->setVisible(false); /* 去掉网格线 */ ui->tableView->setShowGrid(false); /* 设置单元格不可编辑 */ ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); /* 禁止显示横向滚动条 */ // ui->tableView->horizontalHeader()->setStretchLastSection(true); /* 设置最后一列拉伸 */ /* 设置固定列宽度 */ ui->tableView->setColumnWidth(0, 160); /* 第一列宽度 */ ui->tableView->setColumnWidth(1, 160); /* 第二列宽度 */ ui->tableView->setColumnWidth(2, 240); /* 第三列宽度 */ ui->tableView->setColumnWidth(3, 280); /* 第四列宽度 */ ui->tableView->setColumnWidth(4, 96); /* 第五列宽度 */ /* 连接点击信号 */ // connect(ui->tableView, &QTableView::doubleClicked, this, &CompareItemListDialog::do_tableView_doubleClicked); connect(ui->tableView, &QTableView::clicked, this, &CompareItemListDialog::do_tableView_clicked); connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CompareItemListDialog::do_selectChanged); connect(oneHeader, &BaseHeader::sig_Checked, this, &CompareItemListDialog::do_headerSelect_clicked); /* 测试用,加入两列数据 */ // for(int i = 0; i < 10; ++i) // { // CompareItemTableItem_t item; // item.nSerialNum = i + 1; /* 序号 */ // item.nID = i + 1000; /* 对比项ID */ // item.strName = QString("对比项%1").arg(i + 1); /* 对比项名称 */ // item.isEnable = (i % 2 == 0); /* 偶数启用,奇数未启用 */ // item.nChannelCount = i + 1; /* 通道数 */ // addRow(item); // } } /* 添加一行 */ void CompareItemListDialog::addRow(CompareItemTableItem_t tableItem) { QList items; /* -------------------- 序号 -------------------- */ QStandardItem* item0 = new QStandardItem(QString::number(tableItem.nSerialNum)); item0->setCheckable(true); item0->setCheckState(Qt::Unchecked); items.append(item0); /* 保存这个对比项的ID */ item0->setData(tableItem.nID, m_userRole_CompareItemID); /* -------------------- 状态 -------------------- */ QString status = tableItem.isEnable ? "启用" : "未启用"; items.append(new QStandardItem(status)); /* -------------------- 对比项 -------------------- */ items.append(new QStandardItem(tableItem.strName)); /* -------------------- 通道数 -------------------- */ items.append(new QStandardItem(QString::number(tableItem.nChannelCount))); /* -------------------- 详情 -------------------- */ QStandardItem* item4 = new QStandardItem("详情"); /* 这个字体设置为蓝色 */ item4->setForeground(QBrush("#438EFF")); items.append(item4); m_model->appendRow(items); }