templatemanager.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #include "templatemanager.h"
  2. #include "previewplan.h"
  3. #include "ui_templatemanager.h"
  4. #include <QDebug>
  5. #include <QPoint>
  6. #include <QTableWidgetItem>
  7. #include <QFile>
  8. #include <QPainter>
  9. #include <QMouseEvent>
  10. #include <memory>
  11. #include <QLineEdit>
  12. #include "warning/warning.h"
  13. #include "LHQLogAPI.h"
  14. #include "OneShadowEffect.h"
  15. #include "TransmitterSwitchInfo.h"
  16. #include "UIStyleManager.h"
  17. #include "template.h"
  18. #include "managerplan.h"
  19. #include "FromWebAPI.h"
  20. #include "tipwidget.h"
  21. #include "previewplan.h"
  22. #include "FromSQLite.h"
  23. TemplateManager::TemplateManager(QWidget *parent) :
  24. QDialog(parent),
  25. ui(new Ui::TemplateManager)
  26. {
  27. ui->setupUi(this);
  28. /* 设置隐藏边框 */
  29. this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
  30. /* 设置底层样式表 */
  31. this->setAttribute(Qt::WA_TranslucentBackground);
  32. /* 创建阴影 */
  33. QSize size = this->size();
  34. size.setWidth(size.width() - 40);
  35. size.setHeight(size.height() - 40);
  36. auto pShadow = new OneShadowEffect(this);
  37. this->setGraphicsEffect(pShadow);
  38. /* 获取管理员类型 */
  39. eUserPermission userPermission = GInfo.getUserPermission();
  40. if(userPermission == eUserPermission::User_Administrator)
  41. {
  42. /* 管理员权限 */
  43. m_columnCount = 5; // 模版名称、模版频率、预览、修改、删除
  44. }
  45. else if(userPermission == eUserPermission::User_Normal)
  46. {
  47. /* 普通用户权限 */
  48. m_columnCount = 3; // 模版名称、模版频率、预览
  49. }
  50. initTableWidget(m_columnCount);
  51. connect(ui->pBtn_close,SIGNAL(clicked()),this,SLOT(close()));
  52. connect(ui->pBtn_cancel,SIGNAL(clicked()),this,SLOT(close()));
  53. connect(ui->pBtn_ok,SIGNAL(clicked()),this,SLOT(do_ok()));
  54. connect(ui->tableWidget, &QTableWidget::cellClicked, this, &TemplateManager::do_clickedItem);
  55. connect(ui->tableWidget, &QTableWidget::itemChanged, this, &TemplateManager::do_itemChanged);
  56. /* 注册事件过滤器 */
  57. ui->pBtn_close->installEventFilter(this);
  58. }
  59. TemplateManager::~TemplateManager()
  60. {
  61. delete ui;
  62. }
  63. void TemplateManager::do_ok()
  64. {
  65. /* 获取已选中的模版列表 */
  66. m_isOk = true;
  67. this->close();
  68. }
  69. /* 点击了一个单元格 */
  70. void TemplateManager::do_clickedItem(int row, int column)
  71. {
  72. // LH_WRITE_LOG_DEBUG(QString("点击了单元格: %1, %2").arg(row).arg(column));
  73. if(column < 2)
  74. {
  75. return;
  76. }
  77. /* 获取此单元格 */
  78. auto item = ui->tableWidget->item(row, column);
  79. if(item == nullptr)
  80. {
  81. return;
  82. }
  83. /* 判断是什么功能的单元格 */
  84. if(column == 2)
  85. {
  86. /* 预览 */
  87. previewTemplate(item);
  88. }
  89. else if(column == 3)
  90. {
  91. /* 修改 */
  92. modifyTemplate(item);
  93. }
  94. else if(column == 4)
  95. {
  96. /* 删除 */
  97. deleteTemplate(item);
  98. }
  99. // else if(column == 1)
  100. // {
  101. // /* 限制QLineEdit字数 */
  102. // QLineEdit* editor = qobject_cast<QLineEdit*>(ui->tableWidget->indexWidget(ui->tableWidget->model()->index(row, column)));
  103. // if (editor) {
  104. // editor->setMaxLength(5); // 设置最大输入长度为 15
  105. // }
  106. // }
  107. /* 强制重新绘制表格 */
  108. ui->tableWidget->repaint();
  109. }
  110. /* 单元格内容改变了 */
  111. void TemplateManager::do_itemChanged(QTableWidgetItem* item)
  112. {
  113. /* 获取新模版名称 */
  114. QString newName = item->text();
  115. /* 获取旧模版名称 */
  116. OneTemplateInfo info;
  117. info.templateName = item->data(m_roleTemplateName).toString();
  118. info.channelInfo.ChannelID = item->data(m_roleChnID).toInt();
  119. /* 判断是否修改了模版名称 */
  120. if(newName == info.templateName)
  121. {
  122. return;
  123. }
  124. /* 判断新的名称是否为空 */
  125. if(newName.isEmpty())
  126. {
  127. QString nowName = item->data(m_roleTemplateNameNow).toString();
  128. item->setText(nowName);
  129. return;
  130. }
  131. /* 判断同频率下的模板名称是否冲突 */
  132. int rowCount = ui->tableWidget->rowCount();
  133. for(int i = 0; i < rowCount; i++)
  134. {
  135. /* 排除当前项 */
  136. if(i == item->row())
  137. {
  138. continue;
  139. }
  140. /* 获取当前项显示的名称 */
  141. auto itemTmp = ui->tableWidget->item(i, 1);
  142. if(itemTmp == nullptr)
  143. {
  144. continue;
  145. }
  146. /* 获取当前项的模版名称 */
  147. QString strName = itemTmp->text();
  148. /* 获取当前项的模版频率 */
  149. int chnID = itemTmp->data(m_roleChnID).toInt();
  150. /* 判断是否冲突 */
  151. if(chnID == info.channelInfo.ChannelID && strName == newName)
  152. {
  153. /* 已经存在相同的模版名称 */
  154. LH_WRITE_ERROR(QString("模版名称冲突:%1").arg(newName));
  155. TipWidget::display(TipWidget::OPERATOR_FAIL, "模版名称冲突", this);
  156. item->setText(info.templateName);
  157. return;
  158. }
  159. }
  160. /* 修改模版名称 */
  161. m_mapModifyTemplateName.insert(info, newName);
  162. item->setData(m_roleTemplateNameNow, newName);
  163. }
  164. /* 显示事件 */
  165. void TemplateManager::showEvent(QShowEvent *event)
  166. {
  167. /* 根据显示的列数计算每列的宽度 */
  168. int editColum = m_columnCount -2;
  169. /* 设置列宽度 */
  170. int width = (ui->tableWidget->width() - ( 66 * editColum)) / 2;
  171. ui->tableWidget->setColumnWidth(0, width);
  172. ui->tableWidget->setColumnWidth(1, width);
  173. for(int i = 2; i < m_columnCount; i++)
  174. {
  175. ui->tableWidget->setColumnWidth(i, 66);
  176. }
  177. }
  178. /* 设置模版列表 */
  179. void TemplateManager::setTemplateList(const QMultiMap<int, OneTemplateInfo>& mapTemplate)
  180. {
  181. // 暂时阻止 itemChanged 信号
  182. ui->tableWidget->blockSignals(true);
  183. for(auto it = mapTemplate.begin(), end = mapTemplate.end(); it != end; it++)
  184. {
  185. createRow(it.value());
  186. m_listTemplate.append(it.value());
  187. }
  188. // 恢复信号
  189. ui->tableWidget->blockSignals(false);
  190. }
  191. /* 设置QSS */
  192. void TemplateManager::setQSSPath(const QString& qssPath)
  193. {
  194. if(qssPath.isEmpty())
  195. {
  196. return;
  197. }
  198. QString qssFile = qssPath + "/templatemanager.qss";
  199. QFile file(qssFile);
  200. if(file.open(QFile::ReadOnly))
  201. {
  202. QString styleSheet = file.readAll();
  203. this->setStyleSheet(styleSheet);
  204. file.close();
  205. }else
  206. {
  207. LH_WRITE_ERROR(QString("Open %1 failed").arg(qssFile));
  208. }
  209. // if(EPUIStyle.getUIStyle() == enum_UIStyle::UI_Dark)
  210. // {
  211. // /* 手动设置表头的qss */
  212. // ui->tableWidget->horizontalHeader()->setStyleSheet(m_qssHeaderView_dark);
  213. // }else {
  214. // ui->tableWidget->horizontalHeader()->setStyleSheet(m_qssHeaderView_dark);
  215. // }
  216. }
  217. /* 设置WebAPI指针 */
  218. void TemplateManager::setWebAPI(FromWebAPI* webAPI)
  219. {
  220. if(webAPI == nullptr)
  221. {
  222. LH_WRITE_ERROR("WebAPI is nullptr");
  223. return;
  224. }
  225. m_fromWebAPI = webAPI;
  226. /* 设置FromSQLite指针为nullptr */
  227. m_fromSQLite = nullptr;
  228. }
  229. /* 设置FromSQLite指针 */
  230. void TemplateManager::setFromSQLite(FromSQLite* sqlite)
  231. {
  232. if(sqlite == nullptr)
  233. {
  234. LH_WRITE_ERROR("SQLite is nullptr");
  235. return;
  236. }
  237. m_fromSQLite = sqlite;
  238. /* 设置WebAPI指针为nullptr */
  239. m_fromWebAPI = nullptr;
  240. }
  241. /* 初始化表格 */
  242. void TemplateManager::initTableWidget(int columnCount)
  243. {
  244. /* 设置列数 */
  245. ui->tableWidget->horizontalHeader()->setVisible(true);
  246. ui->tableWidget->setColumnCount(columnCount);
  247. /* 设置列表头 */
  248. QStringList headerList = {"频率名称", "模版名称", "", "", ""};
  249. ui->tableWidget->setHorizontalHeaderLabels(headerList);
  250. ui->tableWidget->horizontalHeader()->setSectionsClickable(false);
  251. ui->tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
  252. /* 设置列表头高度 */
  253. ui->tableWidget->horizontalHeader()->setDefaultSectionSize(40);
  254. /* 设置列宽间距,在显示事件中设置 */
  255. /* 设置列宽度固定 */
  256. ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
  257. ui->tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
  258. ui->tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
  259. //设置行高
  260. ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
  261. /* 设置可编辑,后续创建的时候,单独设置不可编辑 */
  262. ui->tableWidget->setEditTriggers(QTableWidget::DoubleClicked);
  263. //设置选中一行
  264. ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
  265. //设置只能选中一行
  266. ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  267. //隐藏横滚动条
  268. ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  269. //隐藏网格线
  270. ui->tableWidget->setShowGrid(false);
  271. //隐藏行号
  272. ui->tableWidget->verticalHeader()->setVisible(false);
  273. //设置不显示选中后的虚线
  274. ui->tableWidget->setFocusPolicy(Qt::NoFocus);
  275. /* 设置第二列输入字数限制 */
  276. LineEditDelegate* delegate = new LineEditDelegate(15, this);
  277. ui->tableWidget->setItemDelegateForColumn(1, delegate);
  278. //开启排序功能
  279. // ui->tableWidget->setSortingEnabled(true);
  280. }
  281. /* 添加一行 */
  282. void TemplateManager::createRow(const OneTemplateInfo& info)
  283. {
  284. /* 设置表格的行数 */
  285. int row = ui->tableWidget->rowCount();
  286. ui->tableWidget->setRowCount(row + 1);
  287. /* 设置行高 */
  288. ui->tableWidget->setRowHeight(row, 40);
  289. /* 频率名称 */
  290. QTableWidgetItem* item0 = new QTableWidgetItem(info.channelInfo.ChannelName);
  291. item0->setFlags(item0->flags() & ~Qt::ItemIsEditable);
  292. item0->setData(m_roleChnID, info.channelInfo.ChannelID);
  293. ui->tableWidget->setItem(row, 0, item0);
  294. /* 模板名称,需要可编辑 */
  295. QTableWidgetItem* item1 = new QTableWidgetItem(info.templateName, Qt::EditRole);
  296. item1->setFlags(item1->flags() | Qt::ItemIsEditable);
  297. item1->setData(m_roleChnID, info.channelInfo.ChannelID);
  298. item1->setData(m_roleTemplateName, info.templateName);
  299. item1->setData(m_roleTemplateNameNow, info.templateName);
  300. ui->tableWidget->setItem(row, 1, item1);
  301. /* 限制输入框的字数 */
  302. // ui->tableWidget->openPersistentEditor(item1);
  303. // QLineEdit* editor = qobject_cast<QLineEdit*>(ui->tableWidget->indexWidget(ui->tableWidget->model()->index(row, 1)));
  304. // if (editor) {
  305. // editor->setMaxLength(15); // 设置最大输入长度为 15
  306. // }
  307. /* 添加固定的三个项 */
  308. auto item2 = new QTableWidgetItem("预览");
  309. item2->setFlags(item0->flags() & ~Qt::ItemIsEditable);
  310. item2->setData(m_roleChnID, info.channelInfo.ChannelID);
  311. item2->setData(m_roleTemplateName, info.templateName);
  312. item2->setForeground(QBrush("#438EFF"));
  313. ui->tableWidget->setItem(row, 2, item2);
  314. auto item3 = new QTableWidgetItem("修改");
  315. item3->setFlags(item0->flags() & ~Qt::ItemIsEditable);
  316. item3->setData(m_roleChnID, info.channelInfo.ChannelID);
  317. item3->setData(m_roleTemplateName, info.templateName);
  318. item3->setForeground(QBrush("#438EFF"));
  319. ui->tableWidget->setItem(row, 3, item3);
  320. auto item4 = new QTableWidgetItem("删除");
  321. item4->setFlags(item0->flags() & ~Qt::ItemIsEditable);
  322. item4->setData(m_roleChnID, info.channelInfo.ChannelID);
  323. item4->setData(m_roleTemplateName, info.templateName);
  324. item4->setForeground(QBrush("#438EFF"));
  325. ui->tableWidget->setItem(row, 4, item4);
  326. }
  327. /* 修改模版 */
  328. void TemplateManager::modifyTemplate(QTableWidgetItem* item)
  329. {
  330. /* 获取频率 */
  331. OneTemplateInfo info;
  332. info.templateName = item->data(m_roleTemplateName).toString();
  333. /* 获取频率名称 */
  334. info.channelInfo = ChnContainer.getChannel(item->data(m_roleChnID).toInt());
  335. /* 获取模版中的计划 */
  336. bool isSuccess = true;
  337. QList<OnePlanItemInfo> nowListPlan;
  338. if(m_fromWebAPI != nullptr)
  339. {
  340. isSuccess = m_fromWebAPI->getOneTemplateData(info, nowListPlan);
  341. }
  342. else if(m_fromSQLite != nullptr)
  343. {
  344. isSuccess = m_fromSQLite->getTemplateData(info, nowListPlan);
  345. }
  346. if(!isSuccess)
  347. {
  348. TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版计划失败", this);
  349. return;
  350. }
  351. LH_WRITE_LOG_DEBUG(QString("获取模版计划成功, 频率ID:%1, 模版名称:%2, 计划数:%3").arg(info.channelInfo.ChannelID).arg(info.templateName).arg(nowListPlan.size()));
  352. /* 弹出修改模版的窗口 */
  353. std::shared_ptr<ManagerPlan> mp = std::make_shared<ManagerPlan>(Enum_Mode::Mode_ModifyTemplate);
  354. mp->setFrequencyID(info.channelInfo);
  355. mp->setPlanList(nowListPlan);
  356. mp->exec();
  357. /* 判断是否点击了OK */
  358. if(!mp->isOK())
  359. {
  360. return;
  361. }
  362. /* 获取计划信息 */
  363. auto& mapPlanInfo = mp->getPlanInfo();
  364. QList<OnePlanItemInfo> newListPlan;
  365. /* 设置该频率的计划 */
  366. for(auto it = mapPlanInfo.begin(), end = mapPlanInfo.end(); it != end; it++)
  367. {
  368. if(it.key() != info.channelInfo.ChannelID)
  369. {
  370. continue;
  371. }
  372. for(auto& it1 : it.value())
  373. {
  374. OnePlanItemInfo tmp;
  375. tmp.ChannelID = info.channelInfo.ChannelID;
  376. tmp.ChannelName = info.channelInfo.ChannelName;
  377. tmp.onWeekDay = it1.onWeekDay;
  378. tmp.onDateTime = it1.onDateTime;
  379. tmp.offWeekDay = it1.offWeekDay;
  380. tmp.offDateTime = it1.offDateTime;
  381. newListPlan.append(tmp);
  382. }
  383. }
  384. m_mapModifyTemplate.insert(info, newListPlan);
  385. }
  386. /* 删除模版 */
  387. void TemplateManager::deleteTemplate(QTableWidgetItem* item)
  388. {
  389. /* 弹出删除模版的提示框 */
  390. Warning w(this);
  391. w.setQSS(EPUIStyle.getQSSPath());
  392. w.setText("确定删除对应频率开关机计划?");
  393. w.exec();
  394. if(!w.isOk())
  395. {
  396. return;
  397. }
  398. /* 删除 */
  399. OneTemplateInfo info;
  400. info.channelInfo.ChannelID = item->data(m_roleChnID).toInt();
  401. info.templateName = item->data(m_roleTemplateName).toString();
  402. /* 将模版信息添加到删除列表 */
  403. m_listDeleteTemplate.append(info);
  404. /* 删除当前行 */
  405. ui->tableWidget->removeRow(item->row());
  406. m_listTemplate.removeOne(info);
  407. }
  408. /* 预览 */
  409. void TemplateManager::previewTemplate(QTableWidgetItem* item)
  410. {
  411. /* 获取频率 */
  412. OneTemplateInfo info;
  413. info.templateName = item->data(m_roleTemplateName).toString();
  414. /* 获取频率名称 */
  415. info.channelInfo = ChnContainer.getChannel(item->data(m_roleChnID).toInt());
  416. /* 获取模版中的计划 */
  417. QList<OnePlanItemInfo> nowListPlan;
  418. bool isSuccess = true;
  419. /* 判断是否是在线模式 */
  420. if(m_fromWebAPI != nullptr)
  421. {
  422. isSuccess = m_fromWebAPI->getOneTemplateData(info, nowListPlan);
  423. }
  424. else if(m_fromSQLite != nullptr)
  425. {
  426. isSuccess = m_fromSQLite->getTemplateData(info, nowListPlan);
  427. }
  428. if(!isSuccess)
  429. {
  430. TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版计划失败", this);
  431. return;
  432. }
  433. std::shared_ptr<PreviewPlan> pp = std::make_shared<PreviewPlan>(this);
  434. pp->setQSSPath(EPUIStyle.getQSSPath());
  435. pp->setFrequencyInfo(info.channelInfo);
  436. pp->setTemplateList(nowListPlan);
  437. pp->exec();
  438. }
  439. /* 事件过滤器 */
  440. bool TemplateManager::eventFilter(QObject *watched, QEvent *event)
  441. {
  442. if(watched == ui->pBtn_close)
  443. {
  444. if(event->type() == QEvent::Enter)
  445. {
  446. ui->pBtn_close->setProperty("Hover", true);
  447. ui->pBtn_close->style()->unpolish(ui->pBtn_close);
  448. ui->pBtn_close->style()->polish(ui->pBtn_close);
  449. return true;
  450. }else if(event->type() == QEvent::Leave)
  451. {
  452. ui->pBtn_close->setProperty("Hover", false);
  453. ui->pBtn_close->style()->unpolish(ui->pBtn_close);
  454. ui->pBtn_close->style()->polish(ui->pBtn_close);
  455. return true;
  456. }
  457. }
  458. return QWidget::eventFilter(watched,event);
  459. }
  460. /* 鼠标点击事件 */
  461. void TemplateManager::mousePressEvent(QMouseEvent *event)
  462. {
  463. m_lastPos = event->globalPos();
  464. event->accept();
  465. }
  466. /* 鼠标移动事件 */
  467. void TemplateManager::mouseMoveEvent(QMouseEvent *event)
  468. {
  469. // QRect rect = this->geometry();
  470. // rect.setBottom(rect.top()+50);
  471. auto point = ui->widget_Top->mapToGlobal(QPoint(0, 0));
  472. QRect rect(point, ui->widget_Top->size());
  473. if(!rect.contains(m_lastPos))
  474. {
  475. event->accept();
  476. return;
  477. }
  478. int dx = event->globalX() - m_lastPos.x();
  479. int dy = event->globalY() - m_lastPos.y();
  480. move(x()+dx, y()+dy);
  481. m_lastPos = event->globalPos();
  482. event->accept();
  483. }
  484. /* 鼠标释放事件 */
  485. void TemplateManager::mouseReleaseEvent(QMouseEvent *event)
  486. {
  487. event->accept();
  488. }