#include "ExecPlan.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lhmaskwidget.h" #include "widget.h" #include "CustomTimeEdit.h" #include "UI/ExecPlan/ExecPlanItem.h" #include "UI/ExecPlan/addnormalitem.h" #include "UI/ExecPlan/addspecialitem.h" #include "Communication/devpacketresolution.h" #include "Communication/devicecommunication.h" #include "event/OneEvent.h" #include "common/globalinfo/globalinfo.h" #include "UI/Template/importtemplate.h" #include "UI/Template/savetotemplate.h" #include "UI/ScrollWidget/scrollwidget.h" #include "CommonModule/date/cdate.h" #include "CommonModule/TipWidget/tipwidget.h" #include "common/warning/warning.h" #include "timewidget.h" ExecPlan::ExecPlan(Widget* mainUI,QWidget* mask,QWidget *parent) : QWidget(parent), m_mainUI(mainUI), m_mask(mask) { m_logger = spdlog::get("ExecPlan"); if(nullptr == m_logger) { qDebug() << "ExecPlan获取logger失败"; } // m_first = true; m_leftColumn = new QWidget(this); m_stack = new QStackedWidget(this); m_pBtnAddItem = new QPushButton(this); m_pBtnClearExecPlan = new QPushButton(this); m_pBtnImportTemplate = new QPushButton(this); m_pBtnSaveTemplate = new QPushButton(this); m_pBtnGetEQMData = new QPushButton(this); m_labelButtomLine = new QLabel(this); m_pBtnDownload = new QPushButton(this); m_pBtnDefault = new QPushButton(this); m_rBtnDoTime = new QRadioButton(this); m_rBtnDoDay = new QRadioButton(this); /* 主体框架大小设置 */ this->resize(1872,698); m_leftColumn->resize(122,475); m_leftColumn->move(24,70); m_stack->resize(1700,474); m_stack->move(146,71); m_labelButtomLine->resize(1872,1); m_labelButtomLine->move(0,633); QLabel* stackButtomLine = new QLabel(this); stackButtomLine->resize(1822,1); stackButtomLine->move(25,544); /* 四个功能按钮设置 */ m_pBtnAddItem->resize(88,32); m_pBtnAddItem->move(40,561); m_pBtnClearExecPlan->resize(88,32); m_pBtnClearExecPlan->move(144,561); m_pBtnImportTemplate->resize(88,32); m_pBtnImportTemplate->move(248,561); m_pBtnSaveTemplate->resize(88,32); m_pBtnSaveTemplate->move(352,561); m_pBtnAddItem->setText("添加计划"); m_pBtnClearExecPlan->setText("清空计划"); m_pBtnImportTemplate->setText("导入模版"); m_pBtnSaveTemplate->setText("保存为模版"); m_pBtnGetEQMData->resize(110,32); m_pBtnGetEQMData->move(456,561); m_pBtnGetEQMData->setText("获取EQM数据"); /* 下载按钮设置 */ m_pBtnDownload->resize(60,32); m_pBtnDownload->move(1788,650); m_pBtnDownload->setText("下载"); /* 计划和模式按钮设置 */ QLabel* labelDefault = new QLabel(this); labelDefault->resize(70,14); labelDefault->move(24,28); labelDefault->setText("默认计划:"); m_pBtnDefault->resize(44,22); m_pBtnDefault->move(94,24); m_pBtnDefault->setCheckable(true); m_pBtnDefault->setChecked(true); QLabel* labelExecMode = new QLabel(this); labelExecMode->resize(70,14); labelExecMode->move(186,28); labelExecMode->setText("执行模式:"); m_rBtnDoTime->resize(80,16); m_rBtnDoTime->move(256,27); m_rBtnDoTime->setText("按时刻"); m_rBtnDoDay->resize(70,16); m_rBtnDoDay->move(354,27); m_rBtnDoDay->setText("按天"); m_rBtnDoTime->setChecked(true); /* 创建小提示 */ m_labelTip = new QLabel(this); m_labelTip->resize(14,14); m_labelTip->move(423,28); m_TipText = new QLabel(this); m_TipText->resize(936,56); m_TipText->move(448,8); m_TipText->setText(R"(按时刻执行模式:即以时刻点为单位进行执行,若某日既为普通日和特殊日,在某一时刻皆有执行动作,将优先执行特殊日在此时刻所计划的动作。 按天执行模式:即以天为单位进行执行,若某日既为普通日和特殊日,则当日一整天优先执行特殊日所计划的动作,普通日计划当日不再执行。)"); m_TipText->hide(); /* 设置样式表 */ m_leftColumn->setObjectName("LeftColumn"); m_labelButtomLine->setObjectName("ButtomLine"); m_pBtnAddItem->setObjectName("AddTime"); m_pBtnClearExecPlan->setObjectName("ClearTime"); m_pBtnImportTemplate->setObjectName("Import"); m_pBtnSaveTemplate->setObjectName("Save"); m_pBtnGetEQMData->setObjectName("GetEQMData"); m_pBtnDownload->setObjectName("Download"); stackButtomLine->setObjectName("stackButtomLine"); m_pBtnDefault->setObjectName("Default"); m_rBtnDoTime->setObjectName("DoTime"); m_rBtnDoDay->setObjectName("DoDay"); m_labelTip->setObjectName("Tip"); m_TipText->setObjectName("TipText"); /* 设置样式表 */ QFile file(":/qss/qss/PageExecPlan/PageExecPlan.qss"); if(file.open(QFile::ReadOnly)) { QString styleSheet = file.readAll(); this->setStyleSheet(styleSheet); file.close(); } else { SPDLOG_LOGGER_ERROR(m_logger,"打开文件失败:{}", file.fileName().toStdString()); } /* 创建一周8天的按钮和stack页面 */ uiSupplement(); /* 存储每日项的容器初始化 */ m_vecItem.clear(); for(int k = 0;k < 8;k++) { QList* one = new QList; one->clear(); m_vecItem.push_back(one); } /* 创建数据库连接 */ createDataBase(); /* 注册事件过滤器 */ m_labelTip->installEventFilter(this); connect(&DevInfo,SIGNAL(signal_addCfgDev()),this,SLOT(do_cfgDevChanged())); connect(m_pBtnAddItem,SIGNAL(clicked()),this,SLOT(do_pBtnAddExecPlan())); connect(m_pBtnDownload,SIGNAL(clicked()),this,SLOT(do_download())); connect(m_pBtnClearExecPlan,SIGNAL(clicked()),this,SLOT(do_clearExecPlan())); connect(m_pBtnSaveTemplate,SIGNAL(clicked()),this,SLOT(do_saveTemplate())); connect(m_pBtnImportTemplate,SIGNAL(clicked()),this,SLOT(do_importTemplate())); connect(m_pBtnGetEQMData,SIGNAL(clicked()),this,SLOT(do_pBtnGetEQMData())); /* 这些信号在全局类中定义的 */ connect(&DevInfo,SIGNAL(signal_deleteCfgDev(QString)),this,SLOT(do_devDelete(QString))); connect(&DevInfo,SIGNAL(signal_oneDevChanged(QString,QString)),this,SLOT(do_devChanged(QString,QString))); } ExecPlan::~ExecPlan() { for(auto& it : m_vecItem) { for(auto& it2 : *it) { delete it2; } } delete m_leftColumn; delete m_stack; delete m_pBtnAddItem; delete m_pBtnClearExecPlan; delete m_pBtnImportTemplate; delete m_pBtnSaveTemplate; delete m_labelButtomLine; } /* 补充UI */ void ExecPlan::uiSupplement() { /* 一周8天的8个按钮设置 */ for(int i = 0;i < 8;i++) { QPushButton* pBtn = new QPushButton(m_leftColumn); pBtn->resize(120,40); pBtn->move(1,i*40); pBtn->setProperty("Pressed",false); pBtn->setStyleSheet(R"( QPushButton[Pressed=true]{ background-color:rgba(68, 88, 254, 0.10); padding-left:20px; border-right:2px solid #4458FE; color:#4458FE; } QPushButton[Pressed=false]{ color: #3A3F63; padding-left:20px; background-color: #F5F5FA; border-right:0px solid #4458FE; } )"); /* 点击周几按钮 */ connect(pBtn,SIGNAL(clicked()),this,SLOT(do_selectDayOfWeeks())); m_vecWeeks.push_back(pBtn); } m_vecWeeks[0]->setText("星期一"); m_vecWeeks[1]->setText("星期二"); m_vecWeeks[2]->setText("星期三"); m_vecWeeks[3]->setText("星期四"); m_vecWeeks[4]->setText("星期五"); m_vecWeeks[5]->setText("星期六"); m_vecWeeks[6]->setText("星期日"); m_vecWeeks[7]->setText("特殊日"); /* 创建8个页面 */ for(int j = 0;j < 7;j++) { QWidget* w = new QWidget; w->resize(m_stack->width(),m_stack->height()); QLabel* labelNum = new QLabel(w); labelNum->resize(28,14); labelNum->move(16,16); labelNum->setText("序号"); QLabel* labelTime = new QLabel(w); labelTime->resize(28,14); labelTime->move(112,16); labelTime->setText("设备"); QLabel* execTime = new QLabel(w); execTime->resize(56,14); execTime->move(388,16); execTime->setText("执行时间"); QLabel* action = new QLabel(w); action->resize(28,14); action->move(536,16); action->setText("动作"); QLabel* operate = new QLabel(w); operate->resize(28,14); operate->move(812,16); operate->setText("操作"); auto sw = new ScrollWidget(w); sw->move(0,30); m_vecLayout.push_back(sw->Layout()); m_stack->addWidget(w); m_vecScrollArea.push_back(sw); } /* 单独创建特殊日页面 */ QWidget* w = new QWidget; w->resize(m_stack->width(),m_stack->height()); QLabel* labelNum = new QLabel(w); labelNum->resize(28,14); labelNum->move(16,16); labelNum->setText("序号"); QLabel* labelTime = new QLabel(w); labelTime->resize(28,14); labelTime->move(112,16); labelTime->setText("设备"); QLabel* execDate = new QLabel(w); execDate->resize(56,14); execDate->move(388,16); execDate->setText("执行日期"); QLabel* execTime = new QLabel(w); execTime->resize(56,14); execTime->move(536,16); execTime->setText("执行时间"); QLabel* action = new QLabel(w); action->resize(28,14); action->move(684,16); action->setText("动作"); QLabel* operate = new QLabel(w); operate->resize(28,14); operate->move(960,16); operate->setText("操作"); auto sw = new ScrollWidget(w); sw->move(0,30); m_vecLayout.push_back(sw->Layout()); m_stack->addWidget(w); m_vecScrollArea.push_back(sw); /* 默认当日周几 */ int day = QDate::currentDate().dayOfWeek() - 1; m_vecWeeks[day]->setProperty("Pressed",true); m_stack->setCurrentIndex(day); /* 需要手动更新控件,使其生效 */ m_leftColumn->style()->unpolish(m_vecWeeks[0]); m_leftColumn->style()->polish(m_vecWeeks[0]); } /** * @brief 判断时间是否重复 * @param time * @return true:时间重叠 * false:不重叠 */ bool ExecPlan::judgeTimeRepetition(QList& list,const QString& devName,const QTime& time) { for(const auto& it : list) { /* 先查设备名称是否重复 */ if(it->getDevName() == devName) { /* 名称相等再查时间是否重复 */ if(it->getExecTime() == time) { return true; } } } /* 所有设备都判断完了 */ return false; } /** * @brief 判断日期是否重复,这里会先将自身移除链表 * @param list * @param item * @return */ bool ExecPlan::judgeTimeRepetition(QList& list, ExecPlanItem* item) { /* 先将自身移除链表 */ list.removeOne(item); // SPDLOG_LOGGER_DEBUG(m_logger,"***** 列表中还有{}项",list.count()); for(const auto& it : list) { /* 先查设备名称是否重复 */ if(it->getDevName() == item->getDevName()) { /* 名称相等再查时间是否重复 */ if(it->getExecTime() == item->getExecTime()) { list.append(item); return true; } } } list.append(item); /* 所有设备都判断完了 */ return false; } /** * @brief ExecPlan::judgeTimeRepetition * @param list * @param item * @param time * @return */ bool ExecPlan::judgeTimeRepetition(QList& list, ExecPlanItem *item, const QTime &time) { /* 先将自身移除链表 */ list.removeOne(item); for(const auto& it : list) { /* 先查设备名称是否重复 */ if(it->getDevName() == item->getDevName()) { /* 名称相等再查时间是否重复 */ if(it->getExecTime() == time) { list.append(item); return true; } } } list.append(item); /* 所有设备都判断完了 */ return false; } /* 判断日期时间是否重复 */ bool ExecPlan::judgeDateTimeRepetition(QList &list, const QString &devName,const QDate& date,const QTime &time) { for(const auto& it : list) { if(it->getDevName() == devName) { if(it->getDate() == date) { if(it->getExecTime() == time) { return true; } } } } /* 没有相等的日期 */ return false; } /** * @brief 特殊日判断时间重复 * @param list * @param item * @param time * @return */ bool ExecPlan::judgeDateTimeRepetition(QList &list, ExecPlanItem *item, const QTime &time) { /* 先将自身移除链表 */ list.removeOne(item); for(const auto& it : list) { /* 先查设备名称是否重复 */ if(it->getDevName() == item->getDevName()) { /* 名称相等再查日期是否重复 */ if(it->getDate() == item->getDate()) { if(it->getExecTime() == time) { list.append(item); return true; } } } } list.append(item); /* 所有设备都判断完了 */ return false; } /** * @brief 这个重载是修改了日期后检查是否冲突 * @param list * @param item * @param date * @return */ bool ExecPlan::judgeDateTimeRepetition(QList &list, ExecPlanItem *item,const QDate& date) { /* 先将自身移除链表 */ list.removeOne(item); for(const auto& it : list) { /* 先查设备名称是否重复 */ if(it->getDevName() == item->getDevName()) { /* 名称相等再查日期是否重复 */ if(it->getDate() == date) { if(it->getExecTime() == item->getExecTime()) { list.append(item); return true; } } } } list.append(item); /* 所有设备都判断完了 */ return false; } /** * @brief 这个重载主要是修改了设备后检查是否冲突 * @param list * @param item * @return */ bool ExecPlan::judgeDateTimeRepetition(QList &list, ExecPlanItem *item) { /* 先将自身移除链表 */ list.removeOne(item); for(const auto& it : list) { /* 先查设备名称是否重复 */ if(it->getDevName() == item->getDevName()) { /* 名称相等再查日期是否重复 */ if(it->getDate() == item->getDate()) { if(it->getExecTime() == item->getExecTime()) { list.append(item); return true; } } } } list.append(item); /* 所有设备都判断完了 */ return false; } /* 获取默认计划 */ char ExecPlan::getDefaultPlan() { if(m_pBtnDefault->isChecked()) { return 1; } return 0; } /* 获取执行模式 */ char ExecPlan::getExecMode() { if(m_rBtnDoDay->isChecked()) { return 1; } return 0; } /* 获取计划容器 */ QVector *> &ExecPlan::vecItem() { return m_vecItem; } /* 获取stackWidget的指针 */ QStackedWidget *ExecPlan::stackWidget() { return m_stack; } QVector& ExecPlan::layout() { return m_vecLayout; } /* 刷新一周8天的页面 */ //void ExecPlan::RefreshUI() //{ // // /* 将当前页,按时间升序排序 */ // // qSort(m_vecItem[m_stack->currentIndex()]->begin(), // // m_vecItem[m_stack->currentIndex()]->end(), // // timeCompare); // /* 设置序号,刷新UI */ // int num1 = 0; // for(auto& it : m_vecItem) // { // num1 = 0; // for(auto& it1 : *it) // { // int y = num1*48; // it1->move(0,y); // num1++; // } // } //} /* 设置默认计划 */ void ExecPlan::setDefaultPlan(int num) { if(0 == num) { m_pBtnDefault->setChecked(false); }else { m_pBtnDefault->setChecked(true); } } /* 按时刻还是按天 */ void ExecPlan::setTimeOrDay(int num) { if(0 == num) { m_rBtnDoTime->setChecked(true); }else { m_rBtnDoDay->setChecked(true); } } /** * @brief 检查数据库中有没有这个表格,这里正常日和特殊日分开检查,二者的名称不相关 * 每个表格名称前面有“正常日-”和“特殊日-”区分,因此显示模板名称的时候需要去掉前缀 * @param tableName * @return */ bool ExecPlan::checkDataBaseTableName(const QString &tableName) { /* 取出数据库中表格的名称,根据当前是周几,选择性的插入到list中 */ QStringList tabList = m_DB.tables(); QStringList normalList; QStringList specialList; for(const auto& it : tabList) { /* 去掉前缀 */ QString name = it.mid(4,it.count() - 4); if(it.contains("正常日")) { normalList.append(name); } else if(it.contains("特殊日")) { specialList.append(name); } } int day = m_stack->currentIndex(); if(day < 7) { for(const auto& it : normalList) { if(it == tableName) { return true; } } return false; }else { for(const auto& it : specialList) { if(it == tableName) { return true; } } return false; } } /* 删除一页,num是周几 */ void ExecPlan::clearOnePage(int num) { /* 先检查时间选择器是否在运行 */ if(nullptr != m_timeEdit) { delete m_timeEdit; m_timeEdit = nullptr; } if(nullptr != m_dateEdit) { delete m_dateEdit; m_dateEdit = nullptr; } if(m_loop.isRunning()) { m_loop.quit(); } int count = m_vecItem[num]->count(); for(int i = 0;i < count; i++) { /* 根据序号删除 */ delete m_vecItem[num]->at(i); } /* 清空数组 */ m_vecItem[num]->clear(); } /* 当前页的项是否为空 */ bool ExecPlan::itemIsEmpty() { return m_vecItem[m_stack->currentIndex()]->isEmpty(); } /* 选择周几 */ void ExecPlan::do_selectDayOfWeeks() { QPushButton* pBtn = qobject_cast(sender()); /* 清除所有选中效果 */ for(int i = 0;i < 8;i++) { m_vecWeeks[i]->setProperty("Pressed",false); m_leftColumn->style()->unpolish(m_vecWeeks[i]); m_leftColumn->style()->polish(m_vecWeeks[i]); if(m_vecWeeks[i] == pBtn) { m_stack->setCurrentIndex(i); } } pBtn->setProperty("Pressed",true); this->style()->unpolish(pBtn); this->style()->polish(pBtn); } /* 修改了一个设备,主要是修改了名称,将这里的名字也修改掉 */ void ExecPlan::do_devChanged(const QString &previous, const QString &now) { SPDLOG_LOGGER_DEBUG(m_logger,"设备名由“{}”改为了“{}”",previous.toStdString(),now.toStdString()); for(auto& it : m_vecItem) { for(auto& it1 : *it) { if(it1->getDevName() == previous) { it1->setDevName(now); } } } } /* 删除了一个设备 */ void ExecPlan::do_devDelete(const QString& devName) { SPDLOG_LOGGER_DEBUG(m_logger,"删除了一个设备:{}",devName.toStdString()); for(auto& it : m_vecItem) { /* 特别注意,删除特定的list中的内容只能使用传统的for循环,而且i++也要根据情况判断再++, * 如果删除了i位置的一个项,i+1位置的项就会来到i位置,因此这个时候不能再++ */ for(int i = 0;i < it->count();) { auto it1 = it->at(i); if(it1->getDevName() == devName) { it1->setParent(nullptr); delete it1; it->removeOne(it1); }else { i++; } } } /* 刷新设备可选项,重新设置可以选择的设备名 */ for(auto& it : m_vecItem) { for(auto& it1 : *it) { it1->setDevName(it1->getDevName()); } } SortAndRefreshUI(); } /* 从EQM获取计划数据 */ void ExecPlan::do_pBtnGetEQMData() { /* 先判断设备是否连接 */ if(!GlobalInfo.getConnectState()) { Warning w(this); w.setTextWithOneButton("设备未连接!"); /* 创建遮罩 */ std::shared_ptr mask = std::make_shared(); mask->SetMainWidget(m_mask); /* 设置主窗口(被遮盖的窗口) */ mask->SetTrigWidget(&w); /* 设置触发的窗口 */ mask->SetOpacity(float(0.4)); /* 设置透明度 */ w.exec(); return; } /* 判断是否连接上了EQM数据库 */ if(!GlobalInfo.isUsingEQM()) { Warning w(this); w.setTextWithOneButton("未使用EQM数据库!"); /* 创建遮罩 */ std::shared_ptr mask = std::make_shared(); mask->SetMainWidget(m_mask); /* 设置主窗口(被遮盖的窗口) */ mask->SetTrigWidget(&w); /* 设置触发的窗口 */ mask->SetOpacity(float(0.4)); /* 设置透明度 */ w.exec(); return; } QList listInfo; GlobalInfo.toEQM.getExecPlanData(listInfo); /* 清空所有的计划 */ for(auto& it : m_vecItem) { for(auto& it1 : *it) { delete it1; } it->clear(); } /* 更新计划列表 */ EQMToHost(listInfo); } /* 点击添加时段按钮 */ void ExecPlan::do_pBtnAddExecPlan() { /* 创建页面,判断是正常日还是特殊日 */ if(m_stack->currentIndex() < 7) { std::shared_ptr atf = std::make_shared(this); int x = (m_mainUI->width() - atf->width())/2 + m_mainUI->x(); int y = (m_mainUI->height() - atf->height())/2 + m_mainUI->y() + 24; atf->setGeometry(x,y,atf->width(),atf->height()); connect(atf.get(),SIGNAL(signal_addNormalItem(QString,QString,QTime)),this,SLOT(do_addNormalOneItem(QString,QString,QTime))); atf->exec(); atf->setAttribute(Qt::WA_DeleteOnClose,true); } else /* 特殊日 */ { std::shared_ptr ast = std::make_shared(this); int x = (m_mainUI->width() - ast->width())/2 + m_mainUI->x(); int y = (m_mainUI->height() - ast->height())/2 + m_mainUI->y(); ast->setGeometry(x,y,ast->width(),ast->height()); connect(ast.get(),SIGNAL(signal_AddSpecialItem(QString,QString,QDate,QTime)),this,SLOT(do_addSpecialOneItem(QString,QString,QDate,QTime))); ast->exec(); // SPDLOG_LOGGER_DEBUG(m_logger,"特殊日添加了一个项,页面关闭了"); ast->setAttribute(Qt::WA_DeleteOnClose,true); } } /** * @brief 新增一条项,接收新增页面发送过来的信号 * @param dev * @param action * @param time */ void ExecPlan::do_addNormalOneItem(QString dev,QString action,QTime time) { SPDLOG_LOGGER_INFO(m_logger,"执行计划:普通日添加了一项"); /* 获取是周几 */ int num = m_stack->currentIndex(); ExecPlanItem* one = new ExecPlanItem(num); // SPDLOG_LOGGER_INFO(m_logger,"devName:{}",dev.toStdString()); one->setDevName(dev); one->setActionName(action); one->setExecTime(time); /* 连接删除项信号,执行时间改变信号 */ connect(one,SIGNAL(signal_OneItemDelete(int)),this,SLOT(do_deleteOneItem(int))); connect(one,SIGNAL(signal_execTimeClicked(QTime)),this,SLOT(do_editExecTime(QTime))); connect(one,SIGNAL(signal_devChanged()),this,SLOT(do_editDev())); one->show(); m_vecLayout[num]->addWidget(one); /* 添加到布局 */ m_vecItem[num]->push_back(one); /* 根据时间排序并重新显示 */ SortAndRefreshUI(); } /* 新增一条特殊日期项 */ void ExecPlan::do_addSpecialOneItem(QString dev, QString action, QDate date, QTime time) { SPDLOG_LOGGER_INFO(m_logger,"执行计划:特殊日添加了一项"); /* 获取是周几 */ int num = m_stack->currentIndex(); ExecPlanItem* one = new ExecPlanItem(num); one->setDevName(dev); one->setActionName(action); one->setDate(date); one->setExecTime(time); /* 连接删除项信号,执行时间改变信号 */ connect(one,SIGNAL(signal_OneItemDelete(int)),this,SLOT(do_deleteOneItem(int))); connect(one,SIGNAL(signal_execTimeClicked(QTime)),this,SLOT(do_editExecTime(QTime))); connect(one,SIGNAL(signal_devChanged()),this,SLOT(do_editDev())); connect(one,SIGNAL(signal_dateClicked(QDate)),this,SLOT(do_editDate(QDate))); one->show(); m_vecLayout[num]->addWidget(one); /* 添加到布局 */ m_vecItem[num]->push_back(one); /* 根据时间排序并重新显示 */ SortAndRefreshUI(); } /* 下载按钮 */ void ExecPlan::do_download() { /* 先检查计划是否是空的,不需要检查 */ // bool isEmpty = true; // for(const auto& it : m_vecItem) // { // if(!it->isEmpty()) // { // isEmpty = false; // } // } // if(isEmpty) // { // Warning w(this); // w.setTextWithOneButton("至少设置一个计划内容!"); // w.exec(); // return; // } QByteArray ba; PacketRS::AnalyzeExecPlan aep; aep.HostToDev(m_vecItem, ba, this); QList* listInfo = new QList; HostToEQMJson(m_vecItem, *listInfo); /* 发送给设备 */ OneEvent* oe = new OneEvent(CustomEventType::event_sendExecPlan); oe->setData(ba); QApplication::postEvent(DevC,oe); /* 发送给EQM数据库 */ // OneEvent* oe1 = new OneEvent(CustomEventType::event_sendToEQM); // auto p = static_cast(listInfo); // oe1->setData(QVariant::fromValue(p)); // QApplication::postEvent(DevC,oe1); if(GlobalInfo.toEQM.insertData(*listInfo)) { SPDLOG_LOGGER_INFO(m_logger,"插入EQM数据库成功"); OneEvent* oe1 = new OneEvent(CustomEventType::event_Echo); oe1->setData("计划写入EQM数据库成功"); QApplication::postEvent(g_uiObject, oe1); } delete listInfo; } /* 清空计划 */ void ExecPlan::do_clearExecPlan() { SPDLOG_LOGGER_DEBUG(m_logger,"清空了当前页的执行计划"); /* 清空当前页 */ // for(const auto& it : *m_vecItem[m_stack->currentIndex()]) // { // delete it; // } // m_vecItem[m_stack->currentIndex()]->clear(); clearOnePage(m_stack->currentIndex()); } /* 保存模版 */ void ExecPlan::do_saveTemplate() { std::shared_ptr stt = std::make_shared(PageType::PageExecPlan,this); int x = (m_mainUI->width() - stt->width())/2 + m_mainUI->x(); int y = (m_mainUI->height() - stt->height())/2 + m_mainUI->y(); stt->setGeometry(x,y,stt->width(),stt->height()); connect(stt.get(),SIGNAL(signal_templateName(QString)),this,SLOT(do_saveTemplateToSQL(QString))); /* 创建遮罩 */ std::shared_ptr mask = std::make_shared(); mask->SetMainWidget(m_mask); /* 设置主窗口(被遮盖的窗口) */ mask->SetTrigWidget(stt.get()); /* 设置触发的窗口 */ mask->SetOpacity(float(0.4)); stt->exec(); } /* 导入模板按钮 */ void ExecPlan::do_importTemplate() { /* 取出数据库中表格的名称,根据当前是周几,选择性显示 */ QStringList tabList = m_DB.tables(); QStringList normalList; QStringList specialList; for(const auto& it : tabList) { /* 去掉前缀 */ QString name = it.mid(4,it.count() - 4); if(it.contains("正常日")) { normalList.append(name); } else if(it.contains("特殊日")) { specialList.append(name); } } int day = m_stack->currentIndex(); std::shared_ptr itl = std::make_shared(day < 7 ? normalList : specialList , this); int x = (m_mainUI->width() - itl->width())/2 + m_mainUI->x(); int y = (m_mainUI->height() - itl->height())/2 + m_mainUI->y(); itl->setGeometry(x,y,itl->width(),itl->height()); connect(itl.get(),SIGNAL(signal_templateName(QString)),this,SLOT(do_importTemplateFromSQL(QString))); connect(itl.get(),SIGNAL(signal_deleteTemplate(QString)),this,SLOT(do_deleteTemplateFromSQL(QString))); /* 创建遮罩 */ std::shared_ptr mask = std::make_shared(); mask->SetMainWidget(m_mask); /* 设置主窗口(被遮盖的窗口) */ mask->SetTrigWidget(itl.get()); /* 设置触发的窗口 */ mask->SetOpacity(float(0.4)); itl->exec(); } /* 将数据保存到数据库中 */ void ExecPlan::do_saveTemplateToSQL(QString name) { SPDLOG_LOGGER_INFO(m_logger,"开始保存数据到数据库:{}",name.toStdString()); if(!m_DB.isValid()) { SPDLOG_LOGGER_INFO(m_logger,"数据库未打开"); return; } /* 创建一个表格 */ QSqlQuery query(m_DB); /** * 表格保存一周8天的所有项,使用weekDay表示周几,1-7是周一到周日,8是特殊日 * 在这里添加模版名称前缀 */ int weekDay = m_stack->currentIndex(); if(weekDay < 7) { name.insert(0,"正常日-"); }else { name.insert(0,"特殊日-"); } QString createTable = QString("CREATE TABLE `%1` (" "`weekDay` INT," "`num` INT," "`devName` VARCHAR(20)," "`devType` INT," "`date` DATE," "`ExecTime` TIME," "`Action` VARCHAR(20))").arg(name); if(query.exec(createTable)) { SPDLOG_LOGGER_INFO(m_logger,"创建成功"); }else { SPDLOG_LOGGER_INFO(m_logger,"创建表格失败:{}",query.lastError().text().toStdString()); } /* 将数据存储到表格中 */ QString insertData = QString("INSERT INTO `%1` (`weekDay`,`num`,`devName`,`devType`,`date`,`ExecTime`,`Action`)" "VALUES (:weekDay,:num,:devName,:devType,:date,:ExecTime,:Action)").arg(name); query.prepare(insertData); int cfgNum = DevInfo.cfgDevInfo().count(); for(auto& it : *m_vecItem[weekDay]) { query.bindValue(":weekDay",weekDay); query.bindValue(":num",it->getNum()); query.bindValue(":devName",it->getDevName()); /* 这里设置为0主要是为了防止没有设置设备,保存模板时会导致程序崩溃 */ query.bindValue(":devType",(cfgNum == 0 ? 0 : it->getCfgDev()->DevType.getDevTypeIDToInt())); query.bindValue(":date",it->getDate().toString("yyyy-MM-dd")); query.bindValue(":ExecTime",it->getExecTime().toString("hh:mm:ss")); query.bindValue(":Action",it->getActionName()); if(!query.exec()) { SPDLOG_LOGGER_INFO(m_logger,"数据插入失败:{}",query.lastError().text().toStdString()); } } /* 弱提示,保存成功 */ TipWidget::display(TipWidget::OPERATOR_OK,"保存模板成功!",m_mainUI); } /* 导入模板 */ void ExecPlan::do_importTemplateFromSQL(QString name) { SPDLOG_LOGGER_DEBUG(m_logger,"选择的模版:{}",name.toStdString()); /* 当前是周几 */ int weekDay = m_stack->currentIndex(); /* 清空内容 */ for(auto& it1 : *m_vecItem[weekDay]) { delete it1; } m_vecItem[weekDay]->clear(); /* 给名称添加前缀 */ if(weekDay < 7) { name.insert(0,"正常日-"); }else { name.insert(0,"特殊日-"); } QSqlQuery query(m_DB); QString sqliteCmd = QString("SELECT * FROM `%1`").arg(name); if(!query.exec(sqliteCmd)) { SPDLOG_LOGGER_INFO(m_logger,"读取表格失败:{}",query.lastError().text().toStdString()); } while(query.next()) { QSqlRecord rec = query.record(); int weekDay = rec.value("weekDay").toInt(); if(weekDay < 7) { /* 将weekDay换成真正的周几,前面的if只是判断是不是正常日 */ weekDay = m_stack->currentIndex(); ExecPlanItem* item = new ExecPlanItem(weekDay, m_stack->widget(weekDay)); item->setNum(rec.value("num").toInt()); QString devName = rec.value("devName").toString(); item->setDevName(devName); QTime time = QTime::fromString(rec.value("ExecTime").toString()); item->setExecTime(time); item->setActionName(rec.value("Action").toString()); // SPDLOG_LOGGER_DEBUG(m_logger,"Action:{}",rec.value("Action").toString().toStdString()); QApplication::connect(item,SIGNAL(signal_OneItemDelete(int)),this,SLOT(do_deleteOneItem(int))); QApplication::connect(item,SIGNAL(signal_execTimeClicked(QTime)),this,SLOT(do_editExecTime(QTime))); QApplication::connect(item,SIGNAL(signal_devChanged()),this,SLOT(do_editDev())); m_vecLayout[weekDay]->addWidget(item); m_vecItem[weekDay]->push_back(item); } else { weekDay = m_stack->currentIndex(); ExecPlanItem* item = new ExecPlanItem(weekDay, m_stack->widget(weekDay)); item->setNum(rec.value("num").toInt()); item->setDevName(rec.value("devName").toString()); QDate date = QDate::fromString(rec.value("date").toString(),"yyyy-MM-dd"); item->setDate(date); QTime time = QTime::fromString(rec.value("ExecTime").toString()); item->setExecTime(time); item->setActionName(rec.value("Action").toString()); QApplication::connect(item,SIGNAL(signal_OneItemDelete(int)),this,SLOT(do_deleteOneItem(int))); QApplication::connect(item,SIGNAL(signal_execTimeClicked(QTime)),this,SLOT(do_editExecTime(QTime))); QApplication::connect(item,SIGNAL(signal_devChanged()),this,SLOT(do_editDev())); QApplication::connect(item,SIGNAL(signal_dateClicked(QDate)),this,SLOT(do_editDate(QDate))); m_vecLayout[weekDay]->addWidget(item); m_vecItem[weekDay]->push_back(item); } } /* 刷新UI */ SortAndRefreshUI(); /* 弱提示,导入成功 */ TipWidget::display(TipWidget::OPERATOR_OK,"导入模版成功!",m_mainUI); } void ExecPlan::do_deleteTemplateFromSQL(QString name) { QSqlQuery query(m_DB); /* 给名称添加前缀 */ int weekDay = m_stack->currentIndex(); if(weekDay < 7) { name.insert(0,"正常日-"); }else { name.insert(0,"特殊日-"); } QString cmd = QString("DROP TABLE `%1`").arg(name); if(query.exec(cmd)) { SPDLOG_LOGGER_INFO(m_logger,"删除模版 {} 成功",name.toStdString()); /* 弱提示,删除成功 */ TipWidget::display(TipWidget::OPERATOR_OK,"删除模版成功!",m_mainUI); }else { SPDLOG_LOGGER_INFO(m_logger,"删除模版失败,error:",query.lastError().text().toStdString()); /* 弱提示,删除失败 */ TipWidget::display(TipWidget::OPERATOR_FAIL,"删除模板失败!",m_mainUI); } } /* 删除一个项 */ void ExecPlan::do_deleteOneItem(int num) { /* 先检查时间选择器是否在运行 */ if(nullptr != m_timeEdit) { delete m_timeEdit; m_timeEdit = nullptr; } if(nullptr != m_dateEdit) { delete m_dateEdit; m_dateEdit = nullptr; } if(m_loop.isRunning()) { m_loop.quit(); } /* 根据序号删除 */ delete m_vecItem[m_stack->currentIndex()]->at(num-1); m_vecItem[m_stack->currentIndex()]->removeAt(num-1); /* 重新排序 */ SortAndRefreshUI(); } /** * @brief 修改执行时间,在增加项的地方连接信号 * @param t 当前现实的时间 */ void ExecPlan::do_editExecTime(QTime t) { if(m_dateEdit != nullptr) { delete m_dateEdit; m_dateEdit = nullptr; } if(m_timeEdit != nullptr) { delete m_timeEdit; m_timeEdit = nullptr; } if(m_loop.isRunning()) { m_loop.quit(); } SPDLOG_LOGGER_DEBUG(m_logger,"修改执行时间"); auto s = dynamic_cast(sender()); s->hideWarn(); m_timeEdit = new TimeWidget(this,TimeWidget::Dialog); /* 覆盖住选择框,需要判断是否是特殊日 */ QPoint p2 = mapToParent(s->pos()); int x = 0; int y = 0; if(m_stack->currentIndex() < 7) { /* 这里的-2是时间选择框比item的框大4,所以可以将其覆盖住 */ x = p2.x() + 534 - 2; }else { x = p2.x() + 682 -2; } /* p2是结束时间框,70是当前页面距离ExecPlan顶部的距离,最后一个是滚动条滚动的距离 */ y = p2.y() + 116 - 2 - m_vecScrollArea[m_stack->currentIndex()]->scrollBarValue(); m_timeEdit->move(x,y); /* 设置样式表 */ // m_timeEdit->setStyleSheet(R"(background: transparent; // border-radius: 4px; // padding-left:12px; // border: 1px solid #E6E9F4;)"); /* 设置当前显示的时间 */ m_timeEdit->setTime(t); /* 选择结束后的信号和槽 */ connect(m_timeEdit,&TimeWidget::signal_nowTime,this,[&](QTime t1){ if(s->getDateType() == DateType::NormalDate) { /* 进行时间重复检测 */ if(judgeTimeRepetition(*m_vecItem[m_stack->currentIndex()],s,t1)) { s->setWarningText("时间冲突"); delete m_timeEdit; m_timeEdit = nullptr; m_loop.quit(); return; } s->setExecTime(t1); }else { if(judgeDateTimeRepetition(*m_vecItem[m_stack->currentIndex()],s,t1)) { s->setWarningText("时间冲突"); delete m_timeEdit; m_timeEdit = nullptr; m_loop.quit(); return; } s->setExecTime(t1); } s->hideWarn(); /* 重新排序并刷新时间 */ SortAndRefreshUI(); m_loop.quit(); }); m_timeEdit->showTimeEditArea(); m_loop.exec(); delete m_timeEdit; m_timeEdit = nullptr; } /* 修改日期 */ void ExecPlan::do_editDate(QDate d) { if(m_timeEdit != nullptr) { delete m_timeEdit; m_timeEdit = nullptr; } if(m_dateEdit != nullptr) { delete m_dateEdit; m_dateEdit = nullptr; } if(m_loop.isRunning()) { m_loop.quit(); } auto s = dynamic_cast(sender()); s->hideWarn(); m_dateEdit = new CDate(d,this); /* 移动组件位置,需要判断是否是特殊日 */ QPoint p2 = mapToParent(s->pos()); int x = 0; int y = 0; /* 已经滚动上去的距离 */ int scrValue = m_vecScrollArea[m_stack->currentIndex()]->scrollBarValue(); /* 这里的-2是时间选择框比item的框大4,所以可以将其覆盖住 */ x = p2.x() + 520; /* p2是结束时间框,102是当前页面距离Broadcast顶部的距离,最后一个是滚动条滚动的距离 */ y = p2.y() + 140 - scrValue; /* 240是当前页面的前六条坐标,日历可以正常显示,后面三条就得设置向上显示了 */ if(p2.y() - scrValue > 260) { /* 整体向上抬日立的高度和date窗口的高度 */ y = y - m_dateEdit->height() - 16; } m_dateEdit->move(x,y); /* 选择结束后的信号和槽 */ connect(m_dateEdit,&CDate::signal_DateChanged,[&](QDate d1){ if(s->getDateType() == DateType::SpecialDate) { /* 进行时间重复检测 */ if(judgeDateTimeRepetition(*m_vecItem[m_stack->currentIndex()],s,d1)) { s->setWarningText("时间重复"); return; } s->setDate(d1); } s->hideWarn(); /* 重新排序并刷新时间 */ SortAndRefreshUI(); m_loop.quit(); }); m_dateEdit->show(); m_loop.exec(); delete m_dateEdit; m_dateEdit = nullptr; } /* 修改了设备 */ void ExecPlan::do_editDev() { auto s = qobject_cast(sender()); /* 判断特殊日还是正常日 */ if(s->getDateType() == DateType::NormalDate) { if(judgeTimeRepetition(*m_vecItem[m_stack->currentIndex()],s)) { s->setWarningText("设备动作时间重复",0); return; } }else { if(judgeDateTimeRepetition(*m_vecItem[m_stack->currentIndex()],s)) { s->setWarningText("设备动作时间重复",0); return; } } s->hideWarn(); /* 重新排序 */ SortAndRefreshUI(); } /* 配置完成的设备改变了 */ void ExecPlan::do_cfgDevChanged() { for(const auto& it1 : m_vecItem) { for(const auto& it2 : *it1) { it2->setDevName(it2->getDevName()); } } } /* 绘图事件 */ void ExecPlan::paintEvent(QPaintEvent *event) { /* 绘制外边框 */ QPainter painter(this); QPen pen; pen.setColor(QColor(218, 224, 242)); pen.setWidth(1); painter.setPen(pen); painter.drawRect(24,70,1824,539); } bool ExecPlan::eventFilter(QObject *watched, QEvent *event) { /* 判断是哪个控件 */ if(watched == m_labelTip) { if(event->type() == QEvent::Enter) { m_TipText->show(); return true; } else if(event->type() == QEvent::Leave) { m_TipText->hide(); } } return QWidget::eventFilter(watched,event); } /* 根据时间排序,并刷新UI */ void ExecPlan::SortAndRefreshUI() { /* 将当前页,按时间升序排序 */ std::sort(m_vecItem[m_stack->currentIndex()]->begin(), m_vecItem[m_stack->currentIndex()]->end(), [&](ExecPlanItem* t1,ExecPlanItem* t2) { /* 按照日期排序,再按照名称排序 */ if(t1->getDate() < t2->getDate()) { return true; } else if(t1->getDate() > t2->getDate()) { return false; } else { if(t1->getExecTime() < t2->getExecTime()) { return true; } else if(t1->getExecTime() > t2->getExecTime()) { return false; }else { return t1->getDevName() < t2->getDevName(); } } }); int index = m_stack->currentIndex(); /* 设置序号 */ int num1 = 1; for(auto& it : *m_vecItem[index]) { it->setNum(num1); num1++; } /* 刷新UI,先清空layout中的所有控件,就是将item的父指针设置为0 */ num1 = 0; for(auto& it : *m_vecItem[index]) { it->setParent(nullptr); } /* 将item重新加入到layout中 */ for(auto& it : *m_vecItem[index]) { m_vecLayout[index]->addWidget(it); } } /* 根据时间排序,并刷新UI */ void ExecPlan::SortAndRefreshUI(int index) { if(index > 7) { return; } /* 将当前页,按时间升序排序 */ std::sort(m_vecItem[index]->begin(), m_vecItem[index]->end(), [&](ExecPlanItem* t1,ExecPlanItem* t2) { /* 按照日期排序,再按照名称排序 */ if(t1->getDate() < t2->getDate()) { return true; } else if(t1->getDate() > t2->getDate()) { return false; } else { if(t1->getExecTime() < t2->getExecTime()) { return true; } else if(t1->getExecTime() > t2->getExecTime()) { return false; }else { return t1->getDevName() < t2->getDevName(); } } }); /* 设置序号 */ int num1 = 1; for(auto& it : *m_vecItem[index]) { it->setNum(num1); num1++; } /* 刷新UI,先清空layout中的所有控件,就是将item的父指针设置为0 */ num1 = 0; for(auto& it : *m_vecItem[index]) { it->setParent(nullptr); } /* 将item重新加入到layout中 */ for(auto& it : *m_vecItem[index]) { m_vecLayout[index]->addWidget(it); } } void ExecPlan::createDataBase() { /* 连接数据库 */ QString dataName = GlobalInfo.ExecPath() + GlobalInfo.DataBasePath + "ExecPlan.db"; /* 第二个参数ExecPlan应该是数据库在Qt中的名字? */ m_DB = QSqlDatabase::addDatabase("QSQLITE","ExecPlan"); m_DB.setDatabaseName(dataName); if(!m_DB.open()) { SPDLOG_LOGGER_INFO(m_logger,"{}打开失败:{}",dataName.toStdString(),m_DB.lastError().text().toStdString()); return; } } /* 本地配置转换成发送的结构体 */ void ExecPlan::HostToEQMJson(QVector*>& cfgVec, QList& listInfo) { for(const auto& it : cfgVec) { for(const auto& it1 : *it) { ExecPlanItemInfo info; info.ExecType = getExecMode(); info.WeekDay = it1->getWeekDay() + 1; /* 转换成1-7表示周1-周日 */ info.date = it1->getDate(); info.execTime = it1->getExecTime(); info.devName = it1->getDevName(); info.actionID = it1->getActionNum(); info.actionName = it1->getActionName(); // info.dateType = it1->getDateType(); info.cfgDev = it1->getCfgDev(); listInfo.append(info); } } } /** * @brief 添加从EQM获取到的数据 * * @param listInfo */ void ExecPlan::EQMToHost(QList& listInfo) { for(auto& it : listInfo) { ExecPlanItem* item = nullptr; if(it.WeekDay < 7) { item = new ExecPlanItem(it.WeekDay, this); }else { item = new ExecPlanItem(it.WeekDay, this); } item->setDate(it.date); item->setExecTime(it.execTime); item->setDevName(it.devName); item->setActionName(it.actionName); item->setActionNum(it.actionID); connect(item,SIGNAL(signal_OneItemDelete(int)),this,SLOT(do_deleteOneItem(int))); connect(item,SIGNAL(signal_execTimeClicked(QTime)),this,SLOT(do_editExecTime(QTime))); connect(item,SIGNAL(signal_devChanged()),this,SLOT(do_editDev())); connect(item,SIGNAL(signal_dateClicked(QDate)),this,SLOT(do_editDate(QDate))); m_vecLayout[it.WeekDay]->addWidget(item); m_vecItem[it.WeekDay]->push_back(item); } /* 排序并添加序号 */ for(int i = 0;i < 8;i++) { SortAndRefreshUI(i); } OneEvent* oe = new OneEvent(CustomEventType::event_Echo); oe->setData("获取EQM执行计划成功"); QApplication::postEvent(g_uiObject, oe); }