#include "WindowAppBlockPort.h"
#include "WindowAppItemInterface.h"
#include "Pou.h"
#include "DialogPortValue.h"
WindowAppBlockPort::WindowAppBlockPort(TOOL* pNewPort, POU* Pou, bool bShowOnly, QGraphicsObject* parent)
: WindowAppBlockBase(pNewPort, Pou, bShowOnly, parent)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges);
updateRect();
// 初始化菜单
createContextMenu();
}
///
/// 根据用户的输入实时更新矩形区域的尺寸
///
void WindowAppBlockPort::updateRect()
{
// 计算高度
int blockHeight = PBD_BASIC_HEIGHT;
// 计算宽度
int blockWidth = PBD_BASIC_WIDTH;
// 2021-3-28增加,根据工具名字字符的宽度计算实际需要的宽度
QRect textRect = QFontMetrics(FONT_INF).boundingRect(m_strInfTitle);
if (textRect.width() > PBD_BASIC_WIDTH - PBD_TEXT_GAP_WIDTH)
{
blockWidth = textRect.width() + PBD_TEXT_GAP_WIDTH;
}
// 主体矩形区域
blockRect.setRect(
-blockWidth / 2,
-blockHeight,
blockWidth,
blockHeight
);
// 总体矩形边界(未计算Interface的范围)
blockBoundingRect.setRect(
blockRect.left(),
blockRect.top() - TBD_INDEX_HEIGHT / 2,
blockRect.width() + TBD_SHADOW_COUNT * PEN_LINE_WIDTH,
blockRect.height() + TBD_INDEX_HEIGHT / 2 + TBD_SHADOW_COUNT * PEN_LINE_WIDTH
);
}
///
/// 绘制功能块
///
///
///
///
void WindowAppBlockPort::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->setRenderHint(QPainter::Antialiasing, true);
WindowAppBlockBase::paint(painter, option, widget);
// bSel = isSelected();
Q_UNUSED(widget);
painter->save();
//// 每次绘制之前都更新一下矩形区域
//UpdateRect();
// 绘制外框
DrawBlock(painter);
// 绘制阴影
//DrawBlockShadow(painter);
//// 绘制序号
//DrawIndex(painter);
////// 绘制接口
////DrawInterface(painter);
painter->restore();
}
///
/// 绘制功能块
///
///
void WindowAppBlockPort::DrawBlock(QPainter* painter)
{
WindowAppBlockBase::DrawBlock(painter);
if (m_toolInfo->execParams.nRetValue == VPEnum::RETURN_VALUE::Error )
{
painter->setBrush(QColor(255,0,0) );
// 绘制主体
painter->drawRect(blockRect);
}
}
///
/// 添加接口
///
void WindowAppBlockPort::addItemInterfaces()
{
// 为本Block添加新的ItemInterface
//for (TOOL_INTERFACE* pInf : qAsConst(toolInfo->Interfaces))
//{
WindowAppItemInterface* pNewItemInf = new WindowAppItemInterface(
m_toolInfo->Interfaces[0],
m_pPou,
this->m_toolInfo,
m_bShowOnly,
this
);
if (!m_bShowOnly)
{
// Pou中保存此接口信息
m_pPou->registerInterface(pNewItemInf, m_toolInfo->Interfaces[0]);
}
// 保存接口Item信息
m_itemInterfaces.append(pNewItemInf);
// 界面中添加此Interface(设置为从属关系之后,都不需要手工添加此Item了,真是方便啊)
// scene()->addItem(pNewItemInf);
//}
// 更新Interface的位置
WindowAppBlockBase::updateInterfacesPostion();
}
///
/// 初始化功能块的右键菜单
///
void WindowAppBlockPort::createContextMenu()
{
WindowAppBlockBase::createContextMenu();
//connect(executeAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuExecute);
//connect(executeAllAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuExecuteAll);
connect(deleteAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuDelete);
// connect(propertyAction, &QAction::triggered, this, &WindowAppBlockPort::onMenuProperty);
contextMenu = new QMenu();
//contextMenu->addAction(executeAction);
//contextMenu->addAction(executeAllAction);
//contextMenu->addSeparator();
contextMenu->addAction(deleteAction);
// Port功能块暂时不需要属性框
//contextMenu->addSeparator();
//contextMenu->addAction(propertyAction);
}
///
/// 菜单 - Delete
///
void WindowAppBlockPort::onMenuDelete()
{
//// 检查是否可以被删除
//if (!WindowAppBlockBase::couldBeDeleted())
//{
// return;
//}
// 2021-6-6 如果有绑定的接口变量,则接口变量的引用计数要 - 1
if (this->m_toolInfo->isBinded())
{
this->m_toolInfo->bindedInterface()->nRefCount--;
}
// 2022-10-4,调用基类函数进行删除
WindowAppBlockBase::onDeleteItem();
//// 逻辑数据删除
//m_pPou->ToolDelete(this);
//// 从界面中移除此功能块
//scene()->removeItem(this);
}
///
/// 鼠标双击时弹出变量选择对话框
///
///
void WindowAppBlockPort::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
if (event->button() != Qt::LeftButton || m_bShowOnly)
{
return;
}
// 显示变量选择对话框
DialogPortValue dlgPortValue(m_toolInfo, m_pPou);
int res = dlgPortValue.exec();
if (res != QDialog::Accepted)
{
return;
}
// 获取用户选择的接口信息
_INTERFACE* pSelInf = const_cast<_INTERFACE*>(dlgPortValue.GetSelectedInf());
// 绑定此接口
this->bindInterface(pSelInf);
// 重绘本功能块,用于绑定接口文字的及时更新
this->update();
QGraphicsItem::mouseDoubleClickEvent(event);
}
///
/// 绑定一个接口
///
///
void WindowAppBlockPort::bindInterface(_INTERFACE* pNewInf)
{
// 2021-6-6增加,保存Port绑定的源接口指针
this->m_toolInfo->bindPortInterface(pNewInf);
// 将本变量的值和接口信息,保存到Port的工具信息中
// m_strInfTitle = pNewInf->strFullName + PORT_INF_POSTFIX;
m_strInfTitle = genPortInfName(pNewInf);
m_pPou->bindPortAndInterface(this, pNewInf, m_strInfTitle);
// 根据新的名字长度信息更新本矩形框
updateRect();
// 更新接口的位置及尺寸
WindowAppBlockBase::updateInterfacesPostion();
// 2021-6-6 增加,此处还得需要调整一下link连线的位置(如果有的话),因为port的尺寸会有变动
emit blockMoveSignal(this);
}
///
/// 2022-3-22 为Port中显示的接口名称做调整(局部变量不加Pou前缀,全局变量加Pou前缀)
///
///
///
QString WindowAppBlockPort::genPortInfName(const _INTERFACE* pNewInf)
{
QString strPortGroup = this->m_toolInfo->strPouName;
QString strInfGroup = pNewInf->parent()->strPouName;
// 如果和本Port在同一个Pou范围内
if (strPortGroup == strInfGroup)
{
// 如果是局部变量,那么没有实例名
if (pNewInf->parent()->Type == TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE)
{
return (pNewInf->strName + PORT_INF_POSTFIX);
}
// 如果是Tool,则加上实例名
else if(pNewInf->parent()->Type == TOOL_TYPE::TOOL_TYPE_STANDARD)
{
return (pNewInf->parent()->strInstanceName + "." + pNewInf->strName + PORT_INF_POSTFIX);
}
}
// 否则,加上Pou名称返回
return (pNewInf->strFullName + PORT_INF_POSTFIX);
}