#include "basicwidget.h" #include "ui_basicwidget.h" #include "compareitemlistdialog.h" #include "DialogBase.h" #include "UIStyleManager.h" #include "customcombobox.h" #include "CompareItemData.h" #include "tipwidget.h" #include "SystemConfig.h" #include "GlobalInfo.h" #include "SoundCardData.h" #include #include BasicWidget::BasicWidget(QWidget *parent) : QWidget(parent), ui(new Ui::BasicWidget) { ui->setupUi(this); m_logger = spdlog::get("ACASetting"); if(m_logger == nullptr) { fmt::print("BasicWidget: Logger ACASetting not found\n"); return; } connect(ui->pBtn_compareItem, &QPushButton::clicked, this, &BasicWidget::do_pBtn_CompareItemClicked); /* 设置UI */ UIStyle.registerWidget(this); /* 设置下拉框选项 */ ui->comBox_notConsistency->setViewShadowEffect(); ui->comBox_driverName->setViewShadowEffect(); ui->comBox_recordMode->setViewShadowEffect(); /* 设置IP地址格式限制 */ QRegularExpression ipRegex(R"(^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}$)"); QValidator *ipValidator = new QRegularExpressionValidator(ipRegex, this); ui->lineEdit_serverIP->setValidator(ipValidator); /* 初始化数据 */ /* 设置录音模式 */ for(auto it = g_mapRecordModes.begin(); it != g_mapRecordModes.end(); ++it) { ui->comBox_recordMode->addItem(it.value(), it.key()); } /* 设置不一致判断选项 */ for(auto it = g_mapNotConsistency.begin(); it != g_mapNotConsistency.end(); ++it) { ui->comBox_notConsistency->addItem(it.value(), it.key()); } /* 隐藏不一致判断选项,这个大部分没用了,有用的搬到AI对比中了 */ ui->label_5->hide(); ui->comBox_notConsistency->hide(); /* 连接信号和槽 */ connect(ui->comBox_driverName, QOverload::of(&QComboBox::currentIndexChanged), this, &BasicWidget::do_soundCardChanged); connect(ui->pBtn_restore, &QPushButton::clicked, this, &BasicWidget::do_pBtn_restore_clicked); connect(ui->checkBox_enableSoundCardName, &QCheckBox::clicked, this, &BasicWidget::do_checkBox_showSoundCardDesc_clicked); /* 设置声卡信息 */ setSoundCardInfo(); /* 设置从数据库读取到的选项 */ restoreBasicSettingInfo(); } BasicWidget::~BasicWidget() { UIStyle.unregisterWidget(this); delete ui; } /* 判断数据是否修改了 */ bool BasicWidget::isDataChanged() { if(isDataChangedBasicInfo() || isDataChangedCompareItem()) { return true; } return false; } /* 保存数据 */ bool BasicWidget::saveBasicInfo() { /* 取消所有的报警 */ cancelAllWarn(); bool isSuccess = true; /* 保存基础信息 */ if(!saveBasicSettingInfo()) { TipWidget::display(TipWidget::OPERATOR_WARN, "保存基础信息失败", GInfo.getTopWindow()); isSuccess = false; } /* 保存对比项信息 */ if(!saveCompareItemInfo()) { TipWidget::display(TipWidget::OPERATOR_WARN, "保存对比项信息失败", GInfo.getTopWindow()); isSuccess = false; } m_isModify = false; // 保存成功后,重置修改标志 return isSuccess; } void BasicWidget::do_pBtn_CompareItemClicked() { CompareItemListDialog dlg; /* 设置已有的对比项列表 */ dlg.setCompareItemList(CIData.getCompareItemTableData()); dlg.exec(); } /* 修改了选择了声卡 */ void BasicWidget::do_soundCardChanged(int nIndex) { if(nIndex < 0 || nIndex >= ui->comBox_driverName->count()) { SPDLOG_LOGGER_ERROR(m_logger, "选择的声卡索引无效: {}", nIndex); return; } std::string strSoundCardName = ui->comBox_driverName->currentData().toString().toStdString(); if(strSoundCardName.empty()) { SPDLOG_LOGGER_ERROR(m_logger, "选择的声卡无效,无法设置通道信息: {}", strSoundCardName); return; } /* 设置当前声卡信息 */ if(!SoundCards.setCurrentSoundCard(strSoundCardName)) { SPDLOG_LOGGER_ERROR(m_logger, "设置当前声卡失败,声卡名称: {}", strSoundCardName); return; } } /* 恢复配置项 */ void BasicWidget::do_pBtn_restore_clicked() { /* 从全局设置中恢复已修改的设置 */ restoreBasicSettingInfo(); /* 恢复对比项信息 */ restoreCompareItemInfo(); } /* 点击了显示声卡通道名的checkBox */ void BasicWidget::do_checkBox_showSoundCardDesc_clicked(bool checked) { SoundCards.setShowSoundCardDesc(checked); } /* 判断基础信息有没有修改 */ bool BasicWidget::isDataChangedBasicInfo() { const BaseConfig_t& srcBaseConfig = SysConfig.getBaseConfigSrc(); /* 获取基础配置信息 */ m_baseConfig.strServerIP = ui->lineEdit_serverIP->text(); m_baseConfig.nRecordMode = ui->comBox_recordMode->currentData().toInt(); m_baseConfig.strSoundCardName = ui->comBox_driverName->currentData().toString(); m_baseConfig.isEnableMultiCore = ui->checkBox_enableMultiCPU->isChecked(); m_baseConfig.isEnableDebugLog = ui->checkBox_enableDebug->isChecked(); m_baseConfig.isClearDirSystemOn = ui->checkBox_clearHistoryDir->isChecked(); m_baseConfig.isUsingSoundCardName = ui->checkBox_enableSoundCardName->isChecked(); /* 检查必填项的有效性 */ bool isSuccess = true; if(m_baseConfig.strServerIP.isEmpty()) { setWarn(ui->lineEdit_serverIP, true); TipWidget::display(TipWidget::OPERATOR_WARN, "服务器IP不能为空", this); isSuccess = false; } if(m_baseConfig.nRecordMode < 0) { setWarn(ui->comBox_recordMode, true); TipWidget::display(TipWidget::OPERATOR_WARN, "录音模式不能为空", this); isSuccess = false; } if(m_baseConfig.strSoundCardName.isEmpty()) { setWarn(ui->comBox_driverName, true); TipWidget::display(TipWidget::OPERATOR_WARN, "声卡驱动不能为空", this); isSuccess = false; } if(isSuccess == false) { return false; } // SPDLOG_LOGGER_DEBUG(m_logger, "修改后的基础配置信息: ServerIP: {}, RecordMode: {}, DriverName: {}, NotConsistency: {}, EnableMultiCore: {}, EnableDebugLog: {}, ClearHistoryDirOnStart: {}, UseSoundCardName: {}", // baseConfig.strServerIP.toStdString(), baseConfig.nRecordMode, baseConfig.strDriverName.toStdString(), // baseConfig.nNotConsistency, baseConfig.isEnableMultiCore, baseConfig.isEnableDebugLog, // baseConfig.isClearDirSystemOn, baseConfig.isUsingSoundCardName); // SPDLOG_LOGGER_DEBUG(m_logger, "现有的基础配置信息: ServerIP: {}, RecordMode: {}, DriverName: {}, NotConsistency: {}, EnableMultiCore: {}, EnableDebugLog: {}, ClearHistoryDirOnStart: {}, UseSoundCardName: {}", // srcBaseConfig.strServerIP.toStdString(), srcBaseConfig.nRecordMode, srcBaseConfig.strDriverName.toStdString(), // srcBaseConfig.nNotConsistency, srcBaseConfig.isEnableMultiCore, srcBaseConfig.isEnableDebugLog, // srcBaseConfig.isClearDirSystemOn, srcBaseConfig.isUsingSoundCardName); if(m_baseConfig == srcBaseConfig) { SPDLOG_LOGGER_DEBUG(m_logger, "基础配置信息没有修改,不需要保存"); return false; } return true; } /* 判断对比项信息有没有修改 */ bool BasicWidget::isDataChangedCompareItem() { /* 获取未修改过的对比项信息,不从数据库里获取了 */ const QList& srcCompareItems = CIData.getSrcCompareItemList(); const QList& nowItems = CIData.getCompareItemList(); QList insertItems; // 新增的对比项 QList deleteIDs; // 删除的对比项ID QList baseUpdateItems; // 修改的对比项基础信息 QList roadUpdateItems; // 修改的对比项通道信息 /* 先找到新增的对比项 */ findInsertCompareItem(srcCompareItems, nowItems, insertItems); /* 找到删除的对比项 */ findDeleteCompareItem(srcCompareItems, nowItems, deleteIDs); /* 找到修改的对比项 */ findUpdateCompareItem(srcCompareItems, nowItems, baseUpdateItems, roadUpdateItems); if(insertItems.isEmpty() && deleteIDs.isEmpty() && baseUpdateItems.isEmpty() && roadUpdateItems.isEmpty()) { SPDLOG_LOGGER_DEBUG(m_logger, "对比项信息没有修改,不需要保存"); return false; } return true; } /* 设置声卡信息 */ void BasicWidget::setSoundCardInfo() { const auto& soundCardInfo = SoundCards.getSoundCardInfo(); /* 清空现有的声卡信息 */ ui->comBox_driverName->clear(); /* 添加声卡信息到下拉框 */ for(const auto& it : soundCardInfo) { QString strDriverName = QString::fromStdString(it.first); ui->comBox_driverName->addItem(strDriverName, strDriverName); } /* 设置当前信息 */ ui->comBox_driverName->setCurrentIndex(0); } /* 保存基础信息 */ bool BasicWidget::saveBasicSettingInfo() { if(!isDataChangedBasicInfo()) { return true; // 没有修改,直接返回成功 } /* 将结构体转换成json字符串 */ std::string strJson; SysConfig.setBaseConfigToJson(m_baseConfig, strJson); if(!m_fromWebAPI->updateSystemConfig(Config_Base, strJson, SysConfig.mapSysConfigDesc[eSystemConfigType::eSCT_BaseConfig])) { SPDLOG_LOGGER_ERROR(m_logger, "更新基础配置信息失败"); return false; } SysConfig.setBaseConfig(m_baseConfig); // 更新本地的基础配置信息 return true; } /* 保存对比项信息 * 先获取未修改过的对比项信息,和现有的进行对比一下,找出新增、修改、删除的对比项。 * 新增的对比项直接添加到数据库中,修改的对比项更新到数据库中,删除的对比项从数据库中删除。 */ bool BasicWidget::saveCompareItemInfo() { if(m_fromWebAPI == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "WebAPI 未设置指针,无法保存对比项信息"); return false; } /* 获取未修改过的对比项信息,不从数据库里获取了 */ const QList& srcCompareItems = CIData.getSrcCompareItemList(); const QList& nowItems = CIData.getCompareItemList(); QList insertItems; // 新增的对比项 QList deleteIDs; // 删除的对比项ID QList baseUpdateItems; // 修改的对比项基础信息 QList roadUpdateItems; // 修改的对比项通道信息 /* 先找到新增的对比项 */ findInsertCompareItem(srcCompareItems, nowItems, insertItems); /* 找到删除的对比项 */ findDeleteCompareItem(srcCompareItems, nowItems, deleteIDs); /* 找到修改的对比项 */ findUpdateCompareItem(srcCompareItems, nowItems, baseUpdateItems, roadUpdateItems); /* 先删除已经消失的对比项 */ if(!deleteIDs.isEmpty()) { if(!m_fromWebAPI->deleteCompareItem(deleteIDs)) { SPDLOG_LOGGER_ERROR(m_logger, "删除对比项信息失败"); return false; } } /* 再插入新增的对比项 */ if(!insertItems.isEmpty()) { if(!m_fromWebAPI->insertCompareItem(insertItems)) { SPDLOG_LOGGER_ERROR(m_logger, "插入对比项信息失败"); return false; } } /* 更新修改的对比项基础信息 */ if(!baseUpdateItems.isEmpty()) { if(!m_fromWebAPI->updateCompareItemOnly(baseUpdateItems)) { SPDLOG_LOGGER_ERROR(m_logger, "更新对比项基础信息失败"); return false; } } /* 更新修改的对比项通道信息 */ if(!roadUpdateItems.isEmpty()) { if(!m_fromWebAPI->updateCompareItemRoadOnly(roadUpdateItems)) { SPDLOG_LOGGER_ERROR(m_logger, "更新对比项通道信息失败"); return false; } } /* 获取更新后的数据库信息 */ QList listNewItems; if(!m_fromWebAPI->getCompareItemInfo(listNewItems)) { SPDLOG_LOGGER_ERROR(m_logger, "获取最新对比项信息失败"); return false; } /* 更新本地的对比项数据 */ CIData.setCompareItemList(listNewItems); return true; } /* 查找新增的对比项信息 */ void BasicWidget::findInsertCompareItem(const QList& srcItems, const QList& nowItems, QList& insertItems) { for(const CompareItemInfo_t& nowItem : nowItems) { bool bFound = false; for(const CompareItemInfo_t& srcItem : srcItems) { if(nowItem.nID == srcItem.nID) { bFound = true; break; } } if(!bFound) { insertItems.append(nowItem); } } } /* 查找删除的对比项信息 */ void BasicWidget::findDeleteCompareItem(const QList& srcItems, const QList& nowItems, QList& deleteIDs) { for(const CompareItemInfo_t& srcItem : srcItems) { bool bFound = false; for(const CompareItemInfo_t& nowItem : nowItems) { if(srcItem.nID == nowItem.nID) { bFound = true; break; } } if(!bFound) { deleteIDs.append(srcItem.nID); } } } /* 查找修改的对比项 */ void BasicWidget::findUpdateCompareItem(const QList& srcItems, const QList& nowItems, QList& baseUpdateItems, QList& roadUpdateItems) { for(const CompareItemInfo_t& nowItem : nowItems) { bool bFound = false; for(const CompareItemInfo_t& srcItem : srcItems) { if(nowItem.nID == srcItem.nID) { bFound = true; if(!nowItem.isEqualBase(srcItem)) { baseUpdateItems.append(nowItem); } /* 对比通道信息 */ if(!nowItem.isEqualRoads(srcItem)) { roadUpdateItems.append(nowItem); } break; } } if(!bFound) { // SPDLOG_LOGGER_DEBUG(m_logger, "对比项ID {} 在源数据中未找到,可能是新增的对比项", nowItem.nID); } } } /* 恢复基础信息 */ void BasicWidget::restoreBasicSettingInfo() { const BaseConfig_t& baseConfig = SysConfig.getBaseConfigSrc(); ui->lineEdit_serverIP->setText(baseConfig.strServerIP); ui->comBox_recordMode->setCurrentIndex(ui->comBox_recordMode->findData(baseConfig.nRecordMode)); ui->comBox_driverName->setCurrentIndex(ui->comBox_driverName->findData(baseConfig.strSoundCardName)); ui->checkBox_enableMultiCPU->setChecked(baseConfig.isEnableMultiCore); ui->checkBox_enableDebug->setChecked(baseConfig.isEnableDebugLog); ui->checkBox_clearHistoryDir->setChecked(baseConfig.isClearDirSystemOn); ui->checkBox_enableSoundCardName->setChecked(baseConfig.isUsingSoundCardName); } /* 恢复对比项信息 */ bool BasicWidget::restoreCompareItemInfo() { const auto& srcCompareItems = CIData.getSrcCompareItemList(); /* 恢复对比项信息 */ CIData.setCompareItemList(srcCompareItems); return true; } /* 设置一个控件报警,边框显示红色 * 注意:这个功能需要在qss里设置属性[Warn=true],并实现相应的报警样式 */ void BasicWidget::setWarn(QWidget* widget, bool isWarn) { if(widget == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "设置控件报警失败,widget为nullptr"); return; } widget->setProperty("Warn", isWarn); widget->style()->unpolish(widget); widget->style()->polish(widget); widget->update(); } /* 取消全部报警 */ void BasicWidget::cancelAllWarn() { setWarn(ui->lineEdit_serverIP, false); setWarn(ui->comBox_driverName, false); setWarn(ui->comBox_recordMode, false); }