DialogPortValue.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #include "DialogPortValue.h"
  2. #include "PouManager.h"
  3. #include "GvlManager.h"
  4. DialogPortValue::DialogPortValue(const TOOL* port, POU* localPou, QWidget *parent)
  5. : QDialog(parent)
  6. , portInfo(port)
  7. , m_pLocalPou(localPou)
  8. {
  9. ui.setupUi(this);
  10. // 对话框风格初始化
  11. initUI();
  12. //// 添加兼容的工具到树形结构中
  13. //AddCompatibleToolsToTree();
  14. //ui.treeTool->installEventFilter(this);
  15. }
  16. DialogPortValue::~DialogPortValue()
  17. {
  18. }
  19. /// <summary>
  20. /// 对话框初始化
  21. /// </summary>
  22. void DialogPortValue::initUI()
  23. {
  24. // 设置对话框标题
  25. this->setWindowTitle(("Port Interface Selection"));
  26. this->setAttribute(Qt::WA_QuitOnClose);
  27. this->setWindowModality(Qt::ApplicationModal);
  28. // ComboBox
  29. // 分别添加当前的Pou和全局变量(每一个全局变量是一个页面,Pou接口和全局变量是一个页面)
  30. // 2022-4-2 修改,默认显示本Port所属Pou的分组
  31. ui.comboValueGroup->addItem(m_pLocalPou->pouName());
  32. // 获取全部的GVL分组,并添加其中的全局变量分组
  33. m_pAllVariables = g_pGvlManager->getAllGvls();
  34. QMapIterator<QString, GVL*> it(*m_pAllVariables);
  35. while (it.hasNext())
  36. {
  37. const GVL* pGvl = it.next().value();
  38. if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
  39. {
  40. ui.comboValueGroup->addItem(it.key());
  41. }
  42. }
  43. // 硬件组态分组
  44. ui.comboValueGroup->addItem(GROUP_NAME_HARDWARE);
  45. ui.comboValueGroup->setCurrentIndex(0);
  46. this->onComboGroupChanged(0);
  47. //ui.comboValueGroup->addItem(("Global Variables"));
  48. //// 初始化为按Pou来选择
  49. //ui.comboValueGroup->setCurrentIndex(COMBO_INDEX_POU);
  50. //// 添加当前Pou兼容的工具到树形结构中
  51. // AddCompatibleToolsToTree();
  52. // m_SelMode = PORT_SEL_MODE::PORT_SEL_POU;
  53. // 添加当前兼容的Gvl变量到树形结构中
  54. // AddCompatibleVariablesToTree();
  55. // ui.comboValueGroup->setCurrentIndex(0);
  56. // m_SelMode = PORT_SEL_MODE::PORT_SEL_GVL;
  57. // Tree
  58. // 1列
  59. ui.treeTool->setColumnCount(1);
  60. // 隐藏表头
  61. ui.treeTool->setHeaderHidden(true);
  62. // 显示虚线
  63. ui.treeTool->setStyle(QStyleFactory::create("windows"));
  64. // 槽函数
  65. connect(ui.selectButton, SIGNAL(clicked()), this, SLOT(onButtonSelectClicked()));
  66. connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
  67. connect(ui.comboValueGroup, SIGNAL(currentIndexChanged(int)),this,SLOT(onComboGroupChanged(int)));
  68. // 设置固定窗体大小
  69. this->setFixedSize(484, 487);
  70. //this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
  71. }
  72. /// <summary>
  73. /// 添加兼容的工具到树形结构中
  74. /// </summary>
  75. void DialogPortValue::AddPouToolsToTree(const POU* pPou)
  76. {
  77. // 添加适配的标准工具
  78. const QVector<TOOL*>& allTools = pPou->GetAllStandardTools();
  79. QVectorIterator<TOOL*> i(allTools);
  80. while (i.hasNext())
  81. {
  82. const TOOL* pTool = i.next();
  83. //// 只添加标准工具(允许绑定goto工具)
  84. //if (!pTool->isStandardTool())
  85. //{
  86. // continue;
  87. //}
  88. // 按照工具名称添加节点
  89. QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
  90. // 继续添加接口
  91. int nInfCount = 0;
  92. for (_INTERFACE* pInf : pTool->Interfaces)
  93. {
  94. // 只添加和Port输入输出类型相同的接口
  95. // 而且隐藏的也不显示
  96. if (pInf->Direction == portInfo->Interfaces[0]->Direction
  97. && pInf->bEnable)
  98. {
  99. // 如果Port已经绑定了变量类型,那么变量类型也需要相同
  100. if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown
  101. && !pInf->isSameTypeTo(portInfo->Interfaces[0]))
  102. {
  103. continue;
  104. }
  105. // 所有条件都符合,才会出现在列表中
  106. AddInterfaceTreeItem(pToolItem, pInf);
  107. nInfCount++;
  108. }
  109. }
  110. // 如果没有有效的接口,则删除掉刚刚添加的Tool节点
  111. if (nInfCount <= 0)
  112. {
  113. ui.treeTool->removeItemWidget(pToolItem, 0);
  114. delete(pToolItem);
  115. }
  116. }
  117. // 将树形结构展开
  118. ui.treeTool->expandAll();
  119. }
  120. /// <summary>
  121. /// 添加兼容的Pou变量到树形结构中(返回是全局变量、局部变量)
  122. /// </summary>
  123. bool DialogPortValue::AddPouVariablesToTree(const QString& strGroup)
  124. {
  125. bool bIsGlobal = false;
  126. // 获取全部的GVL变量
  127. m_pAllVariables = g_pGvlManager->getAllGvls();
  128. // 首先找到用户选择的分组
  129. QMapIterator<QString, GVL*> it(*m_pAllVariables);
  130. while (it.hasNext())
  131. {
  132. if (it.next().key() != strGroup)
  133. {
  134. continue;
  135. }
  136. // 找到当前变量集
  137. const GVL* pGvl = it.value();
  138. // 首先判断是全局变量还是局部变量
  139. if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
  140. {
  141. bIsGlobal = true;
  142. }
  143. else
  144. {
  145. bIsGlobal = false;
  146. }
  147. // 将变量信息添加到树形结构中
  148. QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(pGvl->Type);
  149. const VARIABLES& vars = it.value()->Variables;
  150. // 继续添加变量
  151. for (const VARIABLE* var : vars)
  152. {
  153. // 如果Port已经绑定了变量类型,那么变量类型也需要相同
  154. // 注:全局变量无需考虑方向,所有方向都可以设置
  155. if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown
  156. && var->value.type != portInfo->Interfaces[0]->value.type)
  157. {
  158. continue;
  159. }
  160. // 所有条件都符合,才会出现在列表中
  161. AddVariableTreeItem(pGroupItem, var);
  162. }
  163. // 将树形结构展开
  164. ui.treeTool->expandAll();
  165. break;
  166. }
  167. return bIsGlobal;
  168. //// 获取全部的GVL分组,并添加
  169. //m_pAllVariables = g_pVariablesManager->getAllGlobalVariables();
  170. //QHashIterator<QString, GVL*> it(*m_pAllVariables);
  171. //while (it.hasNext())
  172. //{
  173. // // ui.comboValueGroup->addItem(it.next().key());
  174. // QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(it.next().key());
  175. // const VARIABLES& vars = it.value()->Variables;
  176. // // 继续添加变量
  177. // for (const VARIABLE* var : vars)
  178. // {
  179. // // 如果Port已经绑定了变量类型,那么变量类型也需要相同
  180. // // 注:全局变量无需考虑方向,所有方向都可以设置
  181. // if (portInfo->Interface->value.Type != VALUE_TYPE::Unknown_Type
  182. // && var->value.Type!=portInfo->Interface->value.Type)
  183. // {
  184. // continue;
  185. // }
  186. // // 所有条件都符合,才会出现在列表中
  187. // AddVariableTreeItem(pGroupItem, var);
  188. // }
  189. //}
  190. //// 将树形结构展开
  191. //ui.treeTool->expandAll();
  192. }
  193. /// <summary>
  194. /// 添加兼容的硬件工具
  195. /// </summary>
  196. void DialogPortValue::AddHdwToolsToTree()
  197. {
  198. AddPouToolsToTree(g_pPouManager->getHdwPou());
  199. }
  200. /// <summary>
  201. /// 添加兼容的硬件局部变量
  202. /// </summary>
  203. void DialogPortValue::AddHdwVariablesToTree()
  204. {
  205. // 获取全部的GVL变量
  206. m_pAllVariables = g_pGvlManager->getAllGvls();
  207. // 首先找到用户选择的分组
  208. QMapIterator<QString, GVL*> it(*m_pAllVariables);
  209. while (it.hasNext())
  210. {
  211. if (it.next().key() != GROUP_NAME_HARDWARE)
  212. {
  213. continue;
  214. }
  215. // 找到当前变量集
  216. const GVL* pGvl = it.value();
  217. // 将变量信息添加到树形结构中
  218. QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(pGvl->Type);
  219. const VARIABLES& vars = it.value()->Variables;
  220. // 继续添加变量
  221. for (const VARIABLE* var : vars)
  222. {
  223. // 如果Port已经绑定了变量类型,那么变量类型也需要相同
  224. // 注:全局变量无需考虑方向,所有方向都可以设置
  225. if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown
  226. && var->value.type != portInfo->Interfaces[0]->value.type)
  227. {
  228. continue;
  229. }
  230. // 所有条件都符合,才会出现在列表中
  231. AddVariableTreeItem(pGroupItem, var);
  232. }
  233. // 将树形结构展开
  234. ui.treeTool->expandAll();
  235. break;
  236. }
  237. }
  238. /// <summary>
  239. /// 添加Tool子节点
  240. /// </summary>
  241. /// <param name="toolName"></param>
  242. QTreeWidgetItem* DialogPortValue::AddToolTreeItem(const QString& toolName)
  243. {
  244. QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(toolName));
  245. newItem->setIcon(0, QIcon(":/image/tool_tree_item.png"));
  246. // 使父节点不可选中
  247. newItem->setFlags(Qt::ItemIsEnabled);
  248. ui.treeTool->addTopLevelItem(newItem);
  249. return newItem;
  250. }
  251. /// <summary>
  252. /// 添加接口子节点
  253. /// </summary>
  254. void DialogPortValue::AddInterfaceTreeItem(QTreeWidgetItem* pToolItem, const _INTERFACE* pInf)
  255. {
  256. QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(pInf->strName));
  257. if (pInf->Direction == INF_DIRECTION::INF_DIR_OUT)
  258. {
  259. newItem->setIcon(0, QIcon(":/image/Output.png"));
  260. }
  261. else
  262. {
  263. newItem->setIcon(0, QIcon(":/image/Input.png"));
  264. }
  265. pToolItem->addChild(newItem);
  266. // 将新加入的item和对应的Interface绑定
  267. m_ItemInfs.insert(newItem, pInf);
  268. }
  269. /// <summary>
  270. /// 添加变量分组子节点
  271. /// </summary>
  272. /// <param name="groupName"></param>
  273. /// <returns></returns>
  274. QTreeWidgetItem* DialogPortValue::AddVariableGroupTreeItem(TOOL_TYPE varType)
  275. {
  276. QStringList strTitle;
  277. if (varType == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
  278. {
  279. strTitle.push_back("Global Variables");
  280. }
  281. else
  282. {
  283. strTitle.push_back("Local Variables");
  284. }
  285. QTreeWidgetItem* newItem = new QTreeWidgetItem(strTitle);
  286. newItem->setIcon(0, QIcon(":/image/gvl_group_tree_item.png"));
  287. // 使父节点不可选中
  288. newItem->setFlags(Qt::ItemIsEnabled);
  289. ui.treeTool->addTopLevelItem(newItem);
  290. return newItem;
  291. }
  292. /// <summary>
  293. /// 添加变量子节点
  294. /// </summary>
  295. /// <param name="pToolItem"></param>
  296. /// <param name="pInf"></param>
  297. void DialogPortValue::AddVariableTreeItem(QTreeWidgetItem* pToolItem, const VARIABLE* var)
  298. {
  299. // 添加的节点命名规则为 变量类型:变量名字
  300. QString strNodeName = var->strNameWithType + "[" + Utility::getValueString(var->value.Ptr, var->value.type) + "]";
  301. // strNodeName =
  302. // Utility::getTypeString(var->value.type)
  303. // + ": " + var->strName +
  304. // " [" + Utility::getValueString(var->value.Ptr, var->value.type) + "]";
  305. // 根据名字建立新的节点
  306. QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(strNodeName));
  307. // newItem->setIcon(0, QIcon(":/image/Output.png"));
  308. // 根据当前Port的输入输出选择方向
  309. if (portInfo->Interfaces[0]->Direction == INF_DIRECTION::INF_DIR_OUT)
  310. {
  311. newItem->setIcon(0, QIcon(":/image/Output.png"));
  312. }
  313. else
  314. {
  315. newItem->setIcon(0, QIcon(":/image/Input.png"));
  316. }
  317. pToolItem->addChild(newItem);
  318. // 将新加入的item和对应的Variable绑定
  319. m_ItemInfs.insert(newItem, var);
  320. }
  321. /// <summary>
  322. /// select按钮
  323. /// </summary>
  324. void DialogPortValue::onButtonSelectClicked()
  325. {
  326. // 获取用户选择的节点
  327. QList<QTreeWidgetItem*> selItems = ui.treeTool->selectedItems();
  328. if (selItems.size() <= 0)
  329. {
  330. // 如果选择的节点无效,则不允许关闭
  331. Utility::VPCriticalMessageBox(" The interface selected is invalid!");
  332. selInf = nullptr;
  333. return;
  334. }
  335. // 获取用户选择的接口或变量
  336. selInf = m_ItemInfs[selItems[0]];
  337. this->accept();
  338. }
  339. /// <summary>
  340. /// Combo框选择变更时,需要切换对应的变量列表
  341. /// </summary>
  342. /// <param name="nIndex"></param>
  343. void DialogPortValue::onComboGroupChanged(int nIndex)
  344. {
  345. Q_UNUSED(nIndex);
  346. // 先将当前的树形控件及对应数据结构全部清空
  347. ui.treeTool->clear();
  348. m_ItemInfs.clear();
  349. // 获取当前选中的分组名称
  350. QString strGroup = ui.comboValueGroup->currentText();
  351. // 首先判断是不是硬件组态分组
  352. if (strGroup == GROUP_NAME_HARDWARE)
  353. {
  354. // 添加硬件变量
  355. // AddHdwVariablesToTree();
  356. // 添加硬件工具
  357. AddHdwToolsToTree();
  358. return;
  359. }
  360. // 如果是Pou相关的,则按Pou的逻辑处理
  361. // 根据分组首先添加对应的Pou变量
  362. bool bIsGlobal = AddPouVariablesToTree(strGroup);
  363. // 然后如果选择的是Pou页面,则继续添加Tool的接口变量
  364. if (!bIsGlobal)
  365. {
  366. AddPouToolsToTree(m_pLocalPou);
  367. }
  368. }
  369. ///// <summary>
  370. ///// 事件过滤器,拦截发往treeTool的双击事件
  371. ///// </summary>
  372. ///// <param name="target"></param>
  373. ///// <param name="event"></param>
  374. ///// <returns></returns>
  375. //bool DialogPortValue::eventFilter(QObject* target, QEvent* event)
  376. //{
  377. // if (target == ui.treeTool)
  378. // {
  379. //
  380. // qDebug() << event->type();
  381. //
  382. // if (event->type() == QEvent::MouseButtonPress)
  383. // {
  384. // // 获取用户选择的节点
  385. // QList<QTreeWidgetItem*> selItems = ui.treeTool->selectedItems();
  386. //
  387. // if (selItems.size() <= 0)
  388. // {
  389. // return true;
  390. // }
  391. // else
  392. // {
  393. // QMessageBox::critical(this, "Vision Plus", " The interface selected is invalid!");
  394. // }
  395. //
  396. // this->accept();
  397. // }
  398. // }
  399. //
  400. //
  401. // return QDialog::eventFilter(target, event);
  402. //}
  403. ///// <summary>
  404. ///// 鼠标双击,直接选定接口
  405. ///// </summary>
  406. ///// <param name="event"></param>
  407. //void DialogPortValue::mouseDoubleClickEvent(QMouseEvent* event)
  408. //{
  409. // // 获取用户选择的节点
  410. // QList<QTreeWidgetItem*> selItems = ui.treeTool->selectedItems();
  411. //
  412. // if (selItems.size() <= 0)
  413. // {
  414. // return;
  415. // }
  416. // else
  417. // {
  418. // QMessageBox::critical(this, "Vision Plus", " The interface selected is invalid!");
  419. // }
  420. //
  421. // this->accept();
  422. //}