dialog.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. #include "dialog.h"
  2. #include "ui_dialog.h"
  3. #include <QMessageBox>
  4. #include <QDateTime>
  5. #include <QList>
  6. #include <QKeyEvent>
  7. #ifndef NEW
  8. #define NEW new(std::nothrow)
  9. #endif
  10. // 报警个数
  11. int g_nInidex = 1;
  12. // 界面显示的最大报警个数
  13. const int g_nMaxDisplayAlarmNum = 200;
  14. // 设备断线通知回调函数
  15. void CALLBACK DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
  16. {
  17. if (0 != dwUser)
  18. {
  19. Dialog* pDialog = (Dialog*)dwUser;
  20. pDialog->setWindowTitle(pDialog->tr("Network disconnected"));
  21. }
  22. }
  23. // 设备重连上后通知回调函数
  24. void CALLBACK ReConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
  25. {
  26. if (0 != dwUser)
  27. {
  28. Dialog* pDialog = (Dialog*)dwUser;
  29. pDialog->setWindowTitle(pDialog->tr("Alarm"));
  30. }
  31. }
  32. // 报警消息回调函数
  33. BOOL CALLBACK MessCallBack(LONG lCommand, LLONG lLoginID, char *pBuf, DWORD dwBufLen, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
  34. {
  35. if(0 == dwUser)
  36. {
  37. return false;
  38. }
  39. switch(lCommand)
  40. {
  41. case DH_ALARM_ALARM_EX: // 0x2101 // 外部报警
  42. case DH_MOTION_ALARM_EX: // 0x2102 // 动态检测
  43. case DH_VIDEOLOST_ALARM_EX: // 0x2103 // 视频丢失
  44. case DH_SHELTER_ALARM_EX: // 0x2104 // 视频遮挡
  45. case DH_DISKFULL_ALARM_EX: // 0x2106 // 硬盘满
  46. case DH_DISKERROR_ALARM_EX: // 0x2107 // 硬盘坏
  47. {
  48. Dialog* pDialog = (Dialog*)dwUser;
  49. pDialog->SetAlarmMessage(lCommand, pBuf, dwBufLen);
  50. }
  51. }
  52. return true;
  53. }
  54. Dialog::Dialog(QWidget *parent) :
  55. QDialog(parent),
  56. ui(new Ui::Dialog)
  57. {
  58. ui->setupUi(this);
  59. m_lLoginId = 0;
  60. m_bSubcribe = false;
  61. InitWidget();
  62. InitNetsdk();
  63. }
  64. Dialog::~Dialog()
  65. {
  66. UnInit();
  67. delete ui;
  68. }
  69. void Dialog::keyPressEvent(QKeyEvent* event)
  70. {
  71. switch(event->key())
  72. {
  73. case Qt::Key_Escape:
  74. break;
  75. case Qt::Key_Enter:
  76. break;
  77. default:
  78. QDialog::keyPressEvent(event);
  79. }
  80. }
  81. void Dialog::InitWidget()
  82. {
  83. this->setWindowTitle("Alarm");
  84. // 设置不可以拖动窗口大小
  85. setFixedSize(this->width(), this->height());
  86. // IP控件只可以输入数字和点
  87. QRegExp reqxIP("[0-9.]+$");
  88. ui->IP_lineEdit->setValidator(NEW QRegExpValidator(reqxIP, ui->IP_lineEdit));
  89. // 端口控件只可以输入数字
  90. QRegExp reqxPoet("[0-9]+$");
  91. ui->Port_lineEdit->setValidator(NEW QRegExpValidator(reqxPoet, ui->Port_lineEdit));
  92. // 密码控件属性设置为数字
  93. ui->Password_lineEdit->setEchoMode(QLineEdit::Password);
  94. // 设置初值
  95. ui->IP_lineEdit->setText("10.34.3.158");
  96. ui->Port_lineEdit->setText("37777");
  97. ui->Name_lineEdit->setText("admin");
  98. ui->Password_lineEdit->setText("admin");
  99. //设置表头
  100. m_Model.setHorizontalHeaderItem(LISTCOLUMN_INDEX, NEW QStandardItem(QObject::tr(" Index")));
  101. m_Model.setHorizontalHeaderItem(LISTCOLUMN_TIME, NEW QStandardItem(QObject::tr("Time")));
  102. m_Model.setHorizontalHeaderItem(LISTCOLUMN_CHANNEL, NEW QStandardItem(QObject::tr("Channel")));
  103. m_Model.setHorizontalHeaderItem(LISTCOLUMN_ALARM_MESSAGE, NEW QStandardItem(QObject::tr("Alarm Message")));
  104. ui->tableView->setModel(&m_Model);
  105. //设置表头宽度
  106. ui->tableView->setColumnWidth(LISTCOLUMN_INDEX, 60);
  107. ui->tableView->setColumnWidth(LISTCOLUMN_TIME, 180);
  108. ui->tableView->setColumnWidth(LISTCOLUMN_CHANNEL, 70);
  109. ui->tableView->setColumnWidth(LISTCOLUMN_ALARM_MESSAGE, 240);
  110. ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
  111. ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
  112. ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
  113. ui->StartListen_pushButton->setEnabled(false);
  114. }
  115. void Dialog::InitNetsdk()
  116. {
  117. CLIENT_Init(DisConnectFunc, (LDWORD)this);
  118. LOG_SET_PRINT_INFO stLogPrintInfo = {sizeof(stLogPrintInfo)};
  119. CLIENT_LogOpen(&stLogPrintInfo);
  120. CLIENT_SetAutoReconnect(ReConnectFunc, (LDWORD)this);
  121. // 设置报警回调函数
  122. CLIENT_SetDVRMessCallBack(MessCallBack, (LDWORD)this);
  123. }
  124. void Dialog::UnInit()
  125. {
  126. if (0 != m_lLoginId)
  127. {
  128. on_Login_pushButton_clicked();
  129. }
  130. m_listAlarmInfo.clear();
  131. CLIENT_Cleanup();
  132. }
  133. void Dialog::ConvertAlarmType2String(int nType, bool status, QString& AlarmType)
  134. {
  135. switch(nType)
  136. {
  137. case DH_ALARM_ALARM_EX: // 0x2101 // 外部报警
  138. AlarmType = tr("External alarm");
  139. break;
  140. case DH_MOTION_ALARM_EX: // 0x2102 // 动态检测
  141. AlarmType = tr("Motion detection alarm");
  142. break;
  143. case DH_VIDEOLOST_ALARM_EX: // 0x2103 // 视频丢失
  144. AlarmType = tr("Vedio lose alarm");
  145. break;
  146. case DH_SHELTER_ALARM_EX: // 0x2104 // 视频遮挡
  147. AlarmType = tr("Camera masking alarm");
  148. break;
  149. case DH_DISKFULL_ALARM_EX: // 0x2106 // 硬盘满
  150. AlarmType = tr("Disk full alarm");
  151. break;
  152. case DH_DISKERROR_ALARM_EX: // 0x2107 // 硬盘坏
  153. AlarmType = tr("Disk error alarm");
  154. break;
  155. default:
  156. break;
  157. }
  158. if(status)
  159. {
  160. AlarmType+=tr(" begin");
  161. }
  162. else
  163. {
  164. AlarmType+=tr(" end");
  165. }
  166. }
  167. void Dialog::ShowAlarmInfoInTableView(AlarmInfo stAlarmInfo, bool bAlarmStatus)
  168. {
  169. if(!m_bSubcribe)
  170. {
  171. return;
  172. }
  173. if(g_nInidex >= g_nMaxDisplayAlarmNum)
  174. {
  175. int nIndex = m_Model.rowCount();
  176. m_Model.removeRow(nIndex-1);
  177. }
  178. QString strAlarmType = "";
  179. QString strChannel = "";
  180. QString strIndex = "";
  181. QString strTime = "";
  182. strChannel.setNum(stAlarmInfo.nChannel+1);
  183. strIndex.setNum(g_nInidex);
  184. ConvertAlarmType2String(stAlarmInfo.nType, bAlarmStatus, strAlarmType);
  185. QDateTime currentTime = QDateTime::currentDateTime();
  186. strTime = currentTime.toString("yyyy-MM-dd hh:mm:ss:zzz");
  187. QList<QStandardItem*> listItem;
  188. listItem<<NEW QStandardItem(strIndex)<<NEW QStandardItem(strTime)<<NEW QStandardItem(strChannel)<<NEW QStandardItem(strAlarmType);
  189. m_Model.insertRow(0, listItem);
  190. g_nInidex++;
  191. }
  192. bool Dialog::FindAlarmInList(int nType, int nChannel, bool isDelete)
  193. {
  194. std::list<AlarmInfo>::iterator iter;
  195. for(iter = m_listAlarmInfo.begin(); iter != m_listAlarmInfo.end();iter++)
  196. {
  197. if(nType == iter->nType && nChannel == iter->nChannel)
  198. {
  199. if(isDelete)
  200. {
  201. m_listAlarmInfo.erase(iter);
  202. }
  203. return true;
  204. }
  205. }
  206. return false;
  207. }
  208. void Dialog::SetAlarmMessage(int nType, char* pBuf, int nSize)
  209. {
  210. if(NULL == pBuf || 0 >= nSize)
  211. {
  212. return;
  213. }
  214. for(int i =0; i< nSize; i++)
  215. {
  216. // 对应的通道有报警
  217. if(pBuf[i] == 1)
  218. {
  219. // 判断该报警在报警列表中是否存在,如果存在则说明报警已经上报,就不需要再次上报,flase表示不需要删除该报警信息
  220. bool bExit = FindAlarmInList(nType, i, false);
  221. if(!bExit)
  222. {
  223. // 如果报警列表中不存在,则将该事件上报界面显示(报警开始),并存储于列表中
  224. AlarmInfo stAlarmInfo;
  225. memset(&stAlarmInfo, 0, sizeof(AlarmInfo));
  226. stAlarmInfo.nType = nType;
  227. stAlarmInfo.nChannel = i;
  228. m_listAlarmInfo.push_back(stAlarmInfo);
  229. // 将信息显示起来
  230. ShowAlarmInfoInTableView(stAlarmInfo, true);
  231. }
  232. else
  233. {
  234. // 如果存在则丢弃该上报事件
  235. }
  236. }
  237. // 对应通道报警结束
  238. else
  239. {
  240. // 在链表查询是否存在报警信息,如果存在就说明是报警结束需要上报显示,且在链表中删除这条报警信息
  241. bool bExit = FindAlarmInList(nType, i, true);
  242. if(bExit)
  243. {
  244. // 如果在报警列表中搜索到,则将该事件上报显示(报警结束),并列表中的存储事件找到该事件并阐述
  245. AlarmInfo stAlarmInfo;
  246. memset(&stAlarmInfo, 0, sizeof(AlarmInfo));
  247. stAlarmInfo.nType = nType;
  248. stAlarmInfo.nChannel = i;
  249. // 将信息显示到界面
  250. ShowAlarmInfoInTableView(stAlarmInfo, false);
  251. }
  252. else
  253. {
  254. // 如果没有搜索到,则丢弃该事件。
  255. }
  256. }
  257. }
  258. }
  259. // 将登陆错误码转换为字符串
  260. void Dialog::ConvertLoginError2String(int nErrorCode , QString &strErrorCode)
  261. {
  262. switch(nErrorCode)
  263. {
  264. case 0:
  265. strErrorCode = tr("Login Success");
  266. break;
  267. case 1:
  268. strErrorCode = tr("Account or Password Incorrect");
  269. break;
  270. case 2:
  271. strErrorCode = tr("User Is Not Exist");
  272. break;
  273. case 3:
  274. strErrorCode = tr("Login Timeout");
  275. break;
  276. case 4:
  277. strErrorCode = tr("Repeat Login");
  278. break;
  279. case 5:
  280. strErrorCode = tr("User Account is Locked");
  281. break;
  282. case 6:
  283. strErrorCode = tr("User In Blocklist");
  284. break;
  285. case 7:
  286. strErrorCode = tr("Device Busy");
  287. break;
  288. case 8:
  289. strErrorCode = tr("Sub Connect Failed");
  290. break;
  291. case 9:
  292. strErrorCode = tr("Host Connect Failed");
  293. break;
  294. case 10 :
  295. strErrorCode = tr("Max Connect");
  296. break;
  297. case 11:
  298. strErrorCode = tr("Support Protocol3 Only");
  299. break;
  300. case 12:
  301. strErrorCode = tr("UKey Info Error");
  302. break;
  303. case 13:
  304. strErrorCode = tr("No Authorized");
  305. break;
  306. case 18:
  307. strErrorCode = tr("Device Account isn't Initialized");
  308. break;
  309. default:
  310. strErrorCode = tr("Unknown Error");
  311. break;
  312. }
  313. }
  314. // 设备登陆与登出
  315. void Dialog::on_Login_pushButton_clicked()
  316. {
  317. if (m_lLoginId == 0)
  318. {
  319. // 设备未登陆
  320. QString strIP = "";
  321. QString strName = "";
  322. QString strPwd = "";
  323. QString strPort = "";
  324. strIP = ui->IP_lineEdit->text();
  325. strName = ui->Name_lineEdit->text();
  326. strPwd = ui->Password_lineEdit->text();
  327. strPort = ui->Port_lineEdit->text();
  328. NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;
  329. memset(&stInparam, 0, sizeof(stInparam));
  330. stInparam.dwSize = sizeof(stInparam);
  331. strncpy(stInparam.szIP, strIP.toLatin1().data(), sizeof(stInparam.szIP) - 1);
  332. strncpy(stInparam.szPassword, strPwd.toLatin1().data(), sizeof(stInparam.szPassword) - 1);
  333. strncpy(stInparam.szUserName, strName.toLatin1().data(), sizeof(stInparam.szUserName) - 1);
  334. stInparam.nPort = strPort.toInt();
  335. stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;
  336. NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;
  337. memset(&stOutparam, 0, sizeof(stOutparam));
  338. stOutparam.dwSize = sizeof(stOutparam);
  339. m_lLoginId = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);
  340. if(m_lLoginId == 0)
  341. {
  342. // 登陆失败
  343. QString strError = "";
  344. ConvertLoginError2String(stOutparam.nError, strError);
  345. QMessageBox::about(NULL,tr("Prompt"),strError);
  346. return;
  347. }
  348. else
  349. {
  350. ui->StartListen_pushButton->setEnabled(true);
  351. ui->Login_pushButton->setText(tr("Logout"));
  352. }
  353. }
  354. else
  355. {
  356. // 如果设备已经订阅事件了,那停止订阅事件
  357. if (m_bSubcribe)
  358. {
  359. on_StartListen_pushButton_clicked();
  360. }
  361. CLIENT_Logout(m_lLoginId);
  362. m_lLoginId = 0;
  363. ui->StartListen_pushButton->setEnabled(false);
  364. ui->Login_pushButton->setText(tr("Login"));
  365. this->setWindowTitle("Alarm");
  366. }
  367. }
  368. // 报警订阅与取消订阅
  369. void Dialog::on_StartListen_pushButton_clicked()
  370. {
  371. if (m_bSubcribe)
  372. {
  373. // 取消订阅
  374. CLIENT_StopListen(m_lLoginId);
  375. m_bSubcribe = false;
  376. // 清理资源
  377. m_Model.removeRows(0, m_Model.rowCount());
  378. m_listAlarmInfo.clear();
  379. ui->StartListen_pushButton->setText(tr("Start Listen"));
  380. }
  381. else
  382. {
  383. // 订阅报警事件
  384. bool bSuccess = CLIENT_StartListenEx(m_lLoginId);
  385. if(!bSuccess)
  386. {
  387. QMessageBox::about(NULL,tr("Prompt"), tr("Start listen failed"));
  388. return;
  389. }
  390. m_bSubcribe = true;
  391. g_nInidex = 1;
  392. ui->StartListen_pushButton->setText(tr("Stop Listen"));
  393. }
  394. }