checkperiodwidget.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #include "checkperiodwidget.h"
  2. #include "GlobalVariable.h"
  3. #include "checkperiodfunc.h"
  4. #include "onedetectplan.h"
  5. #include "ui_checkperiodwidget.h"
  6. #include "addperioddialog.h"
  7. #include "UIStyleManager.h"
  8. #include "customcombobox.h"
  9. #include <QFile>
  10. #include <QListWIdgetItem>
  11. #include <algorithm>
  12. #include <cmath>
  13. #include <qboxlayout.h>
  14. #include "checkperiodfunc.h"
  15. #include "tipwidget.h"
  16. #include "GlobalInfo.h"
  17. #include "timewidget.h"
  18. CheckPeriodWidget::CheckPeriodWidget(QWidget *parent) :
  19. QWidget(parent),
  20. ui(new Ui::CheckPeriodWidget)
  21. {
  22. ui->setupUi(this);
  23. m_logger = spdlog::get("ACASetting");
  24. if(m_logger == nullptr)
  25. {
  26. fmt::print("CheckPeriodWidget: Logger ACASetting not found\n");
  27. return;
  28. }
  29. /* 下拉框设置阴影 */
  30. ui->comboBox_selectCompareItem->setViewShadowEffect();
  31. /* 初始化检测计划容器 */
  32. m_layoutDetectPlans = qobject_cast<QVBoxLayout*>(ui->scrollArea_detectPlans->layout());
  33. connect(ui->pBtn_addDetectPlan, &QPushButton::clicked, this, &CheckPeriodWidget::do_pBtn_addDetectPlan_clicked);
  34. connect(ui->pBtn_addNoDetectPlan, &QPushButton::clicked, this, &CheckPeriodWidget::do_pBtn_addNoDetectPlan_clicked);
  35. connect(ui->comboBox_selectCompareItem, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CheckPeriodWidget::do_comboBox_selectCompareItem_currentIndexChanged);
  36. /* 设置UI */
  37. UIStyle.registerWidget(this);
  38. QString qssPath = UIStyle.getQSSPath() + "/onedetectplan.qss";
  39. QFile file(qssPath);
  40. if(file.open(QFile::ReadOnly))
  41. {
  42. m_qssPlan = file.readAll();
  43. file.close();
  44. } else
  45. {
  46. SPDLOG_LOGGER_WARN(m_logger, "打开QSS文件失败: {}", qssPath.toStdString());
  47. }
  48. /* 初始化列表 */
  49. initListWidget();
  50. }
  51. CheckPeriodWidget::~CheckPeriodWidget()
  52. {
  53. UIStyle.unregisterWidget(this);
  54. delete ui;
  55. }
  56. /* 更新可选的对比项列表 */
  57. void CheckPeriodWidget::updateCompareItemList(const QList<CompareItemInfo_t>& compareItemList)
  58. {
  59. /* 先获取当前选择的列表项 */
  60. int id = ui->comboBox_selectCompareItem->currentData().value<int>();
  61. ui->comboBox_selectCompareItem->clear();
  62. m_pListcurrDetect = nullptr;
  63. /* 屏蔽comboBox信号 */
  64. ui->comboBox_selectCompareItem->blockSignals(true);
  65. for(const auto& item : compareItemList)
  66. {
  67. /* 添加到下拉框 */
  68. ui->comboBox_selectCompareItem->addItem(item.strName, QVariant::fromValue(item.nID));
  69. }
  70. /* 设置当前选择的对比项 */
  71. if(id != 0)
  72. {
  73. /* 屏蔽comboBox信号 */
  74. ui->comboBox_selectCompareItem->blockSignals(true);
  75. for(int i = 0; i < ui->comboBox_selectCompareItem->count(); ++i)
  76. {
  77. if(ui->comboBox_selectCompareItem->itemData(i).value<int>() == id)
  78. {
  79. ui->comboBox_selectCompareItem->setCurrentIndex(i);
  80. break;
  81. }
  82. }
  83. } else
  84. {
  85. ui->comboBox_selectCompareItem->setCurrentIndex(0);
  86. }
  87. /* 恢复comboBox信号 */
  88. ui->comboBox_selectCompareItem->blockSignals(false);
  89. /* 手动切换当前的列表 */
  90. do_comboBox_selectCompareItem_currentIndexChanged(ui->comboBox_selectCompareItem->currentIndex());
  91. }
  92. /* 设置计划列表 */
  93. void CheckPeriodWidget::setDetectPlanList(const QList<OnePlan_t>& planList)
  94. {
  95. m_currentPlanList = planList;
  96. removeAllDetectPlanWidgets();
  97. for(const auto& plan : m_currentPlanList)
  98. {
  99. addDetectPlan(plan);
  100. }
  101. }
  102. /* 选择了一个对比项 */
  103. void CheckPeriodWidget::do_comboBox_selectCompareItem_currentIndexChanged(int index)
  104. {
  105. /* 获取当前选择的对比项id */
  106. int id = ui->comboBox_selectCompareItem->currentData().value<int>();
  107. if(id == 0)
  108. {
  109. m_pListcurrDetect = nullptr;
  110. SPDLOG_LOGGER_WARN(m_logger, "对比项ID为0,无法获取检测计划列表");
  111. return;
  112. }
  113. /* 如果已经有了,就不需要重新创建 */
  114. if(m_mapDetectPlanList.contains(id))
  115. {
  116. m_pListcurrDetect = m_mapDetectPlanList.value(id);
  117. }else
  118. {
  119. /* 创建一个新的列表 */
  120. m_pListcurrDetect = new QList<OneDetectPlan*>();
  121. m_mapDetectPlanList.insert(id, m_pListcurrDetect);
  122. }
  123. /* 清空当前的布局 */
  124. removeAllDetectPlanWidgets();
  125. addDetectPlanToLayout();
  126. }
  127. /* 添加一个检测计划 */
  128. void CheckPeriodWidget::do_pBtn_addDetectPlan_clicked()
  129. {
  130. /* 检查当前有没有对比项选择 */
  131. int id = ui->comboBox_selectCompareItem->currentData().value<int>();
  132. if(id <= 0)
  133. {
  134. TipWidget::display(TipWidget::OPERATOR_WARN, "请先选择一个对比项", GInfo.getTopWindow());
  135. SPDLOG_LOGGER_WARN(m_logger, "没有选择对比项,无法添加检测计划");
  136. return;
  137. }
  138. AddPeriodDialog dlg(PERIOD_WEEK);
  139. /* 更新计划列表 */
  140. updateDetectPlanList(1);
  141. /* 设置计划列表 */
  142. dlg.setPlanList(m_currentPlanList);
  143. dlg.exec();
  144. if(!dlg.isOK())
  145. {
  146. return;
  147. }
  148. OnePlan_t plan = dlg.getPlan();
  149. addDetectPlan(plan);
  150. }
  151. /* 添加一个不检测计划 */
  152. void CheckPeriodWidget::do_pBtn_addNoDetectPlan_clicked()
  153. {
  154. /* 检查当前有没有对比项选择 */
  155. int id = ui->comboBox_selectCompareItem->currentData().value<int>();
  156. // if(id <= 0)
  157. // {
  158. // TipWidget::display(TipWidget::OPERATOR_WARN, "请先选择一个对比项", GInfo.getTopWindow());
  159. // SPDLOG_LOGGER_WARN(m_logger, "没有选择对比项,无法添加检测计划");
  160. // return;
  161. // }
  162. AddPeriodDialog dlg(PERIOD_DATE);
  163. dlg.exec();
  164. }
  165. /* 删除一个检测计划 */
  166. void CheckPeriodWidget::do_pBtn_deleteDetectPlan_clicked()
  167. {
  168. /* 获取信号发送者 */
  169. OneDetectPlan *pDetect = qobject_cast<OneDetectPlan*>(sender());
  170. if(pDetect == nullptr)
  171. {
  172. return;
  173. }
  174. m_layoutDetectPlans->removeWidget(pDetect);
  175. m_pListcurrDetect->removeAll(pDetect);
  176. delete pDetect;
  177. /* 重新排序 */
  178. // sortDetectPlanList();
  179. }
  180. /* 删除一个不检测计划 */
  181. void CheckPeriodWidget::do_pBtn_deleteNoDetectPlan_clicked()
  182. {
  183. }
  184. /* 修改了日期或周几,检测是否冲突 */
  185. void CheckPeriodWidget::do_detectPlanModifiedWeek(OnePlan_t formerPlan, OnePlan_t newPlan)
  186. {
  187. OneDetectPlan *pDetect = qobject_cast<OneDetectPlan*>(sender());
  188. /* 更新计划 */
  189. updateDetectPlanList(1);
  190. /* 检测是否冲突 */
  191. if(isWeekPlanDuplicate(m_currentPlanList, newPlan, newPlan))
  192. {
  193. /* 弹出提示 */
  194. TipWidget::display(TipWidget::OPERATOR_WARN, "与已有计划冲突,请重新修改", GInfo.getTopWindow());
  195. SPDLOG_LOGGER_WARN(m_logger, "检测计划冲突");
  196. /* 恢复原计划 */
  197. pDetect->setPlan(formerPlan);
  198. return;
  199. }
  200. /* 重新排序 */
  201. sortDetectPlanList();
  202. }
  203. /* 点击了检测计划的时间按钮,在这里修改时间 */
  204. void CheckPeriodWidget::do_detectPlanModifiedTime(QPoint pBtnSize, bool isStartTime)
  205. {
  206. /* 获取信号发送者 */
  207. auto one = qobject_cast<OneDetectPlan*>(sender());
  208. OnePlan_t plan = one->getPlan();
  209. /* 创建时间选择控件 */
  210. std::shared_ptr<TimeWidget> tw = std::make_shared<TimeWidget>(this, TimeWidget::ShowType::Dialog);
  211. /* 设置样式表 */
  212. tw->setStyleSheet(m_qssPlan);
  213. /* 设置图标 */
  214. tw->setIcon(":/icon/time.png");
  215. tw->setIconShow(true);
  216. tw->setIconSize(16, 16);
  217. /* 重新设置大小 */
  218. tw->setEditLine(112, 32);
  219. /* 设置选择框大小 */
  220. tw->setTimeAreaWidth(140);
  221. /* 移动位置,覆盖显示时间的按钮,获取的坐标是相对于Dialog的位置 */
  222. auto pos = this->mapFromGlobal(pBtnSize);
  223. // pos.setX(pos.x() - 1); /* 去掉阴影的宽度 */
  224. // pos.setY(pos.y()); /* 去掉阴影的高度 */
  225. tw->move(pos);
  226. // SPDLOG_LOGGER_DEBUG(m_logger, "移动前位置: {}, {}", pBtnSize.x(), pBtnSize.y());
  227. // SPDLOG_LOGGER_DEBUG(m_logger, "移动后位置: {}, {}", pos.x(), pos.y());
  228. /* 设置默认的时间 */
  229. if(isStartTime)
  230. {
  231. tw->setTime(plan.timeStart);
  232. } else
  233. {
  234. tw->setTime(plan.timeEnd);
  235. }
  236. tw->execShow();
  237. auto time = tw->getTime();
  238. /* 判断时间有没有修改 */
  239. if(isStartTime)
  240. {
  241. if(time == plan.timeStart)
  242. {
  243. return; // 没有修改
  244. }
  245. } else
  246. {
  247. if(time == plan.timeEnd)
  248. {
  249. return; // 没有修改
  250. }
  251. }
  252. SPDLOG_LOGGER_DEBUG(m_logger, "修改时间: {}, {}", time.toString("hh:mm:ss").toStdString(), isStartTime ? "开始时间" : "结束时间");
  253. OnePlan_t newPlan = plan;
  254. if(isStartTime)
  255. {
  256. newPlan.timeStart = time;
  257. } else
  258. {
  259. newPlan.timeEnd = time;
  260. }
  261. /* 判断时间是否重复 */
  262. updateDetectPlanList(1);
  263. if(isWeekPlanDuplicate(m_currentPlanList, newPlan, plan))
  264. {
  265. /* 设置时间报警 */
  266. TipWidget::display(TipWidget::OPERATOR_WARN, "与已有计划冲突,请重新修改", GInfo.getTopWindow());
  267. SPDLOG_LOGGER_WARN(m_logger, "检测计划冲突");
  268. return;
  269. }
  270. /* 设置时间 */
  271. one->setPlan(newPlan);
  272. /* 重新排序 */
  273. sortDetectPlanList();
  274. }
  275. /* 初始化QListWidget */
  276. void CheckPeriodWidget::initListWidget()
  277. {
  278. ui->listWidget_noDetectPlan->clear();
  279. /* 禁用横向滚动条 */
  280. /* 设置行间距为16 */
  281. }
  282. /* 添加一个检测计划 */
  283. void CheckPeriodWidget::addDetectPlan(const OnePlan_t& plan)
  284. {
  285. OneDetectPlan *detectPlan = new OneDetectPlan(eWeekType::Week_Monday, this);
  286. /* 删除日期选择框 */
  287. detectPlan->setQSS(m_qssPlan);
  288. detectPlan->setPlan(plan);
  289. connect(detectPlan, &OneDetectPlan::signal_oneDetectPlanCloseClicked, this, &CheckPeriodWidget::do_pBtn_deleteDetectPlan_clicked);
  290. connect(detectPlan, &OneDetectPlan::signal_planModifiedWeek, this, &CheckPeriodWidget::do_detectPlanModifiedWeek);
  291. connect(detectPlan, &OneDetectPlan::signal_timeButtonClicked, this, &CheckPeriodWidget::do_detectPlanModifiedTime);
  292. /* 将数据插入到列表中,在排序的时候会将新增加的插入到里面 */
  293. m_pListcurrDetect->append(detectPlan);
  294. /* 排序 */
  295. sortDetectPlanList();
  296. }
  297. /* 重新排序检测计划 */
  298. void CheckPeriodWidget::sortDetectPlanList()
  299. {
  300. /* 清空列表 */
  301. removeAllDetectPlanWidgets();
  302. /* 排序 */
  303. std::sort(m_pListcurrDetect->begin(), m_pListcurrDetect->end(), [](OneDetectPlan *a, OneDetectPlan *b)
  304. {
  305. const OnePlan_t &planA = a->getPlan();
  306. const OnePlan_t &planB = b->getPlan();
  307. /* 按时间从小到大升序 */
  308. return weekTimeIsGerater(planB.weekType, planB.timeStart, planA.weekType, planA.timeStart);
  309. });
  310. /* 重新插入 */
  311. addDetectPlanToLayout();
  312. }
  313. /* 获取计划列表 */
  314. QList<OnePlan_t> CheckPeriodWidget::updateDetectPlanList(int id)
  315. {
  316. m_currentPlanList.clear();
  317. for(auto& pDetect : *m_pListcurrDetect)
  318. {
  319. OnePlan_t plan = pDetect->getPlan();
  320. m_currentPlanList.append(plan);
  321. }
  322. return m_currentPlanList;
  323. }
  324. /* 清空当前检测计划布局中的控件 */
  325. void CheckPeriodWidget::removeAllDetectPlanWidgets()
  326. {
  327. /* 清空布局中的所有控件,只剩一个弹簧 */
  328. // for(auto& pDetect : *m_pListcurrDetect)
  329. // {
  330. // m_layoutDetectPlans->removeWidget(pDetect);
  331. // }
  332. while (m_layoutDetectPlans->count() > 1)
  333. {
  334. QWidget *widget = m_layoutDetectPlans->itemAt(0)->widget();
  335. if(widget)
  336. {
  337. m_layoutDetectPlans->removeWidget(widget);
  338. widget->hide();
  339. }
  340. }
  341. update();
  342. }
  343. /* 从当前列表中添加控件到布局 */
  344. void CheckPeriodWidget::addDetectPlanToLayout()
  345. {
  346. for(auto& pDetect : *m_pListcurrDetect)
  347. {
  348. pDetect->show();
  349. /* 添加到布局中 */
  350. m_layoutDetectPlans->insertWidget(m_layoutDetectPlans->count() - 1, pDetect);
  351. }
  352. }