transmitterswitch.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. #include "transmitterswitch.h"
  2. #include "ui_transmitterswitch.h"
  3. #include <QFile>
  4. #include <QList>
  5. #include <memory>
  6. #include "LHQLogAPI.h"
  7. #include "widgetitems.h"
  8. #include "UserData/pBtnUserData.h"
  9. #include "AddItem/addnormalitem.h"
  10. #include "AddItem/addspecialitem.h"
  11. #include "WebAPI/FromWebAPI.h"
  12. #include "transmitterswitchinfo.h"
  13. #include "oneitem.h"
  14. #include "ItemData.h"
  15. #include "timewidget.h"
  16. TransmitterSwitch::TransmitterSwitch(QWidget *parent) :
  17. QWidget(parent),
  18. ui(new Ui::TransmitterSwitch)
  19. {
  20. ui->setupUi(this);
  21. /* 创建WebAPI实例 */
  22. m_fromWebAPI = new FromWebAPI;
  23. /* 设置“默认计划”按钮可点击 */
  24. ui->pBtn_defaultPlan->setCheckable(true);
  25. /* 创建一周8天的页面 */
  26. createWeekWidget();
  27. /* 设置提示文本 */
  28. m_tipText = new QLabel(this);
  29. m_tipText->resize(936,56);
  30. m_tipText->move(456,8);
  31. m_tipText->setObjectName("label_TipText");
  32. m_tipText->setText(R"(按时刻执行模式:即以时刻点为单位进行执行,若某日既为普通日和特殊日,在某一时刻皆有执行动作,将优先执行特殊日在此时刻所计划的动作。
  33. 按天执行模式:即以天为单位进行执行,若某日既为普通日和特殊日,则当日一整天优先执行特殊日所计划的动作,普通日计划当日不再执行。)");
  34. m_tipText->hide();
  35. ui->label_Tip->installEventFilter(this);
  36. /* 设置默认值 */
  37. ui->pBtn_defaultPlan->setChecked(true);
  38. ui->rBtn_moment->setChecked(true);
  39. /* 获取今天是周几,设置周几页面 */
  40. int day = QDate::currentDate().dayOfWeek() - 1;
  41. m_vecWeeks[day]->setChecked(true);
  42. ui->stackedWidget_items->setCurrentIndex(day);
  43. /* 连接信号和槽 */
  44. connect(ui->pBtn_addPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnAddExecPlan);
  45. connect(ui->pBtn_importPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_importData);
  46. }
  47. TransmitterSwitch::~TransmitterSwitch()
  48. {
  49. if(m_tipText != nullptr)
  50. {
  51. delete m_tipText;
  52. m_tipText = nullptr;
  53. }
  54. delete ui;
  55. }
  56. /**
  57. * @brief 设置样式表
  58. *
  59. * @param qssPath 样式表文件路径
  60. */
  61. void TransmitterSwitch::setQSS(const QString &qssPath)
  62. {
  63. QFile file(qssPath);
  64. if (!file.open(QFile::ReadOnly))
  65. {
  66. LH_WRITE_ERROR("TransmitterSwitch Open qss file failed: " + qssPath);
  67. return;
  68. }
  69. m_styleSheet = file.readAll();
  70. this->setStyleSheet(m_styleSheet);
  71. file.close();
  72. }
  73. /**
  74. * @brief 设置WebAPI信息
  75. *
  76. * @param url WebAPI地址
  77. * @param serID 数据库ID
  78. * @param serKey 限制的关键字
  79. */
  80. void TransmitterSwitch::setWebAPIInfo(const QString &url, const QString &serverID, const QString &serverKey)
  81. {
  82. if(m_fromWebAPI == nullptr)
  83. {
  84. m_fromWebAPI = new FromWebAPI;
  85. }
  86. if(url.isEmpty() || serverID.isEmpty() || serverKey.isEmpty())
  87. {
  88. LH_WRITE_ERROR("WebAPI info is empty");
  89. return;
  90. }
  91. m_fromWebAPI->initWebApi(url,serverID,serverKey);
  92. /* 获取支持的设备 */
  93. m_fromWebAPI->getDeviceInfo(DeviceContainer.getMapDevice());
  94. }
  95. /* 每周几的按钮点击了,设置stackedWidegt页面 */
  96. void TransmitterSwitch::do_weekpBtn_clicked()
  97. {
  98. auto pBtn = qobject_cast<QPushButton*>(sender());
  99. /* 清除所有选中效果 */
  100. for(const auto& it : m_vecWeeks)
  101. {
  102. if(it != pBtn)
  103. {
  104. it->setChecked(false);
  105. }
  106. }
  107. pBtn->setChecked(true);
  108. auto userData = pBtn->userData(0);
  109. auto pBtnUserData = static_cast<PBtnUserData*>(userData);
  110. if(pBtnUserData == nullptr)
  111. {
  112. return;
  113. }
  114. int index = pBtnUserData->getIndex();
  115. ui->stackedWidget_items->setCurrentIndex(index);
  116. }
  117. /* 点击了添加计划按钮 */
  118. void TransmitterSwitch::do_pBtnAddExecPlan()
  119. {
  120. /* 创建页面,判断是正常日还是特殊日 */
  121. if(ui->stackedWidget_items->currentIndex() < 7)
  122. {
  123. std::shared_ptr<AddNormalItem> atf = std::make_shared<AddNormalItem>(this);
  124. atf->setParentPointer(this);
  125. /* 设置可选项 */
  126. atf->setDevice(DeviceContainer.getMapDevice());
  127. /* 设置是周几 */
  128. int weekDay = ui->stackedWidget_items->currentIndex();
  129. atf->setWeekDay(weekDay);
  130. atf->exec();
  131. /* 判断是否需要添加计划 */
  132. if(atf->isAddDev())
  133. {
  134. /* 添加计划 */
  135. addNormalOneItem(weekDay, atf->getDevName(), atf->getAction(), atf->getTime());
  136. }
  137. }
  138. else
  139. {
  140. /* 特殊日 */
  141. std::shared_ptr<AddSpecialItem> atf = std::make_shared<AddSpecialItem>(this);
  142. atf->setParentPointer(this);
  143. /* 设置可选项 */
  144. atf->setDevice(DeviceContainer.getMapDevice());
  145. /* 设置是周几 */
  146. int weekDay = ui->stackedWidget_items->currentIndex();
  147. atf->setWeekDay(weekDay);
  148. atf->exec();
  149. /* 判断是否需要添加计划 */
  150. if(atf->isAddDev())
  151. {
  152. /* 添加计划 */
  153. addSpecialOneItem(weekDay, atf->getDevName(), atf->getAction(), atf->getDate(), atf->getTime());
  154. }
  155. }
  156. }
  157. /* 删除一项正常日计划 */
  158. void TransmitterSwitch::do_deleteOneItem(int week, int index)
  159. {
  160. /* 删除该项 */
  161. IData.deleteOneItem(week, index);
  162. /* 重新排序 */
  163. sortLayout(week);
  164. }
  165. /* 一个计划修改了设备 */
  166. void TransmitterSwitch::do_changeDev()
  167. {
  168. /* 判断修改设备后时间是否冲突 */
  169. auto one = qobject_cast<OneItem*>(sender());
  170. if(one == nullptr)
  171. {
  172. return;
  173. }
  174. if(one->getWeekDay() > 0 && one->getWeekDay() < 7)
  175. {
  176. if(IData.judgeTimeRepetitionWithEdit(one->getWeekDay(), one, one->getExecTime()))
  177. {
  178. /* 设置时间报警 */
  179. one->setWarningText("设备执行时间冲突", -1);
  180. return;
  181. }
  182. }
  183. else if(one->getWeekDay() == 7)
  184. {
  185. if(IData.judgeDateTimeRepetitionWithEdit(one->getWeekDay(), one, one->getDate(), one->getExecTime()))
  186. {
  187. /* 设置时间报警 */
  188. one->setWarningText("设备执行日期时间冲突", -1);
  189. return;
  190. }
  191. }
  192. /* 取消报警 */
  193. one->hideWarn();
  194. }
  195. /* 点击修改执行时间 */
  196. void TransmitterSwitch::do_editExecTime(QTime t)
  197. {
  198. /* 获取信号发送者 */
  199. auto one = qobject_cast<OneItem*>(sender());
  200. /* 创建时间选择控件 */
  201. std::shared_ptr<TimeWidget> tw = std::make_shared<TimeWidget>(this, TimeWidget::ShowType::Dialog);
  202. /* 设置图标 */
  203. tw->setIcon(":/ICON/ICON/Time.png");
  204. tw->setIconShow(true);
  205. tw->setIconSize(16, 16);
  206. /* 重新设置大小 */
  207. tw->setEditLine(one->getExecTimeSize().width(), one->getExecTimeSize().height());
  208. /* 设置选择框大小 */
  209. tw->setTimeAreaWidth(140);
  210. /* 移动位置,覆盖显示时间的按钮,获取的坐标是相对于Dialog的位置 */
  211. auto pos = one->mapTo(this, one->getExecTimePos());
  212. tw->move(pos);
  213. /* 设置默认的时间 */
  214. tw->setTime(t);
  215. tw->execShow();
  216. auto time = tw->getTime();
  217. /* 判断时间有没有修改 */
  218. if(time == t)
  219. {
  220. return;
  221. }
  222. LH_WRITE_LOG_DEBUG(QString("选择时间:%1").arg(time.toString("hh:mm:ss")));
  223. one->setExecTime(time);
  224. /* 判断时间是否重复 */
  225. if(IData.judgeTimeRepetitionWithEdit(one->getWeekDay(), one, time))
  226. {
  227. /* 设置时间报警 */
  228. one->setWarningText("设备执行时间冲突", -1);
  229. return;
  230. }
  231. /* 取消报警 */
  232. one->hideWarn();
  233. /* 重新排序 */
  234. sortLayout(one->getWeekDay());
  235. }
  236. /* 导入数据 */
  237. void TransmitterSwitch::do_importData()
  238. {
  239. QList<ExecPlanItemInfo> list;
  240. m_fromWebAPI->getExecPlanData(list);
  241. }
  242. /* 创建一周8天的item页面 */
  243. void TransmitterSwitch::createWeekWidget()
  244. {
  245. /* 将8个按钮的指针存入到数组中,方便后续使用 */
  246. m_vecWeeks.push_back(ui->pBtn_Monday);
  247. m_vecWeeks.push_back(ui->pBtn_Tuesday);
  248. m_vecWeeks.push_back(ui->pBtn_Wednesday);
  249. m_vecWeeks.push_back(ui->pBtn_Thursday);
  250. m_vecWeeks.push_back(ui->pBtn_Friday);
  251. m_vecWeeks.push_back(ui->pBtn_Saturday);
  252. m_vecWeeks.push_back(ui->pBtn_Sunday);
  253. m_vecWeeks.push_back(ui->pBtn_SpecialDay);
  254. for(const auto& it : m_vecWeeks)
  255. {
  256. /* 设置每周的按钮可点击 */
  257. it->setCheckable(true);
  258. connect(it,&QPushButton::clicked,this,&TransmitterSwitch::do_weekpBtn_clicked);
  259. }
  260. /* 清空stackedWidget页面 */
  261. int wcount = ui->stackedWidget_items->count();
  262. for(int i = 0; i < wcount; ++i)
  263. {
  264. auto widgetItems = ui->stackedWidget_items->widget(i);
  265. ui->stackedWidget_items->removeWidget(widgetItems);
  266. delete widgetItems;
  267. }
  268. /* 创建Widget页面 */
  269. for(int i = 0; i < 7; ++i)
  270. {
  271. auto widgetItems = new WidgetItems(this);
  272. m_vecWidgetItems.push_back(widgetItems);
  273. ui->stackedWidget_items->addWidget(widgetItems);
  274. /* 设置正常日 */
  275. widgetItems->setDayType(false);
  276. /* 获取layout,这个才是存储item的区域 */
  277. auto layout = widgetItems->getLayout();
  278. m_vecLayouts.push_back(layout);
  279. /* 给按钮设置用户数据 */
  280. auto pBtnUserData = new PBtnUserData();
  281. pBtnUserData->setData(widgetItems);
  282. pBtnUserData->setIndex(i);
  283. m_vecWeeks[i]->setUserData(0, pBtnUserData);
  284. }
  285. /* 创建特殊日 */
  286. auto widgetItems = new WidgetItems(this);
  287. m_vecWidgetItems.push_back(widgetItems);
  288. ui->stackedWidget_items->addWidget(widgetItems);
  289. /* 设置特殊日 */
  290. widgetItems->setDayType(true);
  291. /* 获取layout,这个才是存储item的区域 */
  292. auto layout = widgetItems->getLayout();
  293. m_vecLayouts.push_back(layout);
  294. /* 给按钮设置用户数据 */
  295. auto pBtnUserData = new PBtnUserData();
  296. pBtnUserData->setData(widgetItems);
  297. pBtnUserData->setIndex(7);
  298. m_vecWeeks[7]->setUserData(0, pBtnUserData);
  299. // LH_WRITE_LOG("StackedWidget count: " + QString::number(ui->stackedWidget_items->count()));
  300. }
  301. /* 添加一个正常日的计划 */
  302. void TransmitterSwitch::addNormalOneItem(int week, QString devName, QString action, QTime execTime)
  303. {
  304. OneItem* one = new OneItem();
  305. /* 添加可选的设备 */
  306. one->addDevice();
  307. /* 设置最小高度 */
  308. // one->setMinimumHeight(48);
  309. one->setDevName(devName);
  310. one->setExecTime(execTime);
  311. one->setWeekDay(week);
  312. /* 连接删除项信号,执行时间改变信号 */
  313. connect(one, &OneItem::signal_OneItemDelete, this, &TransmitterSwitch::do_deleteOneItem);
  314. connect(one, &OneItem::signal_devChanged, this, &TransmitterSwitch::do_changeDev);
  315. connect(one, &OneItem::signal_execTimeClicked, this, &TransmitterSwitch::do_editExecTime);
  316. /* 添加到容器中 */
  317. IData.addOneItem(week, one);
  318. /* 重新排序 */
  319. sortLayout(week);
  320. }
  321. /* 添加一项特殊日计划 */
  322. void TransmitterSwitch::addSpecialOneItem(int week, QString devName, QString action, QDate date, QTime execTime)
  323. {
  324. }
  325. /* 重新排序布局 */
  326. void TransmitterSwitch::sortLayout(int weekDay)
  327. {
  328. if(weekDay < 7 && weekDay >= 0)
  329. {
  330. sortNormalDayData(weekDay);
  331. }else if(weekDay == 7)
  332. {
  333. sortSpecialDayData();
  334. }
  335. /* 重新布局 */
  336. sortLayoutUI(weekDay);
  337. }
  338. /* 排序正常日 */
  339. void TransmitterSwitch::sortNormalDayData(int weekDay)
  340. {
  341. /* 获取当前页容器 */
  342. auto list = IData.getOneDay(weekDay);
  343. // LH_WRITE_LOG_DEBUG(QString("获取到的容器大小:%1").arg(list->size()));
  344. if(list == nullptr)
  345. {
  346. return;
  347. }
  348. /* 将当前页,按时间升序排序 */
  349. std::sort(list->begin(), list->end(), [&](OneItem* t1, OneItem* t2)
  350. {
  351. /* 按照日期排序,再按照名称排序 */
  352. if(t1->getDate() < t2->getDate())
  353. {
  354. return true;
  355. }
  356. else if(t1->getDate() > t2->getDate())
  357. {
  358. return false;
  359. }
  360. else
  361. {
  362. if(t1->getExecTime() < t2->getExecTime())
  363. {
  364. return true;
  365. }
  366. else if(t1->getExecTime() > t2->getExecTime())
  367. {
  368. return false;
  369. }else
  370. {
  371. return t1->getDevName() < t2->getDevName();
  372. }
  373. }
  374. });
  375. /* 设置序号 */
  376. int num1 = 1;
  377. for(auto& it : *list)
  378. {
  379. it->setNum(num1);
  380. num1++;
  381. }
  382. }
  383. /* 排序特殊日 */
  384. void TransmitterSwitch::sortSpecialDayData()
  385. {
  386. }
  387. /* 重新布局项 */
  388. void TransmitterSwitch::sortLayoutUI(int weekDay)
  389. {
  390. /* 获取数据列表和layout */
  391. auto listItem = IData.getOneDay(weekDay);
  392. if(listItem == nullptr)
  393. {
  394. return;
  395. }
  396. auto layout = m_vecLayouts[weekDay];
  397. /* 刷新UI,先清空layout中的所有控件,就是将item的父指针设置为0 */
  398. int num1 = 0;
  399. for(auto& it : *listItem)
  400. {
  401. it->setParent(nullptr);
  402. }
  403. /* 将item重新加入到layout中 */
  404. for(auto& it : *listItem)
  405. {
  406. layout->addWidget(it);
  407. }
  408. }
  409. /* 事件过滤器 */
  410. bool TransmitterSwitch::eventFilter(QObject *watched, QEvent *event)
  411. {
  412. if(watched == ui->label_Tip)
  413. {
  414. if(event->type() == QEvent::Enter)
  415. {
  416. m_tipText->show();
  417. return true;
  418. }else if(event->type() == QEvent::Leave)
  419. {
  420. m_tipText->hide();
  421. }
  422. }
  423. return QWidget::eventFilter(watched,event);
  424. }