#include "DialogPortValue.h"
#include "PouManager.h"
#include "GvlManager.h"
DialogPortValue::DialogPortValue(const TOOL* port, POU* localPou, QWidget *parent)
: QDialog(parent)
, portInfo(port)
, m_pLocalPou(localPou)
{
ui.setupUi(this);
// 对话框风格初始化
initUI();
//// 添加兼容的工具到树形结构中
//AddCompatibleToolsToTree();
//ui.treeTool->installEventFilter(this);
}
DialogPortValue::~DialogPortValue()
{
}
///
/// 对话框初始化
///
void DialogPortValue::initUI()
{
// 设置对话框标题
this->setWindowTitle(("Port Interface Selection"));
this->setAttribute(Qt::WA_QuitOnClose);
this->setWindowModality(Qt::ApplicationModal);
// ComboBox
// 分别添加当前的Pou和全局变量(每一个全局变量是一个页面,Pou接口和全局变量是一个页面)
// 2022-4-2 修改,默认显示本Port所属Pou的分组
ui.comboValueGroup->addItem(m_pLocalPou->pouName());
// 获取全部的GVL分组,并添加其中的全局变量分组
m_pAllVariables = g_pGvlManager->getAllGvls();
QMapIterator it(*m_pAllVariables);
while (it.hasNext())
{
const GVL* pGvl = it.next().value();
if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
{
ui.comboValueGroup->addItem(it.key());
}
}
// 硬件组态分组
ui.comboValueGroup->addItem(GROUP_NAME_HARDWARE);
ui.comboValueGroup->setCurrentIndex(0);
this->onComboGroupChanged(0);
//ui.comboValueGroup->addItem(("Global Variables"));
//// 初始化为按Pou来选择
//ui.comboValueGroup->setCurrentIndex(COMBO_INDEX_POU);
//// 添加当前Pou兼容的工具到树形结构中
// AddCompatibleToolsToTree();
// m_SelMode = PORT_SEL_MODE::PORT_SEL_POU;
// 添加当前兼容的Gvl变量到树形结构中
// AddCompatibleVariablesToTree();
// ui.comboValueGroup->setCurrentIndex(0);
// m_SelMode = PORT_SEL_MODE::PORT_SEL_GVL;
// Tree
// 1列
ui.treeTool->setColumnCount(1);
// 隐藏表头
ui.treeTool->setHeaderHidden(true);
// 显示虚线
ui.treeTool->setStyle(QStyleFactory::create("windows"));
// 槽函数
connect(ui.selectButton, SIGNAL(clicked()), this, SLOT(onButtonSelectClicked()));
connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
connect(ui.comboValueGroup, SIGNAL(currentIndexChanged(int)),this,SLOT(onComboGroupChanged(int)));
// 设置固定窗体大小
this->setFixedSize(484, 487);
//this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
}
///
/// 添加兼容的工具到树形结构中
///
void DialogPortValue::AddPouToolsToTree(const POU* pPou)
{
// 添加适配的标准工具
const QVector& allTools = pPou->GetAllStandardTools();
QVectorIterator i(allTools);
while (i.hasNext())
{
const TOOL* pTool = i.next();
//// 只添加标准工具(允许绑定goto工具)
//if (!pTool->isStandardTool())
//{
// continue;
//}
// 按照工具名称添加节点
QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
// 继续添加接口
int nInfCount = 0;
for (_INTERFACE* pInf : pTool->Interfaces)
{
// 只添加和Port输入输出类型相同的接口
// 而且隐藏的也不显示
if (pInf->Direction == portInfo->Interfaces[0]->Direction
&& pInf->bEnable)
{
// 如果Port已经绑定了变量类型,那么变量类型也需要相同
if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown
&& !pInf->isSameTypeTo(portInfo->Interfaces[0]))
{
continue;
}
// 所有条件都符合,才会出现在列表中
AddInterfaceTreeItem(pToolItem, pInf);
nInfCount++;
}
}
// 如果没有有效的接口,则删除掉刚刚添加的Tool节点
if (nInfCount <= 0)
{
ui.treeTool->removeItemWidget(pToolItem, 0);
delete(pToolItem);
}
}
// 将树形结构展开
ui.treeTool->expandAll();
}
///
/// 添加兼容的Pou变量到树形结构中(返回是全局变量、局部变量)
///
bool DialogPortValue::AddPouVariablesToTree(const QString& strGroup)
{
bool bIsGlobal = false;
// 获取全部的GVL变量
m_pAllVariables = g_pGvlManager->getAllGvls();
// 首先找到用户选择的分组
QMapIterator it(*m_pAllVariables);
while (it.hasNext())
{
if (it.next().key() != strGroup)
{
continue;
}
// 找到当前变量集
const GVL* pGvl = it.value();
// 首先判断是全局变量还是局部变量
if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
{
bIsGlobal = true;
}
else
{
bIsGlobal = false;
}
// 将变量信息添加到树形结构中
QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(pGvl->Type);
const VARIABLES& vars = it.value()->Variables;
// 继续添加变量
for (const VARIABLE* var : vars)
{
// 如果Port已经绑定了变量类型,那么变量类型也需要相同
// 注:全局变量无需考虑方向,所有方向都可以设置
if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown
&& var->value.type != portInfo->Interfaces[0]->value.type)
{
continue;
}
// 所有条件都符合,才会出现在列表中
AddVariableTreeItem(pGroupItem, var);
}
// 将树形结构展开
ui.treeTool->expandAll();
break;
}
return bIsGlobal;
//// 获取全部的GVL分组,并添加
//m_pAllVariables = g_pVariablesManager->getAllGlobalVariables();
//QHashIterator it(*m_pAllVariables);
//while (it.hasNext())
//{
// // ui.comboValueGroup->addItem(it.next().key());
// QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(it.next().key());
// const VARIABLES& vars = it.value()->Variables;
// // 继续添加变量
// for (const VARIABLE* var : vars)
// {
// // 如果Port已经绑定了变量类型,那么变量类型也需要相同
// // 注:全局变量无需考虑方向,所有方向都可以设置
// if (portInfo->Interface->value.Type != VALUE_TYPE::Unknown_Type
// && var->value.Type!=portInfo->Interface->value.Type)
// {
// continue;
// }
// // 所有条件都符合,才会出现在列表中
// AddVariableTreeItem(pGroupItem, var);
// }
//}
//// 将树形结构展开
//ui.treeTool->expandAll();
}
///
/// 添加兼容的硬件工具
///
void DialogPortValue::AddHdwToolsToTree()
{
AddPouToolsToTree(g_pPouManager->getHdwPou());
}
///
/// 添加兼容的硬件局部变量
///
void DialogPortValue::AddHdwVariablesToTree()
{
// 获取全部的GVL变量
m_pAllVariables = g_pGvlManager->getAllGvls();
// 首先找到用户选择的分组
QMapIterator it(*m_pAllVariables);
while (it.hasNext())
{
if (it.next().key() != GROUP_NAME_HARDWARE)
{
continue;
}
// 找到当前变量集
const GVL* pGvl = it.value();
// 将变量信息添加到树形结构中
QTreeWidgetItem* pGroupItem = AddVariableGroupTreeItem(pGvl->Type);
const VARIABLES& vars = it.value()->Variables;
// 继续添加变量
for (const VARIABLE* var : vars)
{
// 如果Port已经绑定了变量类型,那么变量类型也需要相同
// 注:全局变量无需考虑方向,所有方向都可以设置
if (portInfo->Interfaces[0]->value.type != VALUE_TYPE::Type_Unknown
&& var->value.type != portInfo->Interfaces[0]->value.type)
{
continue;
}
// 所有条件都符合,才会出现在列表中
AddVariableTreeItem(pGroupItem, var);
}
// 将树形结构展开
ui.treeTool->expandAll();
break;
}
}
///
/// 添加Tool子节点
///
///
QTreeWidgetItem* DialogPortValue::AddToolTreeItem(const QString& toolName)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(toolName));
newItem->setIcon(0, QIcon(":/image/tool_tree_item.png"));
// 使父节点不可选中
newItem->setFlags(Qt::ItemIsEnabled);
ui.treeTool->addTopLevelItem(newItem);
return newItem;
}
///
/// 添加接口子节点
///
void DialogPortValue::AddInterfaceTreeItem(QTreeWidgetItem* pToolItem, const _INTERFACE* pInf)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(pInf->strName));
if (pInf->Direction == INF_DIRECTION::INF_DIR_OUT)
{
newItem->setIcon(0, QIcon(":/image/Output.png"));
}
else
{
newItem->setIcon(0, QIcon(":/image/Input.png"));
}
pToolItem->addChild(newItem);
// 将新加入的item和对应的Interface绑定
m_ItemInfs.insert(newItem, pInf);
}
///
/// 添加变量分组子节点
///
///
///
QTreeWidgetItem* DialogPortValue::AddVariableGroupTreeItem(TOOL_TYPE varType)
{
QStringList strTitle;
if (varType == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
{
strTitle.push_back("Global Variables");
}
else
{
strTitle.push_back("Local Variables");
}
QTreeWidgetItem* newItem = new QTreeWidgetItem(strTitle);
newItem->setIcon(0, QIcon(":/image/gvl_group_tree_item.png"));
// 使父节点不可选中
newItem->setFlags(Qt::ItemIsEnabled);
ui.treeTool->addTopLevelItem(newItem);
return newItem;
}
///
/// 添加变量子节点
///
///
///
void DialogPortValue::AddVariableTreeItem(QTreeWidgetItem* pToolItem, const VARIABLE* var)
{
// 添加的节点命名规则为 变量类型:变量名字
QString strNodeName = var->strNameWithType + "[" + Utility::getValueString(var->value.Ptr, var->value.type) + "]";
// strNodeName =
// Utility::getTypeString(var->value.type)
// + ": " + var->strName +
// " [" + Utility::getValueString(var->value.Ptr, var->value.type) + "]";
// 根据名字建立新的节点
QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(strNodeName));
// newItem->setIcon(0, QIcon(":/image/Output.png"));
// 根据当前Port的输入输出选择方向
if (portInfo->Interfaces[0]->Direction == INF_DIRECTION::INF_DIR_OUT)
{
newItem->setIcon(0, QIcon(":/image/Output.png"));
}
else
{
newItem->setIcon(0, QIcon(":/image/Input.png"));
}
pToolItem->addChild(newItem);
// 将新加入的item和对应的Variable绑定
m_ItemInfs.insert(newItem, var);
}
///
/// select按钮
///
void DialogPortValue::onButtonSelectClicked()
{
// 获取用户选择的节点
QList selItems = ui.treeTool->selectedItems();
if (selItems.size() <= 0)
{
// 如果选择的节点无效,则不允许关闭
Utility::VPCriticalMessageBox(" The interface selected is invalid!");
selInf = nullptr;
return;
}
// 获取用户选择的接口或变量
selInf = m_ItemInfs[selItems[0]];
this->accept();
}
///
/// Combo框选择变更时,需要切换对应的变量列表
///
///
void DialogPortValue::onComboGroupChanged(int nIndex)
{
Q_UNUSED(nIndex);
// 先将当前的树形控件及对应数据结构全部清空
ui.treeTool->clear();
m_ItemInfs.clear();
// 获取当前选中的分组名称
QString strGroup = ui.comboValueGroup->currentText();
// 首先判断是不是硬件组态分组
if (strGroup == GROUP_NAME_HARDWARE)
{
// 添加硬件变量
// AddHdwVariablesToTree();
// 添加硬件工具
AddHdwToolsToTree();
return;
}
// 如果是Pou相关的,则按Pou的逻辑处理
// 根据分组首先添加对应的Pou变量
bool bIsGlobal = AddPouVariablesToTree(strGroup);
// 然后如果选择的是Pou页面,则继续添加Tool的接口变量
if (!bIsGlobal)
{
AddPouToolsToTree(m_pLocalPou);
}
}
/////
///// 事件过滤器,拦截发往treeTool的双击事件
/////
/////
/////
/////
//bool DialogPortValue::eventFilter(QObject* target, QEvent* event)
//{
// if (target == ui.treeTool)
// {
//
// qDebug() << event->type();
//
// if (event->type() == QEvent::MouseButtonPress)
// {
// // 获取用户选择的节点
// QList selItems = ui.treeTool->selectedItems();
//
// if (selItems.size() <= 0)
// {
// return true;
// }
// else
// {
// QMessageBox::critical(this, "Vision Plus", " The interface selected is invalid!");
// }
//
// this->accept();
// }
// }
//
//
// return QDialog::eventFilter(target, event);
//}
/////
///// 鼠标双击,直接选定接口
/////
/////
//void DialogPortValue::mouseDoubleClickEvent(QMouseEvent* event)
//{
// // 获取用户选择的节点
// QList selItems = ui.treeTool->selectedItems();
//
// if (selItems.size() <= 0)
// {
// return;
// }
// else
// {
// QMessageBox::critical(this, "Vision Plus", " The interface selected is invalid!");
// }
//
// this->accept();
//}