managerplan.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  1. #include "managerplan.h"
  2. #include "ui_managerplan.h"
  3. #include <QMouseEvent>
  4. #include <QDesktopWidget>
  5. #include <QScreen>
  6. #include "UIStyleManager.h"
  7. #include "OneShadowEffect.h"
  8. #include "TransmitterSwitchInfo.h"
  9. #include "warning.h"
  10. #include "tipwidget.h"
  11. #include "LHQLogAPI.h"
  12. #include "savetotemplate.h"
  13. #include "FromWebAPI.h"
  14. #include "FromSQLite.h"
  15. ManagerPlan::ManagerPlan(Enum_Mode mode, QDialog *parent) :
  16. m_mode(mode),
  17. QDialog(parent),
  18. ui(new Ui::ManagerPlan)
  19. {
  20. ui->setupUi(this);
  21. /* 设置隐藏边框 */
  22. this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
  23. /* 设置底层样式表 */
  24. this->setAttribute(Qt::WA_TranslucentBackground);
  25. /* 创建阴影 */
  26. auto pShadow = new OneShadowEffect(this);
  27. ui->widget_background->setGraphicsEffect(pShadow);
  28. /* 获取屏幕大小 */
  29. // auto screenRect = QApplication::desktop()->availableGeometry();
  30. auto screenRect = QGuiApplication::screenAt(QCursor::pos())->geometry();
  31. this->resize(screenRect.width(), screenRect.height());
  32. /* 设置设置区域居中显示 */
  33. ui->widget_background->move(screenRect.width() / 2 - ui->widget_background->width() / 2,
  34. screenRect.height() / 2 - ui->widget_background->height() / 2);
  35. /* 设置Card最小宽度 */
  36. ui->pCard->setMinimumWidth(300);
  37. ui->pCard->setFixedWidth(300);
  38. /* 注册事件过滤器 */
  39. ui->cBox_selectChn->installEventFilter(this);
  40. ui->pBtn_close->installEventFilter(this);
  41. /* 设置时间和日期选择Tab */
  42. setTabWidget();
  43. /* 设置默认时间和日期 */
  44. auto date = QDate::currentDate();
  45. auto time = QTime::fromString("00:00:00", "hh:mm:ss");
  46. ui->timeEdit_weekStart->setTime(time);
  47. ui->timeEdit_weekEnd->setTime(time);
  48. ui->timeEdit_specialStart->setTime(time);
  49. ui->timeEdit_specialEnd->setTime(time);
  50. ui->dateEdit_specialStart->setDisplayFormat("yy-MM-dd");
  51. ui->dateEdit_specialEnd->setDisplayFormat("yy-MM-dd");
  52. ui->dateEdit_specialStart->setDate(date);
  53. ui->dateEdit_specialEnd->setDate(date);
  54. /* 设置时间图标 */
  55. ui->timeEdit_weekStart->setIcon(":/ICON/ICON/Time.png");
  56. ui->timeEdit_weekEnd->setIcon(":/ICON/ICON/Time.png");
  57. ui->timeEdit_specialStart->setIcon(":/ICON/ICON/Time.png");
  58. ui->timeEdit_specialEnd->setIcon(":/ICON/ICON/Time.png");
  59. ui->timeEdit_weekStart->SetMainWindow(this);
  60. ui->timeEdit_weekEnd->SetMainWindow(this);
  61. ui->timeEdit_specialStart->SetMainWindow(this);
  62. ui->timeEdit_specialEnd->SetMainWindow(this);
  63. /* 需要设置这个属性,qss设置的图标才会生效 */
  64. ui->dateEdit_specialStart->setCalendarPopup(true);
  65. ui->dateEdit_specialEnd->setCalendarPopup(true);
  66. /* 设置可选择的频率 */
  67. setSelectFrequency();
  68. /* 设置可选择的周几 */
  69. setWeekDay();
  70. /* 连接信号和槽 */
  71. connect(ui->pBtn_cancel, &QPushButton::clicked, this, &ManagerPlan::close);
  72. connect(ui->pBtn_close, &QPushButton::clicked, this, &ManagerPlan::close);
  73. connect(ui->cBox_selectChn, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ManagerPlan::do_selectFrequency);
  74. connect(&EPUIStyle, &UIStyleManager::signal_qssChanged, this, &ManagerPlan::do_setUIStyle);
  75. connect(ui->pBtn_addPlan, &QPushButton::clicked, this, &ManagerPlan::do_addPlanItem);
  76. connect(ui->pBtn_editPlan, &QPushButton::clicked, this, &ManagerPlan::do_modifyPlanItem);
  77. connect(ui->pBtn_deletePlan, &QPushButton::clicked, this, &ManagerPlan::do_deletePlanItem);
  78. connect(ui->pBtn_ok, &QPushButton::clicked, this, &ManagerPlan::do_pBtn_ok);
  79. connect(ui->pCard, &PlanCard::signal_clickedItem, this, &ManagerPlan::do_tableView_clicked);
  80. connect(ui->pBtn_saveTotemplate, &QPushButton::clicked, this, &ManagerPlan::do_saveTemplate);
  81. /* 设置皮肤样式 */
  82. do_setUIStyle();
  83. /* 设置下拉框阴影 */
  84. ui->cBox_selectChn->setViewShadowEffect();
  85. ui->cBox_selectWeekStart->setViewShadowEffect();
  86. ui->cBox_selectWeekEnd->setViewShadowEffect();
  87. /* 注册事件过滤器 */
  88. ui->cBox_selectChn->installEventFilter(this);
  89. ui->cBox_selectWeekStart->installEventFilter(this);
  90. ui->cBox_selectWeekEnd->installEventFilter(this);
  91. /* 默认显示周计划 */
  92. ui->tabWidget->setCurrentIndex(0);
  93. /* 设置显示模式 */
  94. setMode(mode);
  95. }
  96. ManagerPlan::~ManagerPlan()
  97. {
  98. delete ui;
  99. }
  100. /* 设置频率信息 */
  101. void ManagerPlan::setFrequencyID(ChannelInfo& info)
  102. {
  103. m_channelInfo = info;
  104. /* 设置当前频率选项 */
  105. if(ui->cBox_selectChn->count() > 0)
  106. {
  107. for(int i = 0; i < ui->cBox_selectChn->count(); i++)
  108. {
  109. if(ui->cBox_selectChn->itemData(i).toInt() == info.ChannelID)
  110. {
  111. ui->cBox_selectChn->setCurrentIndex(i);
  112. break;
  113. }
  114. }
  115. }
  116. /* 设置当前频率的计划列表 */
  117. ui->pCard->setChannelInfo(info);
  118. if((m_mode == Enum_Mode::Mode_Add) || (m_mode == Enum_Mode::Mode_Modify))
  119. {
  120. /* 设置当前频率的计划列表 */
  121. auto list = findPlanList(info.ChannelID);
  122. /* 设置计划列表 */
  123. ui->pCard->setPlanList(list);
  124. }
  125. if(ui->pCard->isPlanEmpty())
  126. {
  127. /* 没有计划,隐藏按钮 */
  128. setButtonVisible(false);
  129. }else
  130. {
  131. /* 有计划,显示按钮 */
  132. setButtonVisible(true);
  133. }
  134. }
  135. /* 设置计划列表,给修改模版使用 */
  136. void ManagerPlan::setPlanList(QList<OnePlanItemInfo>& listPlan)
  137. {
  138. /* 设置当前频率的计划列表 */
  139. ui->pCard->setPlanList(listPlan);
  140. /* 转换为PlanInfo */
  141. QList<PlanInfo> list;
  142. ui->pCard->getPlanList(list);
  143. /* 设置计划列表 */
  144. m_mapPlanInfo.insert(m_channelInfo.ChannelID, list);
  145. if(ui->pCard->isPlanEmpty())
  146. {
  147. /* 没有计划,隐藏按钮 */
  148. setButtonVisible(false);
  149. }else
  150. {
  151. /* 有计划,显示按钮 */
  152. setButtonVisible(true);
  153. }
  154. }
  155. /* 设置FromWebAPI地址,复用主窗口的WebAPI */
  156. void ManagerPlan::setFromWebAPI(FromWebAPI* fromWebAPI)
  157. {
  158. if(fromWebAPI == nullptr)
  159. {
  160. // LH_WRITE_ERROR("传入的FromWebAPI指针为空");
  161. return;
  162. }
  163. m_fromWebAPI = fromWebAPI;
  164. }
  165. /* 设置FromSQLite地址,复用主窗口的SQLite */
  166. void ManagerPlan::setFromSQLite(FromSQLite* fromSQLite)
  167. {
  168. if(fromSQLite == nullptr)
  169. {
  170. // LH_WRITE_ERROR("传入的FromSQLite指针为空");
  171. return;
  172. }
  173. m_fromSQLite = fromSQLite;
  174. }
  175. /* 修改UI样式 */
  176. void ManagerPlan::do_setUIStyle()
  177. {
  178. this->setStyleSheet(EPUIStyle.StrQSS_ManagerPlan);
  179. }
  180. /* 设置显示模式,需要在执行exec()之前调用 */
  181. void ManagerPlan::setMode(Enum_Mode mode)
  182. {
  183. if(mode == Enum_Mode::Mode_Add)
  184. {
  185. ui->label_title->setText("新增"); /* 修改标题 */
  186. ui->widget_background->resize(this->width(), 740); /* 修改窗口大小 */
  187. }
  188. else if(mode == Enum_Mode::Mode_Modify)
  189. {
  190. ui->widget_addPlan->setVisible(false); /* 隐藏添加计划区域 */
  191. ui->label_title->setText("编辑"); /* 修改标题 */
  192. ui->widget_background->resize(this->width(), 600); /* 修改窗口大小 */
  193. }
  194. else if(mode == Enum_Mode::Mode_ModifyTemplate)
  195. {
  196. ui->widget_addPlan->setVisible(false); /* 隐藏添加计划区域 */
  197. ui->label_title->setText("修改模板"); /* 修改标题 */
  198. ui->widget_background->resize(this->width(), 600); /* 修改窗口大小 */
  199. ui->pBtn_saveTotemplate->setVisible(false); /* 隐藏保存模版按钮 */
  200. }
  201. m_mode = mode;
  202. }
  203. /* 设置时间和日期选择Tab */
  204. void ManagerPlan::setTabWidget()
  205. {
  206. /* 设置Tab的大小 */
  207. QSize size(ui->tabWidget->width(), ui->tabWidget->height() - ui->tabWidget->tabBar()->height() - 2);
  208. /* 设置正常日的Tab */
  209. ui->tab_week->resize(size);
  210. auto vLayout1 = new QVBoxLayout(ui->tab_week);
  211. vLayout1->setContentsMargins(0, 24, 0, 0);
  212. vLayout1->setSpacing(12);
  213. ui->tab_week->setLayout(vLayout1);
  214. vLayout1->addWidget(ui->widget_weekStart);
  215. vLayout1->addWidget(ui->widget_weekEnd);
  216. /* 设置特殊日的Tab */
  217. ui->tab_special->resize(size);
  218. auto vLayout2 = new QVBoxLayout(ui->tab_special);
  219. vLayout2->setContentsMargins(0, 24, 0, 0);
  220. vLayout2->setSpacing(12);
  221. ui->tab_special->setLayout(vLayout2);
  222. vLayout2->addWidget(ui->widget_specialStart);
  223. vLayout2->addWidget(ui->widget_specialEnd);
  224. }
  225. /* 设置可选择的周几 */
  226. void ManagerPlan::setWeekDay()
  227. {
  228. ui->cBox_selectWeekStart->addItem("星期一", static_cast<int>(enum_WeekDay::WeekDay_Mon));
  229. ui->cBox_selectWeekStart->addItem("星期二", static_cast<int>(enum_WeekDay::WeekDay_Tue));
  230. ui->cBox_selectWeekStart->addItem("星期三", static_cast<int>(enum_WeekDay::WeekDay_Wed));
  231. ui->cBox_selectWeekStart->addItem("星期四", static_cast<int>(enum_WeekDay::WeekDay_Thu));
  232. ui->cBox_selectWeekStart->addItem("星期五", static_cast<int>(enum_WeekDay::WeekDay_Fri));
  233. ui->cBox_selectWeekStart->addItem("星期六", static_cast<int>(enum_WeekDay::WeekDay_Sat));
  234. ui->cBox_selectWeekStart->addItem("星期天", static_cast<int>(enum_WeekDay::WeekDay_Sun));
  235. ui->cBox_selectWeekEnd->addItem("星期一", static_cast<int>(enum_WeekDay::WeekDay_Mon));
  236. ui->cBox_selectWeekEnd->addItem("星期二", static_cast<int>(enum_WeekDay::WeekDay_Tue));
  237. ui->cBox_selectWeekEnd->addItem("星期三", static_cast<int>(enum_WeekDay::WeekDay_Wed));
  238. ui->cBox_selectWeekEnd->addItem("星期四", static_cast<int>(enum_WeekDay::WeekDay_Thu));
  239. ui->cBox_selectWeekEnd->addItem("星期五", static_cast<int>(enum_WeekDay::WeekDay_Fri));
  240. ui->cBox_selectWeekEnd->addItem("星期六", static_cast<int>(enum_WeekDay::WeekDay_Sat));
  241. ui->cBox_selectWeekEnd->addItem("星期天", static_cast<int>(enum_WeekDay::WeekDay_Sun));
  242. }
  243. /* 设置可选频率 */
  244. void ManagerPlan::setSelectFrequency()
  245. {
  246. for(const auto& chnInfo : ChnContainer.getMapChannel())
  247. {
  248. ui->cBox_selectChn->addItem(chnInfo.ChannelName, chnInfo.ChannelID);
  249. }
  250. /* 设置默认的频率 */
  251. if(ui->cBox_selectChn->count() > 0)
  252. {
  253. ui->cBox_selectChn->setCurrentIndex(0);
  254. do_selectFrequency(0);
  255. }
  256. }
  257. /* 查找本地计划列表,这个频率不存在则添加 */
  258. QList<PlanInfo>& ManagerPlan::findPlanList(const int chnID)
  259. {
  260. auto list = m_mapPlanInfo.find(chnID);
  261. /* 如果没有这个频率的计划列表,则创建一个新的列表 */
  262. if(list == m_mapPlanInfo.end())
  263. {
  264. QList<PlanInfo> listPlan;
  265. /* 如果是修改模版,则不从全局获取数据,插入一个空的即可 */
  266. if(m_mode != Enum_Mode::Mode_ModifyTemplate)
  267. {
  268. /* 将PData的计划拷贝过来 */
  269. auto pCard = PData.findPlanCard(chnID);
  270. if(pCard != nullptr)
  271. {
  272. pCard->getPlanList(listPlan);
  273. }
  274. }
  275. m_mapPlanInfo.insert(chnID, listPlan);
  276. }
  277. /* 再次查找这个频率的列表 */
  278. list = m_mapPlanInfo.find(chnID);
  279. return *list;
  280. }
  281. /* 查找全局计划列表,没有被修改过的计划列表 */
  282. void ManagerPlan::findGlobalPlanList(const int chnID, QList<PlanInfo>& list)
  283. {
  284. /* 将PData的计划拷贝过来 */
  285. auto pCard = PData.findPlanCard(chnID);
  286. if(pCard != nullptr)
  287. {
  288. pCard->getPlanList(list);
  289. }
  290. }
  291. /* 添加计划,同时添加ui的卡片计划和计划列表 */
  292. void ManagerPlan::addPlanItem(const int chnID, const PlanInfo& info)
  293. {
  294. /* 添加到UI*/
  295. ui->pCard->addPlanItem(info);
  296. /* 添加到计划列表 */
  297. QList<PlanInfo>& list = findPlanList(chnID);
  298. list.append(info);
  299. }
  300. /* 修改容器中的计划 */
  301. void ManagerPlan::modifyPlanItem(const int chnID, const PlanInfo& nowInfo, const PlanInfo& newInfo)
  302. {
  303. auto& list = findPlanList(chnID);
  304. for(int i = 0; i < list.count(); i++)
  305. {
  306. if(list.at(i) == nowInfo)
  307. {
  308. list.replace(i, newInfo);
  309. break;
  310. }
  311. }
  312. }
  313. /**
  314. * @brief 判断开机和关机时间是否冲突
  315. *
  316. * @param info
  317. * @return true 冲突
  318. * @return false 不冲突
  319. */
  320. bool ManagerPlan::checkOnAndOffTime(const PlanInfo& info)
  321. {
  322. if(info.onWeekDay != enum_WeekDay::WeekDay_Special)
  323. {
  324. /* 正常日判断 */
  325. if(info.onWeekDay > info.offWeekDay)
  326. {
  327. /* 开机时间大于关机时间,冲突 */
  328. return true;
  329. }
  330. else if(info.onWeekDay == info.offWeekDay)
  331. {
  332. /* 开机和关机在同一天 */
  333. if(info.onDateTime.time() >= info.offDateTime.time())
  334. {
  335. /* 开机时间大于等于关机时间,冲突 */
  336. return true;
  337. }else
  338. {
  339. /* 开机时间小于关机时间,不冲突 */
  340. return false;
  341. }
  342. }
  343. return false;
  344. }
  345. else
  346. {
  347. /* 特殊日判断 */
  348. /* 开机和关机在不同天 */
  349. if(info.onDateTime.date() > info.offDateTime.date())
  350. {
  351. /* 开机时间大于关机时间,冲突 */
  352. return true;
  353. }
  354. else if(info.onDateTime.date() == info.offDateTime.date())
  355. {
  356. /* 开机和关机在同一天 */
  357. if(info.onDateTime.time() >= info.offDateTime.time())
  358. {
  359. /* 开机时间大于等于关机时间,冲突 */
  360. return true;
  361. }else
  362. {
  363. /* 开机时间小于关机时间,不冲突 */
  364. return false;
  365. }
  366. }
  367. return false;
  368. }
  369. }
  370. /**
  371. * @brief 比较两个时间点的大小,正常日和特殊日都可以比较
  372. *
  373. * @param info1
  374. * @param info2
  375. * @return true info1 > info2
  376. * @return false info1 < info2
  377. */
  378. bool ManagerPlan::timeIsGerater(const enum_WeekDay weekDay1, const QDateTime& time1,
  379. const enum_WeekDay weekDay2, const QDateTime& time2)
  380. {
  381. /* 正常日 */
  382. if(weekDay1 != enum_WeekDay::WeekDay_Special)
  383. {
  384. /* 先比较日期 */
  385. if(weekDay1 > weekDay2)
  386. {
  387. return true;
  388. }
  389. else if(weekDay1 == weekDay2)
  390. {
  391. /* 日期相同,比较时间 */
  392. if(time1.time() > time2.time())
  393. {
  394. return true;
  395. }else
  396. {
  397. return false;
  398. }
  399. }
  400. return false;
  401. }
  402. else /* 特殊日 */
  403. {
  404. /* 先比较日期 */
  405. if(time1.date() > time2.date())
  406. {
  407. return true;
  408. }
  409. else if(time1.date() == time2.date())
  410. {
  411. /* 日期相同,比较时间 */
  412. if(time1.time() > time2.time())
  413. {
  414. return true;
  415. }else
  416. {
  417. return false;
  418. }
  419. }
  420. return false;
  421. }
  422. }
  423. /**
  424. * @brief 判断计划时间和列表中的时间是否冲突
  425. * 判断规则是只要时间段不和任何一个时间段重合就不冲突
  426. *
  427. * @param chnID
  428. * @param info
  429. * @return true 时间冲突
  430. * @return false 时间不冲突
  431. */
  432. bool ManagerPlan::checkPlanTimeConflict(const int chnID, const PlanInfo& info)
  433. {
  434. QList<PlanInfo>& list = findPlanList(chnID);
  435. bool isConflict = false;
  436. int weekDayStart = static_cast<int>(info.onWeekDay);
  437. int weekDayEnd = static_cast<int>(info.offWeekDay);
  438. for(const auto& it : list)
  439. {
  440. /* info结束时间小于开始时间,或者info开始时间大于结束时间,就不冲突 */
  441. bool isLess = timeIsGerater(it.onWeekDay, it.onDateTime, info.offWeekDay, info.offDateTime);
  442. bool isGreater = timeIsGerater(info.onWeekDay, info.onDateTime, it.offWeekDay, it.offDateTime);
  443. if(isLess || isGreater)
  444. {
  445. /* 时间不冲突 */
  446. continue;
  447. }
  448. isConflict = true; /* 时间冲突 */
  449. break;
  450. }
  451. return isConflict;
  452. }
  453. /* 判断计划时间和列表中的时间是否冲突,排除原有的日期,用于比较修改的计划 */
  454. bool ManagerPlan::checkPlanTimeConflict(const int chnID, const PlanInfo& newInfo, const PlanInfo& exInfo)
  455. {
  456. /* 这里采用拷贝的方式获取,后续不需要再把排除的项放回去 */
  457. QList<PlanInfo> list = findPlanList(chnID);
  458. /* 先去掉需要排除的项 */
  459. list.removeOne(exInfo);
  460. bool isConflict = false;
  461. int weekDayStart = static_cast<int>(newInfo.onWeekDay);
  462. int weekDayEnd = static_cast<int>(newInfo.offWeekDay);
  463. for(const auto& it : list)
  464. {
  465. /* info结束时间小于开始时间,或者info开始时间大于结束时间,就不冲突 */
  466. bool isLess = timeIsGerater(it.onWeekDay, it.onDateTime, newInfo.offWeekDay, newInfo.offDateTime);
  467. bool isGreater = timeIsGerater(newInfo.onWeekDay, newInfo.onDateTime, it.offWeekDay, it.offDateTime);
  468. if(isLess || isGreater)
  469. {
  470. /* 时间不冲突 */
  471. continue;
  472. }
  473. isConflict = true; /* 时间冲突 */
  474. break;
  475. }
  476. return isConflict;
  477. }
  478. /**
  479. * @brief 判断新添加的计划是否在即将要执行的计划附近
  480. * 1、运行这个函数之前会先进行时间冲突监测,如果有冲突,新计划的关机计划必定在即将执行的计划之前
  481. * 2、新添加计划主要判断新计划的结束时间是否在即将执行的计划开始时间之前的10分钟内
  482. *
  483. * @param chnID
  484. * @param newInfo
  485. * @return true
  486. * @return false
  487. */
  488. bool ManagerPlan::checkNewPlanNear(const int chnID, const PlanInfo& newInfo)
  489. {
  490. QList<PlanInfo> list;
  491. findGlobalPlanList(chnID, list);
  492. /* 先寻找是否有即将执行的计划 */
  493. QDateTime nowTime = QDateTime::currentDateTime();
  494. /* 先判断关机时间是否在当前时间点到之后十分钟之内 */
  495. if(!isNearTime(nowTime, newInfo.offWeekDay, newInfo.offDateTime))
  496. {
  497. /* 关机时间不在当前时间点到之后十分钟之内,不冲突 */
  498. return false;
  499. }
  500. /* 关机时间在当前时间之后的十分钟内,再查找已有的计划开机时间是否有在十分钟之内的 */
  501. bool isConflict = false;
  502. // PlanInfo tmpInfo;
  503. for(const auto& it : list)
  504. {
  505. if(isNearTime(nowTime, it.onWeekDay, it.onDateTime))
  506. {
  507. isConflict = true;
  508. // tmpInfo = it; /* 记录即将执行的计划 */
  509. break;
  510. }
  511. }
  512. return isConflict;
  513. }
  514. /* 判断修改的计划是否对即将要执行的计划有影响 */
  515. bool ManagerPlan::checkModifyPlanNear(const int chnID, const PlanInfo& oldInfo, const PlanInfo& newInfo)
  516. {
  517. /* 先判断旧数据是否在原始数据列表中 */
  518. QList<PlanInfo> list;
  519. findGlobalPlanList(chnID, list);
  520. bool isExist = false;
  521. for(const auto& it : list)
  522. {
  523. if(it == oldInfo)
  524. {
  525. isExist = true;
  526. break;
  527. }
  528. }
  529. if(!isExist)
  530. {
  531. /* 旧数据不在原始数据列表中,直接返回 */
  532. return false;
  533. }
  534. /*--------------------------------------------------------------
  535. * 判断修改的计划有没有在倒计时附近
  536. * 1、如果被修改的计划在倒计时附近,不能修改
  537. * 2、如果被修改的计划不在倒计时附近,判断修改完成后的计划是否在倒计时附近
  538. * 判断方法:先判断修改完成后的计划是否在当前十分钟之内,如果在,再查找
  539. * 当前十分钟之内是否有即将执行的计划,如果有,则冲突
  540. *--------------------------------------------------------------*/
  541. QDateTime nowTime = QDateTime::currentDateTime();
  542. /* 先判断被修改的计划是否在倒计时附近 */
  543. if(isNearTime(nowTime, oldInfo.onWeekDay, oldInfo.onDateTime) ||
  544. isNearTime(nowTime, oldInfo.offWeekDay, oldInfo.offDateTime))
  545. {
  546. /* 被修改的计划在倒计时附近,不能修改 */
  547. TipWidget::display(TipWidget::OPERATOR_WARN, "被修改的计划正在倒计时,不能修改!", this);
  548. return true;
  549. }
  550. /* 判断修改完成后的计划是否在当前时间附近 */
  551. if(isNearTime(nowTime, newInfo.onWeekDay, newInfo.onDateTime) ||
  552. isNearTime(nowTime, newInfo.offWeekDay, newInfo.offDateTime))
  553. {
  554. /* 查找附近有无倒计时 */
  555. if(findNearPlan(chnID, nowTime))
  556. {
  557. TipWidget::display(TipWidget::OPERATOR_WARN, "修改后的计划在倒计时范围内,不能修改!", this);
  558. return true;
  559. }
  560. }
  561. return false;
  562. }
  563. /**
  564. * @brief 判断这个时间点附近有没有即将要执行的计划
  565. * 1、先寻找特殊日,特殊日会覆盖正常日的计划,十分钟内既有特殊日又有正常日,返回的是特殊日
  566. * 2、这个查找的是原始的没有被修改过的计划列表
  567. *
  568. * @param chnID
  569. * @param nearInfo
  570. * @return true
  571. * @return false
  572. */
  573. bool ManagerPlan::findNearPlan(const int chnID, const QDateTime& nowTime)
  574. {
  575. QList<PlanInfo> list;
  576. findGlobalPlanList(chnID, list);
  577. bool isNear = false;
  578. /* 先判断特殊日 */
  579. for(const auto& it : list)
  580. {
  581. if(it.onWeekDay == enum_WeekDay::WeekDay_Special)
  582. {
  583. if(isNearTime(nowTime, it.onWeekDay, it.onDateTime))
  584. {
  585. /* 找到特殊日的计划 */
  586. isNear = true;
  587. break;
  588. }
  589. if(isNearTime(nowTime, it.offWeekDay, it.offDateTime))
  590. {
  591. /* 找到特殊日的计划 */
  592. isNear = true;
  593. break;
  594. }
  595. }
  596. }
  597. if(isNear)
  598. {
  599. /* 找到特殊日的计划,直接返回 */
  600. return true;
  601. }
  602. /* 判断正常日 */
  603. for(const auto& it : list)
  604. {
  605. if(it.onWeekDay != enum_WeekDay::WeekDay_Special)
  606. {
  607. if(isNearTime(nowTime, it.onWeekDay, it.onDateTime))
  608. {
  609. /* 找到正常日的计划 */
  610. isNear = true;
  611. break;
  612. }
  613. if(isNearTime(nowTime, it.offWeekDay, it.offDateTime))
  614. {
  615. /* 找到正常日的计划 */
  616. isNear = true;
  617. break;
  618. }
  619. }
  620. }
  621. return isNear;
  622. }
  623. /* 判断两个时间点是否在十分钟之内 */
  624. bool ManagerPlan::isNearTime(const QDateTime& nowTime, const enum_WeekDay weekDay, const QDateTime& time)
  625. {
  626. // 10分钟后
  627. QDateTime tmpTime = nowTime.addSecs(10 * 60);
  628. enum_WeekDay nowWeekDay = static_cast<enum_WeekDay>(nowTime.date().dayOfWeek());
  629. enum_WeekDay tmpWeekDay = static_cast<enum_WeekDay>(tmpTime.date().dayOfWeek());
  630. /* 先判断是否是特殊日 */
  631. if(weekDay == enum_WeekDay::WeekDay_Special)
  632. {
  633. if(time <= tmpTime && time > nowTime)
  634. {
  635. /* 在10分钟之内 */
  636. return true;
  637. }
  638. }
  639. /* 正常日,先判断有没有跨天 */
  640. if(nowWeekDay == tmpWeekDay)
  641. {
  642. /* 在同一天 */
  643. if(time.time() <= tmpTime.time() && time.time() > nowTime.time())
  644. {
  645. /* 在10分钟之内 */
  646. return true;
  647. }
  648. }else {
  649. /* 跨天了,判断时间 */
  650. if(weekDay == nowWeekDay)
  651. {
  652. /* 在今天 */
  653. if(time.time() >= nowTime.time())
  654. {
  655. /* 在今天的10分钟之内 */
  656. return true;
  657. }else {
  658. /* 在明天的10分钟之内 */
  659. if(time.time() <= tmpTime.time())
  660. {
  661. return true;
  662. }
  663. }
  664. }
  665. }
  666. return false; /* 不在10分钟之内 */
  667. }
  668. /* 设置按钮显示或隐藏 */
  669. void ManagerPlan::setButtonVisible(bool isVisible)
  670. {
  671. if(isVisible)
  672. {
  673. ui->pBtn_editPlan->show();
  674. ui->pBtn_deletePlan->show();
  675. }else
  676. {
  677. ui->pBtn_editPlan->hide();
  678. ui->pBtn_deletePlan->hide();
  679. }
  680. }
  681. /* 保存模版 */
  682. void ManagerPlan::saveTemplateToEQM()
  683. {
  684. if(m_fromWebAPI == nullptr && m_fromSQLite == nullptr)
  685. {
  686. LH_WRITE_ERROR("没有初始化FromWebAPI或FromSQLite");
  687. return;
  688. }
  689. auto chnInfo = ui->pCard->getChannelInfo();
  690. /* 获取所有的模板名称 */
  691. QList<OneTemplateInfo> list;
  692. if(!m_fromWebAPI->getTemplateList(chnInfo.ChannelID, list))
  693. {
  694. LH_WRITE_ERROR(QString("获取频率ID为%1的模版列表失败").arg(chnInfo.ChannelID));
  695. TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);
  696. return;
  697. }
  698. /* 弹出导出页面 */
  699. std::shared_ptr<SaveToTemplate> stt = std::make_shared<SaveToTemplate>();
  700. stt->setQSS(EPUIStyle.getQSSPath());
  701. stt->setTemplateList(list);
  702. stt->exec();
  703. if(!stt->isOk())
  704. {
  705. return;
  706. }
  707. /* 获取一天的数据 */
  708. QList<OnePlanItemInfo> listTmp;
  709. ui->pCard->getAllPlanInfo(listTmp);
  710. /* 保存到模板 */
  711. bool isSuccess = false;
  712. if(GInfo.isOnlineDB())
  713. {
  714. isSuccess = m_fromWebAPI->saveTemplate(stt->getTemplateName(), listTmp);
  715. }else {
  716. isSuccess = m_fromSQLite->saveTemplate(stt->getTemplateName(), listTmp);
  717. }
  718. if(isSuccess)
  719. {
  720. TipWidget::display(TipWidget::OPERATOR_OK, "保存模版成功", this);
  721. }else {
  722. TipWidget::display(TipWidget::OPERATOR_FAIL, "保存模版失败", this);
  723. }
  724. /* 调用回调函数 */
  725. emit signal_callBack(3);
  726. }
  727. /* 选择了一个频率 */
  728. void ManagerPlan::do_selectFrequency(int index)
  729. {
  730. auto chnID = ui->cBox_selectChn->itemData(index).toInt();
  731. m_channelInfo = ChnContainer.getChannel(chnID);
  732. QList<PlanInfo>& list = findPlanList(chnID);
  733. /* 设置频率信息 */
  734. ui->pCard->setChannelInfo(ChnContainer.getChannel(chnID));
  735. /* 设置计划列表 */
  736. ui->pCard->setPlanList(list);
  737. if(list.isEmpty())
  738. {
  739. /* 没有计划,隐藏按钮 */
  740. setButtonVisible(false);
  741. }else
  742. {
  743. /* 有计划,显示按钮 */
  744. setButtonVisible(true);
  745. }
  746. }
  747. /* 点击了添加按钮 */
  748. void ManagerPlan::do_addPlanItem()
  749. {
  750. int chnID = ui->pCard->getChannelInfo().ChannelID;
  751. PlanInfo one;
  752. /* 判断是正常日还是特殊日 */
  753. if(ui->tabWidget->currentIndex() == 0)
  754. {
  755. /* 正常日 */
  756. one.onWeekDay = static_cast<enum_WeekDay>(ui->cBox_selectWeekStart->itemData(ui->cBox_selectWeekStart->currentIndex()).toInt());
  757. one.onDateTime.setTime(ui->timeEdit_weekStart->getTime());
  758. one.offWeekDay = static_cast<enum_WeekDay>(ui->cBox_selectWeekEnd->itemData(ui->cBox_selectWeekEnd->currentIndex()).toInt());
  759. one.offDateTime.setTime(ui->timeEdit_weekEnd->getTime());
  760. }else {
  761. /* 特殊日 */
  762. one.onWeekDay = enum_WeekDay::WeekDay_Special;
  763. one.onDateTime.setDate(ui->dateEdit_specialStart->date());
  764. one.onDateTime.setTime(ui->timeEdit_specialStart->getTime());
  765. one.offWeekDay = enum_WeekDay::WeekDay_Special;
  766. one.offDateTime.setDate(ui->dateEdit_specialEnd->date());
  767. one.offDateTime.setTime(ui->timeEdit_specialEnd->getTime());
  768. }
  769. /* 先判断开机时间和关机时间是否冲突 */
  770. if(checkOnAndOffTime(one))
  771. {
  772. /* 开始和结束时间冲突 */
  773. TipWidget::display(TipWidget::OPERATOR_WARN, "开机时间早于或等于关机时间!", this);
  774. return;
  775. }
  776. /* 判断时间段是否和历史时间段冲突 */
  777. if(checkPlanTimeConflict(chnID, one))
  778. {
  779. /* 时间段冲突 */
  780. TipWidget::display(TipWidget::OPERATOR_WARN, "时间段冲突!", this);
  781. return;
  782. }
  783. /* 判断新计划是否在即将要执行的计划时间点附近 */
  784. // if(checkNewPlanNear(chnID, one))
  785. // {
  786. // TipWidget::display(TipWidget::OPERATOR_WARN, "新计划在即将执行的计划倒计时之内!", this);
  787. // return;
  788. // }
  789. /* 添加计划 */
  790. addPlanItem(chnID, one);
  791. setButtonVisible(true); /* 显示按钮 */
  792. }
  793. /* 点击修改按钮 */
  794. void ManagerPlan::do_modifyPlanItem()
  795. {
  796. int chnID = ui->pCard->getChannelInfo().ChannelID;
  797. auto& list = findPlanList(chnID);
  798. /* 获取选中的行 */
  799. auto slectRow = ui->pCard->getSelectedRow();
  800. if(slectRow < 0 || slectRow >= list.size())
  801. {
  802. /* 没有选中行 */
  803. TipWidget::display(TipWidget::OPERATOR_WARN, "没有选中行!", this);
  804. return;
  805. }
  806. // LH_WRITE_LOG_DEBUG(QString("修改行: %1").arg(index));
  807. /* 获取修改后的日期 */
  808. PlanInfo one;
  809. if(ui->tabWidget->currentIndex() == 0)
  810. {
  811. /* 正常日 */
  812. one.onWeekDay = static_cast<enum_WeekDay>(ui->cBox_selectWeekStart->itemData(ui->cBox_selectWeekStart->currentIndex()).toInt());
  813. one.onDateTime.setTime(ui->timeEdit_weekStart->getTime());
  814. one.offWeekDay = static_cast<enum_WeekDay>(ui->cBox_selectWeekEnd->itemData(ui->cBox_selectWeekEnd->currentIndex()).toInt());
  815. one.offDateTime.setTime(ui->timeEdit_weekEnd->getTime());
  816. }else {
  817. /* 特殊日 */
  818. one.onWeekDay = enum_WeekDay::WeekDay_Special;
  819. one.onDateTime.setDate(ui->dateEdit_specialStart->date());
  820. one.onDateTime.setTime(ui->timeEdit_specialStart->getTime());
  821. one.offWeekDay = enum_WeekDay::WeekDay_Special;
  822. one.offDateTime.setDate(ui->dateEdit_specialEnd->date());
  823. one.offDateTime.setTime(ui->timeEdit_specialEnd->getTime());
  824. }
  825. /* 先判断设置的时间是否和当前选中的行的时间相同 */
  826. auto nowPlan = ui->pCard->getSelectedPlan();
  827. if(nowPlan == one)
  828. {
  829. return;
  830. }
  831. /* 先判断开机时间和关机时间是否冲突 */
  832. if(checkOnAndOffTime(one))
  833. {
  834. /* 开始和结束时间冲突 */
  835. TipWidget::display(TipWidget::OPERATOR_WARN, "开机时间早于或等于关机时间!", this);
  836. return;
  837. }
  838. auto exPlan = ui->pCard->getSelectedPlan();
  839. /* 判断时间段是否和历史时间段冲突 */
  840. if(checkPlanTimeConflict(chnID, one, exPlan))
  841. {
  842. /* 时间段冲突 */
  843. TipWidget::display(TipWidget::OPERATOR_WARN, "时间段冲突!", this);
  844. return;
  845. }
  846. /* 判断修改的计划是否在即将要执行的计划时间点附近 */
  847. // if(checkModifyPlanNear(chnID, exPlan, one))
  848. // {
  849. // return;
  850. // }
  851. /* 修改选中的行 */
  852. auto oldPlan = ui->pCard->modifyPlanItem(slectRow, one);
  853. /* 修改数据容器中的计划 */
  854. modifyPlanItem(chnID, oldPlan, one);
  855. }
  856. /* 点击了删除按钮 */
  857. void ManagerPlan::do_deletePlanItem()
  858. {
  859. int chnID = ui->pCard->getChannelInfo().ChannelID;
  860. auto& list = findPlanList(chnID);
  861. /* 获取选中的行 */
  862. auto row = ui->pCard->getSelectedRow();
  863. if(row < 0 || row >= list.size())
  864. {
  865. /* 没有选中行 */
  866. TipWidget::display(TipWidget::OPERATOR_WARN, "没有选中行!", this);
  867. return;
  868. }
  869. LH_WRITE_LOG_DEBUG(QString("删除行: %1").arg(row));
  870. /* 删除选中的行 */
  871. auto plan = ui->pCard->deletePlanItem(row);
  872. /* 删除UI的计划 */
  873. list.removeOne(plan);
  874. /* 判断删除后是否还有计划,没有就隐藏修改和删除按钮 */
  875. if(list.isEmpty())
  876. {
  877. /* 没有计划,隐藏按钮 */
  878. setButtonVisible(false);
  879. }
  880. }
  881. /* 点击了保存模版按钮 */
  882. void ManagerPlan::do_saveTemplate()
  883. {
  884. /* 判断卡片有没有计划 */
  885. if(ui->pCard->isPlanEmpty())
  886. {
  887. /* 没有计划 */
  888. TipWidget::display(TipWidget::OPERATOR_WARN, "该频率没有计划!", this);
  889. return;
  890. }
  891. saveTemplateToEQM();
  892. }
  893. /* 点击了OK按钮 */
  894. void ManagerPlan::do_pBtn_ok()
  895. {
  896. m_isOK = true;
  897. this->close();
  898. }
  899. /* 选中了一项,回显到编辑页面 */
  900. void ManagerPlan::do_tableView_clicked(PlanInfo& info)
  901. {
  902. /* 设置时间和日期 */
  903. if(info.onWeekDay != enum_WeekDay::WeekDay_Special)
  904. {
  905. /* 正常日 */
  906. ui->cBox_selectWeekStart->setCurrentIndex(static_cast<int>(info.onWeekDay) - 1);
  907. ui->timeEdit_weekStart->setTime(info.onDateTime.time());
  908. ui->cBox_selectWeekEnd->setCurrentIndex(static_cast<int>(info.offWeekDay) - 1);
  909. ui->timeEdit_weekEnd->setTime(info.offDateTime.time());
  910. }else
  911. {
  912. /* 特殊日 */
  913. ui->dateEdit_specialStart->setDate(info.onDateTime.date());
  914. ui->timeEdit_specialStart->setTime(info.onDateTime.time());
  915. ui->dateEdit_specialEnd->setDate(info.offDateTime.date());
  916. ui->timeEdit_specialEnd->setTime(info.offDateTime.time());
  917. }
  918. /* 判断是正常日还是特殊日,自动切换显示的页面 */
  919. if(info.onWeekDay != enum_WeekDay::WeekDay_Special)
  920. {
  921. /* 正常日 */
  922. ui->tabWidget->setCurrentIndex(0);
  923. }else {
  924. /* 特殊日 */
  925. ui->tabWidget->setCurrentIndex(1);
  926. }
  927. }
  928. /* 鼠标点击事件 */
  929. void ManagerPlan::mousePressEvent(QMouseEvent *event)
  930. {
  931. m_lastPos = event->globalPos();
  932. event->accept();
  933. }
  934. /* 鼠标移动事件 */
  935. void ManagerPlan::mouseMoveEvent(QMouseEvent *event)
  936. {
  937. auto point = ui->widget_top->mapToGlobal(QPoint(0, 0));
  938. QRect rect(point, ui->widget_top->size());
  939. if(!rect.contains(m_lastPos))
  940. {
  941. event->accept();
  942. return;
  943. }
  944. int dx = event->globalX() - m_lastPos.x();
  945. int dy = event->globalY() - m_lastPos.y();
  946. ui->widget_background->move(ui->widget_background->x() + dx, ui->widget_background->y() + dy);
  947. m_lastPos = event->globalPos();
  948. event->accept();
  949. }
  950. /* 鼠标释放事件 */
  951. void ManagerPlan::mouseReleaseEvent(QMouseEvent *event)
  952. {
  953. event->accept();
  954. }
  955. /* 事件过滤器 */
  956. bool ManagerPlan::eventFilter(QObject *watched, QEvent *event)
  957. {
  958. if(watched == ui->cBox_selectChn)
  959. {
  960. if(event->type() == QEvent::Wheel)
  961. {
  962. return true;
  963. }
  964. }
  965. else if(watched == ui->cBox_selectChn)
  966. {
  967. if(event->type() == QEvent::Wheel)
  968. {
  969. return true;
  970. }
  971. }
  972. else if(watched == ui->cBox_selectWeekStart)
  973. {
  974. if(event->type() == QEvent::Wheel)
  975. {
  976. return true;
  977. }
  978. }
  979. else if(watched == ui->cBox_selectWeekEnd)
  980. {
  981. if(event->type() == QEvent::Wheel)
  982. {
  983. return true;
  984. }
  985. }
  986. else if(watched == ui->pBtn_close)
  987. {
  988. if(event->type() == QEvent::Enter)
  989. {
  990. ui->pBtn_close->setProperty("Hover", true);
  991. ui->pBtn_close->style()->unpolish(ui->pBtn_close);
  992. ui->pBtn_close->style()->polish(ui->pBtn_close);
  993. return true;
  994. }else if(event->type() == QEvent::Leave)
  995. {
  996. ui->pBtn_close->setProperty("Hover", false);
  997. ui->pBtn_close->style()->unpolish(ui->pBtn_close);
  998. ui->pBtn_close->style()->polish(ui->pBtn_close);
  999. return true;
  1000. }
  1001. }
  1002. return QDialog::eventFilter(watched, event);
  1003. }