WindowAppBlockPort.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include "WindowAppBlockPort.h"
  2. #include "WindowAppItemInterface.h"
  3. #include "Pou.h"
  4. #include "DialogPortValue.h"
  5. WindowAppBlockPort::WindowAppBlockPort(TOOL* pNewPort, POU* Pou, bool bShowOnly, QGraphicsObject* parent)
  6. : WindowAppBlockBase(pNewPort, Pou, bShowOnly, parent)
  7. {
  8. setFlag(QGraphicsItem::ItemIsMovable);
  9. setFlag(QGraphicsItem::ItemIsSelectable);
  10. setFlag(QGraphicsItem::ItemSendsGeometryChanges);
  11. updateRect();
  12. // 初始化菜单
  13. createContextMenu();
  14. }
  15. /// <summary>
  16. /// 根据用户的输入实时更新矩形区域的尺寸
  17. /// </summary>
  18. void WindowAppBlockPort::updateRect()
  19. {
  20. // 计算高度
  21. int blockHeight = PBD_BASIC_HEIGHT;
  22. // 计算宽度
  23. int blockWidth = PBD_BASIC_WIDTH;
  24. // 2021-3-28增加,根据工具名字字符的宽度计算实际需要的宽度
  25. QRect textRect = QFontMetrics(FONT_INF).boundingRect(m_strInfTitle);
  26. if (textRect.width() > PBD_BASIC_WIDTH - PBD_TEXT_GAP_WIDTH)
  27. {
  28. blockWidth = textRect.width() + PBD_TEXT_GAP_WIDTH;
  29. }
  30. // 主体矩形区域
  31. blockRect.setRect(
  32. -blockWidth / 2,
  33. -blockHeight,
  34. blockWidth,
  35. blockHeight
  36. );
  37. // 总体矩形边界(未计算Interface的范围)
  38. blockBoundingRect.setRect(
  39. blockRect.left(),
  40. blockRect.top() - TBD_INDEX_HEIGHT / 2,
  41. blockRect.width() + TBD_SHADOW_COUNT * PEN_LINE_WIDTH,
  42. blockRect.height() + TBD_INDEX_HEIGHT / 2 + TBD_SHADOW_COUNT * PEN_LINE_WIDTH
  43. );
  44. }
  45. /// <summary>
  46. /// 绘制功能块
  47. /// </summary>
  48. /// <param name="painter"></param>
  49. /// <param name="option"></param>
  50. /// <param name="widget"></param>
  51. void WindowAppBlockPort::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
  52. {
  53. painter->setRenderHint(QPainter::Antialiasing, true);
  54. WindowAppBlockBase::paint(painter, option, widget);
  55. // bSel = isSelected();
  56. Q_UNUSED(widget);
  57. painter->save();
  58. //// 每次绘制之前都更新一下矩形区域
  59. //UpdateRect();
  60. // 绘制外框
  61. DrawBlock(painter);
  62. // 绘制阴影
  63. //DrawBlockShadow(painter);
  64. //// 绘制序号
  65. //DrawIndex(painter);
  66. ////// 绘制接口
  67. ////DrawInterface(painter);
  68. painter->restore();
  69. }
  70. /// <summary>
  71. /// 绘制功能块
  72. /// </summary>
  73. /// <param name="painter"></param>
  74. void WindowAppBlockPort::DrawBlock(QPainter* painter)
  75. {
  76. WindowAppBlockBase::DrawBlock(painter);
  77. if (m_toolInfo->execParams.nRetValue == VPEnum::RETURN_VALUE::Error )
  78. {
  79. painter->setBrush(QColor(255,0,0) );
  80. // 绘制主体
  81. painter->drawRect(blockRect);
  82. }
  83. }
  84. /// <summary>
  85. /// 添加接口
  86. /// </summary>
  87. void WindowAppBlockPort::addItemInterfaces()
  88. {
  89. // 为本Block添加新的ItemInterface
  90. //for (TOOL_INTERFACE* pInf : qAsConst(toolInfo->Interfaces))
  91. //{
  92. WindowAppItemInterface* pNewItemInf = new WindowAppItemInterface(
  93. m_toolInfo->Interfaces[0],
  94. m_pPou,
  95. this->m_toolInfo,
  96. m_bShowOnly,
  97. this
  98. );
  99. if (!m_bShowOnly)
  100. {
  101. // Pou中保存此接口信息
  102. m_pPou->registerInterface(pNewItemInf, m_toolInfo->Interfaces[0]);
  103. }
  104. // 保存接口Item信息
  105. m_itemInterfaces.append(pNewItemInf);
  106. // 界面中添加此Interface(设置为从属关系之后,都不需要手工添加此Item了,真是方便啊)
  107. // scene()->addItem(pNewItemInf);
  108. //}
  109. // 更新Interface的位置
  110. WindowAppBlockBase::updateInterfacesPostion();
  111. }
  112. /// <summary>
  113. /// 初始化功能块的右键菜单
  114. /// </summary>
  115. void WindowAppBlockPort::createContextMenu()
  116. {
  117. WindowAppBlockBase::createContextMenu();
  118. //connect(executeAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuExecute);
  119. //connect(executeAllAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuExecuteAll);
  120. connect(deleteAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuDelete);
  121. // connect(propertyAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuProperty);
  122. contextMenu = new QMenu();
  123. //contextMenu->addAction(executeAction);
  124. //contextMenu->addAction(executeAllAction);
  125. //contextMenu->addSeparator();
  126. contextMenu->addAction(deleteAction);
  127. // Port功能块暂时不需要属性框
  128. //contextMenu->addSeparator();
  129. //contextMenu->addAction(propertyAction);
  130. }
  131. /// <summary>
  132. /// 菜单 - Delete
  133. /// </summary>
  134. void WindowAppBlockPort::onMenuDelete()
  135. {
  136. //// 检查是否可以被删除
  137. //if (!WindowAppBlockBase::couldBeDeleted())
  138. //{
  139. // return;
  140. //}
  141. // 2021-6-6 如果有绑定的接口变量,则接口变量的引用计数要 - 1
  142. if (this->m_toolInfo->isBinded())
  143. {
  144. this->m_toolInfo->bindedInterface()->nRefCount--;
  145. }
  146. // 2022-10-4,调用基类函数进行删除
  147. WindowAppBlockBase::onDeleteItem();
  148. //// 逻辑数据删除
  149. //m_pPou->ToolDelete(this);
  150. //// 从界面中移除此功能块
  151. //scene()->removeItem(this);
  152. }
  153. /// <summary>
  154. /// 鼠标双击时弹出变量选择对话框
  155. /// </summary>
  156. /// <param name="event"></param>
  157. void WindowAppBlockPort::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
  158. {
  159. if (event->button() != Qt::LeftButton || m_bShowOnly)
  160. {
  161. return;
  162. }
  163. // 显示变量选择对话框
  164. DialogPortValue dlgPortValue(m_toolInfo, m_pPou);
  165. int res = dlgPortValue.exec();
  166. if (res != QDialog::Accepted)
  167. {
  168. return;
  169. }
  170. // 获取用户选择的接口信息
  171. _INTERFACE* pSelInf = const_cast<_INTERFACE*>(dlgPortValue.GetSelectedInf());
  172. // 绑定此接口
  173. this->bindInterface(pSelInf);
  174. // 重绘本功能块,用于绑定接口文字的及时更新
  175. this->update();
  176. QGraphicsItem::mouseDoubleClickEvent(event);
  177. }
  178. /// <summary>
  179. /// 绑定一个接口
  180. /// </summary>
  181. /// <param name="pNewInf"></param>
  182. void WindowAppBlockPort::bindInterface(_INTERFACE* pNewInf)
  183. {
  184. // 2021-6-6增加,保存Port绑定的源接口指针
  185. this->m_toolInfo->bindPortInterface(pNewInf);
  186. // 将本变量的值和接口信息,保存到Port的工具信息中
  187. // m_strInfTitle = pNewInf->strFullName + PORT_INF_POSTFIX;
  188. m_strInfTitle = genPortInfName(pNewInf);
  189. m_pPou->bindPortAndInterface(this, pNewInf, m_strInfTitle);
  190. // 根据新的名字长度信息更新本矩形框
  191. updateRect();
  192. // 更新接口的位置及尺寸
  193. WindowAppBlockBase::updateInterfacesPostion();
  194. // 2021-6-6 增加,此处还得需要调整一下link连线的位置(如果有的话),因为port的尺寸会有变动
  195. emit blockMoveSignal(this);
  196. }
  197. /// <summary>
  198. /// 2022-3-22 为Port中显示的接口名称做调整(局部变量不加Pou前缀,全局变量加Pou前缀)
  199. /// </summary>
  200. /// <param name="pNewInf"></param>
  201. /// <returns></returns>
  202. QString WindowAppBlockPort::genPortInfName(const _INTERFACE* pNewInf)
  203. {
  204. QString strPortGroup = this->m_toolInfo->strPouName;
  205. QString strInfGroup = pNewInf->parent()->strPouName;
  206. // 如果和本Port在同一个Pou范围内
  207. if (strPortGroup == strInfGroup)
  208. {
  209. // 如果是局部变量,那么没有实例名
  210. if (pNewInf->parent()->Type == TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE)
  211. {
  212. return (pNewInf->strName + PORT_INF_POSTFIX);
  213. }
  214. // 如果是Tool,则加上实例名
  215. else if(pNewInf->parent()->Type == TOOL_TYPE::TOOL_TYPE_STANDARD)
  216. {
  217. return (pNewInf->parent()->strInstanceName + "." + pNewInf->strName + PORT_INF_POSTFIX);
  218. }
  219. }
  220. // 否则,加上Pou名称返回
  221. return (pNewInf->strFullName + PORT_INF_POSTFIX);
  222. }